0

I've been looking around, saw similar posts, but nothing like this that could give me answers. This is my setup and flow of the app:

  1. User has to login via Facebook, using Facebook Graph. LoginView is presented modally, non animated
  2. When user logins I can retrieve FBID and I use this fbid to send it to my web service (REST)
  3. Web service gets the FBID from the NSURL and matches it with database to retrieve other user info
  4. Using JSONserialization i parse the JSON received from web service and display it in the view

PROBLEM: Everything returns NULL except FBID that I get from Facebook. BUT, if I logout from Facebook and then login, that's when it works.

Here is my code:

viewDidAppear method:

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:NO];
    if (FBSession.activeSession.isOpen) {
        [self populateUserDetails];
    }

    //Connect to WebService
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://atnightcorp.com/api/member/id/%@/format/json", fbid]];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [NSURLConnection connectionWithRequest:request delegate:self];
    NSArray *pics = [member valueForKeyPath:@"photos"];
    NSString *picCount = [NSString stringWithFormat:@"%d", [pics count]];
    [photosCount setTitle:picCount forState:UIControlStateNormal];

    NSLog(@"PHOTO: %@", picCount);
    NSLog(@"FB: %@", fbid);

}

I tried putting NSURL request and connection code in viewDidLoad, but then I don't get anything back.

My NSURLConnection methods:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    data = [[NSMutableData alloc]init];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
    [data appendData:theData];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

    member = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];

}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    UIAlertView *errorView = [[UIAlertView alloc]initWithTitle:@"Error" message:@"The download could not complete. Please make sure you are connected to internet" delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
    [errorView show];
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

The populateUserDetails method that you have seen above:

- (void)populateUserDetails
{
    if (FBSession.activeSession.isOpen) {
        [[FBRequest requestForMe] startWithCompletionHandler:
         ^(FBRequestConnection *connection,
           NSDictionary<FBGraphUser> *user,
           NSError *error) {
             if (!error) {
                 self.userProfileImage.profileID = user.id;
                 self.navigationItem.title = user.name;
                 self.fbid = user.id;
             }
         }];
    }
}

This method basically sets the FBID once user is logged in. Other important things you should know that could help you understand my project:

  • FBID is set as NSString property in my .H file
  • All facebook connect thing goes on in AppDelegate
  • I need to dynamically set the NSURL after I find out who the user is.
  • if I manually input FBID in NSURL, then it works.
  • everything should be executed when user logins, I think that the timing of retrieving fbid and receiving data from web service is wrong but I can't get to fix it.
  • IF you need anything else, I will elaborate more and post more code if needed. -

PLEASE HELP as I've been looking for answers for last 3 days.

SasaT
  • 731
  • 6
  • 19

1 Answers1

0

Your problem is that the populateUserDetails is called and it returns without waiting the code to be executed (because it's an async task with a completition handler, and when you call the NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://atnightcorp.com/api/member/id/%@/format/json", fbid]]; for the first time, the fbid is nuil or not set properly (also you should use self.fbid not fbid since fbid is a property).

So you should try to move the whole code that is handling the request from viewDidAppear into a separate method and you should call that method from startWithCompletionHandler after you set the line with self.fbid = user.id

Also call [super viewDidAppear:animated]; not with NO param (this won't solve your problem but this is the right way to do it)

danypata
  • 9,895
  • 1
  • 31
  • 44
  • Thanks bud. It makes a lot of sense what you are saying. I will try to implement it when I get back to office and will let you know. – SasaT May 22 '13 at 18:21
  • Thanks danypata. You woke me up from my nightmare. After I implemented your approach, all I had to do is move the parsing code to -connectionDidFinishLoading method and everything worked like a charm. – SasaT May 23 '13 at 04:44