Batch Loader

Oftentimes you will need to multiple types of data for a single view within your project, and while you can perform multiple requests using multiple object loaders, it is often more efficient to do one single request. You can combine multiple object loaders into a single request by using a batch object loader. The batch object loader, AWFBatchLoader, provides an easy-to-use interface to the API’s batch endpoint by combining multiple object loaders and their various options into a single HTTP request.

To use the batch loader, you first need to create the instances of the individual object loaders you wish to request data for:

AWFPlace *place = [AWFPlace placeWithCity:@"seattle" state:@"wa" country:@"us"];

AWFObservationsLoader *obsLoader = [[AWFObservationsLoader alloc] init]; = place;

AWFForecastLoader *forecastLoader = [[AWFForecastsLoader alloc] init]; = place;
forecastLoader.options.limit = 7;
forecastLoader.options.filter = @"day";

AWFAdvisoriesLoader *advisoriesLoader = [[AWFAdvisoriesLoader alloc] init]; = place;
let place = AWFPlace(city: "seattle", state: "wa", country: "us")

let obsLoader = AWFObservationsLoader() = place

let forecastLoader = AWFForecastsLoader() = place
forecastLoader.options.limit = 7
forecastLoader.options.filterString = "day"

let advisoriesLoader = AWFAdvisoriesLoader() = place

Then create an instance of AWFBatchLoader:

AWFBatchLoader *loader = [[AWFBatchLoader alloc] initWithLoaders:@[obsLoader, forecastLoader]];
let loader = AWFBatchLoader(loaders: [obsLoader, forecastLoader])!

You can also add and remove object loaders to the batch after it’s been created:

[loader addLoader:advisoriesLoader];

If you need to add an object loader for a specific API action, such as within or search, you can associate an action with an individual object loader when adding it:

[loader addLoader:advisoryLoader action:AerisAPIActionSearch];
loader.addLoader(advisoriesLoader, action: AerisAPIActionSearch)

Alternatively, you can add individual object loaders to a batch loader by associating them with a unique key. This method allows you to easily reference that specific object loader directly when handling the response from batch request:

[loader addLoader:advisoryLoader forKey:@"advisories"];
loader.addLoader(advisoriesLoader, forKey: "advisories")

The same keyed object loader method can also be used for specific actions:

[loader addLoader:advisoryLoader action:AerisAPIActionSearch forKey:@"advisory"];
loader.addLoader(advisoriesLoader, action: AerisAPIActionSearch, forKey: "advisories")

When adding object loaders to a batch request using a key, you can always return that object loader instance from the batch loader later if needed:

AWFObjectLoader *advisoryLoader = [loader objectLoaderForKey:@"advisory"];
let advisoryLoader = loader.objectLoader(forKey: "advisories")

Once your batch loader is setup with the necessary object loaders and options, then perform the request in a single call:

[loader getWithCompletionBlock:^(AWFBatchLoader *loader, NSError *error) {
    // do something
loader.getWithCompletionBlock({ (loader, error) in
	// do something

Removing Object Loaders

Similar to adding object loaders to a batch loader instance, you can also remove object loaders from the request:

[loader removeLoader:advisoryLoader];

You can also remove an object loader associated with a specific key when it was added:

[loader removeLoaderForKey:@"advisory"];
loader.remove(forKey: "advisories")

If you want to remove all object loaders associated with a batch request, you can use a single method:

[loader removeAllLoaders];

Handling a Batch Loader Response

Instead of returning an array of model objects to your completion block like standard object loaders, a batch loader just returns itself and an error, if any. In order to get the objects that were loader for a specific object loader in the batch, you use the objectsForLoader: method on the batch loader, passing in the original loader instance that was added to the batch loader:

[loader getWithCompletionBlock:^(AWFBatchLoader *loader, NSError *error) {
    if (error) {

	// return objects for a specific object loader instance
	NSArray *advisories = [loader objectsForLoader:advisoriesLoader];
	// or, return objects for an object loader associated with a specific key
	NSArray *advisories = [loader objectsForLoaderWithKey:@"advisory"];
	if ([advisories count] > 0) {
		// do something
loader.getWithCompletionBlock({ (loader, error) in
	if error != nil { return }
	// return objects for a specific object loader instance
	let advisories: [AWFAdvisory]? = loader?.objects(for: advisoriesLoader)
	// or, return objects for an object loader associated with a specific key
	let advisories: [AWFAdvisory]? = loader?.objectsForLoader(withKey: "advisory")
	if let advisories = advisories, advisories.count > 0 {
		// do something

This method will always return an array, or nil if there are no object (no data) for the specific object loader. As with the standard set of object loaders, ensure you are checking that this array is not empty or nil before trying to access objects within it.

Updating the Batch Loader Location

If you are performing a request for multiple types of data for a single location, you may find that you need to change the location being used for each individual object loader in the batch request. Instead of iterating through the array of object loaders, you can update the place on each with a single method:

[loader setPlaceForAllLoaders:[AWFPlace placeWithCity:@"seattle" state:@"wa" country:@"us"]];

This method will update the `place` value on each of the batch request’s object loaders.

Batch Request Limits

The AerisWeather API batch endpoint currently limits the number of endpoint requests in a single batch query to ten (10). Therefore, the batch loader also enforces this limit.

Last modified: July 30, 2020