简体   繁体   中英

How do you know which FBRequest initiated the request didLoad: method?

From the facebook iOS API documentation, I've create two methods that request either the friends list from the graph, or details about the currently logged in user.

- (IBAction)showMyFriends:(id)sender {
    AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    [[delegate facebook] requestWithGraphPath:@"me/friends" andDelegate:self];
    NSLog(@"Getting friends list");
}
- (IBAction)showMyDetails:(id)sender {
    AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    [[delegate facebook] requestWithGraphPath:@"me" andDelegate:self];
    NSLog(@"Getting my info");
}

Sounds reasonable so far. The delegate method that responds from these calls is :

- (void)request:(FBRequest *)request didLoad:(id)result
{
    NSLog(@"Got a request");

// Print out friends
//    NSArray * items = [NSArray alloc];
//    items = [(NSDictionary *)result objectForKey:@"data"];
//    for (int i=0; i<[items count]; i++) {
//        NSDictionary *friend = [items objectAtIndex:i];
//        long long fbid = [[friend objectForKey:@"id"]longLongValue];
//        NSString *name = [friend objectForKey:@"name"];
//        NSLog(@"id: %lld - Name: %@", fbid, name);
//    }


// Print out self username
    NSString *username = [result objectForKey:@"name"];
    NSLog(@"Username is %@", username);
    helloGreeting.text = [NSString stringWithFormat:@"Hello %@", username];

}

Question : In the didLoad , how can you check which graph request the current invocation relates to? For example, in the above code I would either want to print out the friends list, or print out the username, so I would image I need to wrap the code in some case/switch statement dependant on the request type.

I couldn't find anything obvious on the API, what is the best approach for ensuring only relevant response code is executed?

As noted above, you can inspect the request object to check which request generated the response. You can use the url property of the request object to more conveniently check which request was used.

Eg for the request to get a friends list

[facebook requestWithGraphPath:@"me/friends" andDelegate:self];

You can check for the url of the request object being:

https://graph.facebook.com/me/friends

The following implementation of request didLoad will detect a friends list request and iterate over each friend.

- (void)request:(FBRequest *)request didLoad:(id)result {

    // Friends request
    if([request.url rangeOfString:@"me/friends"].location != NSNotFound) {

        NSArray *friends = [result objectForKey:@"data"];
        for (int i=0;i<friends.count;i++) {

            NSDictionary *friend = [friends objectAtIndex:i];
            //NSLog([friend objectForKey:@"name"]);

        }  
    }
}

That is why you get the FBRequest variable back in "didLoad". You can use that to inspect the original request. It's kind of a crap solution, but at least you can inspect what it was.

Actually looks like Hackbook is doing a switch based on an int called "currentAPICall", setting an int for each request, then checking on that in the return. So it's all done in the main thread, I'm guessing.

I also have different result objects, of different types. I end up looking at the result and determining if it's from the /me request or from the /home. I have various "ifs" looking at the returning object. Not ideal by any means. Ie

if([result objectForKey:@"first_name"]){
    // back from getMe()
}

if ([result objectForKey:@"data"]) {
    // more checking here- I have two calls that return a data object
}

Update: this doesn't work for asynchronous requests, and most of these are, so I used the method above, checking request.url, instead, and that works like a charm.

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