Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-c + RestKit - Wait for response before next step

Hello and thanks in advance for your help. I've been looking but couldn't find an answer for this. I've only been programing for iOS for a week.

So far, all the connections to the web services are functioning and I've created a class and methods to do those calls. I'm making a standard login, user enters login info, the app passes those values to the web service and it returns a bool value depending if the info matches anything on the database. After that, the app gets the return value and it moves to the next screen or shows an error alert. Or at least that's what I'm aiming for.

The problem is that, the conditional is being executed before the rest call is made or the response parsed and I'm not having much luck finding a solution. I've read about asynchronous and synchronous calls but hadn't have much luck at implementing them.

This is the call code:

//Class that has the methods for calling the web services
__restObj  = [[restCalls alloc] init];
bool login = [__restObj restLogin:user passwd:pass];
if (login) {
   [self performSegueWithIdentifier:@"adminLogin" sender:self];
}
else{
   UIAlertView*alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Incorrect group name or password." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
   [alert show];
}

The conditional in being performed before the actual POST occurs and there for is always false.

This is my method:

- (bool)restLogin:(NSString*)user passwd:(NSString*)pass{
// Load the object model via RestKit
RKObjectManager *objectManager = [RKObjectManager sharedManager];

groupInfo *gi = [[groupInfo alloc] init];

gi.gName = user;
gi.pass = pass;


RKObjectMapping *userInfoMapping = [RKObjectMapping requestMapping];
[userInfoMapping addAttributeMappingsFromDictionary:@{@"gName": @"groupName",@"pass":@"pass"}];

RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:userInfoMapping
                                                                               objectClass:[groupInfo class]
                                                                               rootKeyPath:nil];
[objectManager addRequestDescriptor:requestDescriptor];
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;

[objectManager postObject:gi
                     path:@"adminLoginIos"
               parameters:nil
                  success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
                      NSArray* statuses = [mappingResult array];
                      NSLog(@"Loaded statuses: %@", statuses);
                      _result = [statuses objectAtIndex:0];
                  }
                  failure:^(RKObjectRequestOperation *operation, NSError *error) {
                      NSLog(@"Hit error: %@", error);
                  }
 ];

return _result;
}

Thanks in advance and keep in mind that I'm really new at this so I appreciate your help and if my code is not the best please tell me so.

Regards, ChmlGr

like image 426
user2119777 Avatar asked Dec 08 '25 09:12

user2119777


1 Answers

You need to pass in a block and then inside the success callback, block return the _result.

An example based on your structure would be something like:

-(void) restLogin:(NSString*)user passwd:(NSString*)pass block:(void (^)(id))block {
    // Load the object model via RestKit
    RKObjectManager *objectManager = [RKObjectManager sharedManager];

    groupInfo *gi = [[groupInfo alloc] init];

    gi.gName = user;
    gi.pass = pass;


    RKObjectMapping *userInfoMapping = [RKObjectMapping requestMapping];
    [userInfoMapping addAttributeMappingsFromDictionary:@{@"gName": @"groupName",@"pass":@"pass"}];

    RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:userInfoMapping
                                                                                   objectClass:[groupInfo class]
                                                                                   rootKeyPath:nil];
    [objectManager addRequestDescriptor:requestDescriptor];
    objectManager.requestSerializationMIMEType = RKMIMETypeJSON;

    [objectManager postObject:gi
                         path:@"adminLoginIos"
                   parameters:nil
                      success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
                          NSArray* statuses = [mappingResult array];
                          NSLog(@"Loaded statuses: %@", statuses);
                          _result = [statuses objectAtIndex:0];
                          block(_result);
                      }
                      failure:^(RKObjectRequestOperation *operation, NSError *error) {
                          NSLog(@"Hit error: %@", error);
                          block(nil);
                      }
     ];

}

Your call to that method would be something like:

[__restObj restLogin:user passwd:pass block:^(id obj) {
    // do something here to translate that object into a BOOL and check value    
}];

I don't use RestKit, so I can't verify this is exactly what you need, but it should get you on the right path. That said, if you wanted to check out AFNetworking, I wrote a NetworkClient wrapper that I don't mind sharing.

like image 157
LJ Wilson Avatar answered Dec 09 '25 23:12

LJ Wilson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!