luna_
luna_

Reputation: 312

Executing code after all requests have finished (Facebook SDK)

Is it possible to return from an async completion block some way besides delegation? Is it best to pass the value by calling a block?

- (NSMutableArray *)facebookGalleryImages
{
    // Create array which will hold dicts for each image containing both thumbnail and original image URLs
    NSMutableArray *allFBImages = [[NSMutableArray alloc] init];
    // Begin Facebook API Calls
    [FBRequestConnection startWithGraphPath:@"me/albums" completionHandler:^(FBRequestConnection* connection, id result, NSError* error) {
        if (!error) {
            // Get data of all albums
            NSArray *feed =[result objectForKey:@"data"];
            for (NSDictionary *dict in feed) {
                // Get album ID of each album
                NSString *albumID = [dict objectForKey:@"id"];
                // New API call to get the image data for a specific album ID
                [FBRequestConnection startWithGraphPath:[NSString stringWithFormat:@"%@/photos", albumID] completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
                    if (!error){
                        // Get data of all images in album
                        NSArray *imageFeed = [result objectForKey:@"data"];
                        // For each image data object, extract source image URL and thumbnail URL, then add these to a dictionary
                        for (NSDictionary *dict in imageFeed){
                            NSString *sourceURL = [dict objectForKey:@"source"];
                            NSString *thumbnailURL = [dict objectForKey:@"picture"];
                            NSDictionary *imageDict = @{ @"source" : sourceURL, @"thumbnail" : thumbnailURL};
                            //Add the dictionary holding an images URLs to an array which will be passed to our gallery
                            [allFBImages addObject:imageDict];
                        }
                    }
                }];
            }
        }
    }];
}

Upvotes: 1

Views: 208

Answers (1)

kabarga
kabarga

Reputation: 803

Your return code doesnt work because the methods are async. The best you can do is to extend your method to return on completion, so your method will look like:

- (void) facebookGalleryImages:(void (^)(NSMutableArray *imagesArray, NSError *error))completion
{
     NSMutableArray *allFBImages = [[NSMutableArray alloc] init];
     // Begin Facebook API Calls
    [FBRequestConnection startWithGraphPath:@"me/albums" completionHandler:^(FBRequestConnection* connection, id result, NSError* error) {
         if (!error) {
            // Get data of all albums
            NSArray *feed =[result objectForKey:@"data"];
            for (NSDictionary *dict in feed) {
                // Get album ID of each album
                NSString *albumID = [dict objectForKey:@"id"];
                // New API call to get the image data for a specific album ID
                [FBRequestConnection startWithGraphPath:[NSString stringWithFormat:@"%@/photos", albumID] completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
                    if (!error){
                        // Get data of all images in album
                        NSArray *imageFeed = [result objectForKey:@"data"];
                        // For each image data object, extract source image URL and thumbnail URL, then add these to a dictionary
                        for (NSDictionary *dict in imageFeed){
                            NSString *sourceURL = [dict objectForKey:@"source"];
                            NSString *thumbnailURL = [dict objectForKey:@"picture"];
                            NSDictionary *imageDict = @{ @"source" : sourceURL, @"thumbnail" : thumbnailURL};
                            //Add the dictionary holding an images URLs to an array which will be passed to our gallery
                            [allFBImages addObject:imageDict];
                        }
                    }
                }];
            }
            completion(allFBImages, nil);
        }else {
           completion(nil, error);
        }
    }];
}

Finally, you will use your method like:

[self facebookGalleryImages:^(NSMutableArray *imagesArray, NSError *error) {
     if ([imagesArray count] > 0 ){
         // do something with the array
     }else {
         // do something with error
     }     
};

Upvotes: 1

Related Questions