overview : using amazon dynamodb login service. , login method looks in useraccount.m. , calling class method in loginviewcontroller.m on login button tap:
+ (bool)loginwithusername:(nsstring *)username password:(nsstring *)password{ awsdynamodbobjectmapper *dynamodbobjectmapper = [awsdynamodbobjectmapper defaultdynamodbobjectmapper]; bool __block isloginsuccessful = no; [[dynamodbobjectmapper load:[user class] hashkey:username rangekey:@"key"] continuewithblock:^id(awstask *task) { if (task.error) { nslog(@"the request failed. error: [%@]", task.error); } if (task.exception) { nslog(@"the request failed. exception: [%@]", task.exception); } if (task.result) { //do result. user *user = task.result; // user model i'm using nslog(@"pass: %@", user.password); // check returned password dynamodb user-supplied password. if ([user.password isequaltostring:password]) { isloginsuccessful = yes; } } return nil; }]; return isloginsuccessful; // <-- issue: function returns before block executes , isloginsuccessful value changed. } the issue function returns before block executes. tried:
i) read using dispatch groups on question
ii) tried execute method - (awstask *)load:(class)resultclass hashkey:(id)hashkey rangekey:(id)rangekey on main thread still function returns before block execution finishes.:
dispatch_async(dispatch_get_main_queue(), ^{ [[dynamodbobjectmapper load:[user class] hashkey:username rangekey:@"key"] continuewithexecutor:[awsexecutor mainthreadexecutor] withblock:^id(awstask *task) { if (!task.error) { user *user = task.result; nslog(@"pass: %@", user.password); //do result. if ([user.password isequaltostring:password]) { isloginsuccessful = yes; } } else { nslog(@"error: [%@]", task.error); } return nil; }]; }); am missing out here/ doing wrong in approach? suggestion towards right direction helpful. thank you!
edit 1: including function
loginwithusernameclass method being called:
@ibaction func login(sender: anyobject) { if(useraccount.loginwithusername(txtemail.text, password: txtpassword.text)){ println("success") lblincorrect.hidden = true } else{ println("incorrect username/password") lblincorrect.hidden = false } }
it basic idea of gcd blocks executed "in background", control flow can return sender of message before task finished. is, because task potential long runner , not want block sending control flow, esp. if main thread.
if want execute code after finishing operation, add block. code inside login(): add if block , remove block variable , return value. make method void.
to have general pattern:
-(ibaction)dosomething:(id)sender { [self executeoperation]; // method becomes void // remove code processing on result } -(void)executeoperation // method becomes void { [receiver longrunnerwithblock:^(id result) { … // add code processing on result } } please take care, block potentially run on different thread main thread, have dispatch on main thread, if ui related.
Comments
Post a Comment