简体   繁体   中英

getting Facebook profile pictures for a set of friends in background

I am looking for a clear and complete explanation of the best way to get profile pictures for a set of Facebook friends (whose Facebook IDs are stored in an array). Elsewhere in my app, I use the following code to get the current user's image:

...
...
    // Create request for user's Facebook data
    FBRequest *request = [FBRequest requestForMe];

    // Send request to Facebook
    [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
        if (!error) {
            NSLog(@"no fb error");
            // result is a dictionary with the user's Facebook data
            NSDictionary *userData = (NSDictionary *)result;

            // Download the user's facebook profile picture
            self.imageData = [[NSMutableData alloc] init]; // the data will be loaded in here

            // URL should point to https://graph.facebook.com/{facebookId}/picture?type=large&return_ssl_resources=1
            NSURL *pictureURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=square&return_ssl_resources=1", userData[@"id"]]];

            NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:pictureURL
                                                                      cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                                  timeoutInterval:2.0f];
            // Run network request asynchronously
            NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
            if (!urlConnection) {
                NSLog(@"Failed to download picture");
            }
        } 
    }];         
}

// Called every time a chunk of the data is received
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.imageData appendData:data]; // Build the image
}

// Called when the entire image is finished downloading
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {  
    [[PFUser currentUser] setObject:self.imageData forKey:@"image"];
    [[PFUser currentUser] saveInBackground];
}

This approach seems to have the advantage of downloading the data in the background, but it seems like it could be tricky to implement it as part of a for loop in which I cycle through a set of the user's Facebook friends to get their profile pictures, since it calls multiple delegate methods and I would then have to keep track of which friend's image data was being received in the delegate methods.

Would it would even be possible to keep track of which friend's image data was being received in the delegate methods, given that the for loop iterating through those friends would execute on the main thread and complete before the data collection completes for prior iterations (I believe)?

I guess one way to solve this problem would be to execute the entire for loop in a background thread where I don't iterate to the next friend until the current one collects all its data. And then I wouldn't need to use the NSURLConnection asynchronous call. And this would probably simplify the code quite a bit. Would that be a good solution, and if so, how would I set up such a background process?

Or what other solution would you recommend?

use NSURLConns method: + (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler like this:

// Create request for user's Facebook data
FBRequest *request = [FBRequest requestForMe];

// Send request to Facebook
[request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
    if (!error) {
        NSLog(@"no fb error");
        // result is a dictionary with the user's Facebook data
        NSDictionary *userData = (NSDictionary *)result;

        // Download the user's facebook profile picture
        self.imageData = [[NSMutableData alloc] init]; // the data will be loaded in here

        // URL should point to https://graph.facebook.com/{facebookId}/picture?type=large&return_ssl_resources=1
        NSURL *pictureURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=square&return_ssl_resources=1", userData[@"id"]]];

        NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:pictureURL
                                                                  cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                              timeoutInterval:2.0f];
        // Run network request asynchronously
       [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *resp, NSData *data, NSError *error) {
           [[PFUser currentUser] setObject:data forKey:@"image"];
            [[PFUser currentUser] saveInBackground];
       }];
    } 
}];         

}

I'm not really sure how to do it, but I'm 95% that it is achievable by an FQL query. Check Facebook's documentation of FQL here . The loop really isn't a great idea, although there is a way where you can combine multiple FBRequests into one big FBRequestConnection and launch all at once - however I'd advise against it.

In one of my apps I check for the users friends checked-in at a Facebook event (cross-referencing user friends agains a list of all attendees) - I do it with FQL query. I understand that this is not what you want, however it might help you understanding the approach. Check the answer to my own question here .

Hope this helps...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM