0

In my view controller, I've got data inside of self.acceptedFriends. In my first if statement, the mutable array populates perfectly and data is present. However, in my last portion of the statement ( else if ([neighbourDetail count] > 0) ), self.acceptedFriends is empty for some reason? Any idea why this might be?

Note: This question is different than the linked examples, as the data IS working outside of the AFNetworking block - it's populated inside the first if statement, just not the last.

ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UIAlertViewDelegate>

@property (nonatomic, strong) NSMutableArray *acceptedFriends;

@end

ViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];

    NSMutableDictionary *viewParams3 = [NSMutableDictionary new];
    [viewParams3 setValue:@"accepted_friends" forKey:@"view_name"];
    [DIOSView viewGet:viewParams3 success:^(AFHTTPRequestOperation *operation, id responseObject) {
        self.acceptedFriends = (NSMutableArray *)responseObject;

        [operation responseString];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"Failure: %@", [error localizedDescription]);
    }];

    if ([self.mapuserData count] > 0 ) {
        NSLog(@"This is map user data %@", self.mapuserData);

        NSString *thisUserId = [self.mapuserData objectForKey:@"users_name"];

        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"node_title CONTAINS[cd] %@",
                                      thisUserId];

        NSArray *resultArray = [self.acceptedFriends filteredArrayUsingPredicate:predicate];

        if (!resultArray) {
            NSLog(@"Executed!");
            self.addFriend.hidden = YES;
            self.orangeFriendCircle.hidden = YES;
        }
    } else if ([self.frienduserData count] > 0) {
        self.addFriend.hidden = YES;
        self.orangeFriendCircle.hidden = YES;    

        self.username.text = self.frienduserData[@"node_title"];

        self.userBio.text = self.frienduserData[@"body"];

        NSString *thirdLink = self.frienduserData[@"friendphoto"];

        NSString *ImageURLTwo = thirdLink;
        NSData *imageDataTwo = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURLTwo]];

        self.userPhoto.image = [[UIImage alloc] initWithData:imageDataTwo];
    }  else if ([neighbourDetail count] > 0) { 
        NSString *thisUserId = [self.neighbourDetail objectForKey:@"users_name"];

        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"node_title CONTAINS[cd] %@",
                                    thisUserId];

        NSArray *resultArray = [self.acceptedFriends filteredArrayUsingPredicate:predicate];

        if ([resultArray count] > 0) {
            NSLog(@"Executed!");
            self.addFriend.hidden = YES;
            self.orangeFriendCircle.hidden = YES;
        }
    }
}
jscs
  • 63,694
  • 13
  • 151
  • 195
Brittany
  • 1,359
  • 4
  • 24
  • 63
  • 2
    Your block [DIOSView viewGet is asynchronous, you should do your if else statements inside the block completion. –  Sep 03 '17 at 18:50
  • @Sneak Tried it - If I do my if statement inside the block, for some reason, it takes an additional 2-3 seconds to trigger self.addFriend.hidden etc. :/ – Brittany Sep 03 '17 at 18:51
  • 1
    That is because it probably takes 2-3 seconds for your request/block to finish. You are manipulating the data inside the block and you are doing if-else statements outside of it while it is running. There is no way around that. If it takes 2-3 seconds to call your backend server, you should look into why the response is so slow, what is wrong with your backend or your method on client side etc. –  Sep 03 '17 at 18:52
  • @Sneak Then how come self.acceptedFriends outside of DIOSView in my first if statement works perfectly?? – Brittany Sep 03 '17 at 18:54
  • 1
    I don't know the response and execution timings etc. I am just telling you how it works. You are setting the self.acceptedFriends inside the block, while the block is executing you are doing other things with self.acceptedFriends, no matter the results, they can't be predicated with your execution, unless you move it inside the completion block. You should instead look into 1: why the response is so slow from your server 2: Show a progress/activity indicator for the user while the response is fetching. This should be done anyway, maybe the client has slow connection etc. –  Sep 03 '17 at 18:57
  • You have an `if` and two `else if`s; they're mutually exclusive, so it doesn't make sense to say it's populated inside the first but not the last. Only one of those bodies can be running. Sneak has explained what's going on. You should strongly consider paring down your code locally to try to reproduce the problem, then, if you don't resolve it, editing the code here once you have that minimal example. – jscs Sep 03 '17 at 20:02
  • Also see: [NSMutable array not retaining data after exiting function](https://stackoverflow.com/q/46017607) – jscs Sep 04 '17 at 16:43
  • @JoshCaswell Did a bit of digging - you guys were right, self.acceptedFriends was empty across the board. That said, when I put everything inside of my AFNetworking statement, things work, but anything inside that statement still takes a solid 3 seconds behind everything else to load? I'm not understanding how can I have it load at the same time as my other items? – Brittany Sep 05 '17 at 05:16
  • Great, glad to hear you figured it out! As Sneak said, that's simply down to the speed of the network request, unless DIOSView is doing something non-obvious. If you must have the data before this view is shown, you might have to pre-fetch it. – jscs Sep 05 '17 at 11:22
  • @JoshCaswell Yeah I ended up fetching in the view controller prior to the one I actually need to use the data on and now it works great - thanks a bunch for the insight :) – Brittany Sep 05 '17 at 21:17

0 Answers0