I have a singleton class that checks the login status of the app.
There's a method named attemptToLogin
in the singleton class that makes an http request with parameters and returns with json data about the login status. (true or false)
Now in the main TabBarViewController
i did the following:
@interface CustomTabBarController ()
@end
@implementation CustomTabBarController{
LoginCheckSingleton *loginSingleton;
dispatch_queue_t myCustomQueue;
}
-(void)viewDidAppear:(BOOL)animated{
myCustomQueue = dispatch_queue_create("com.myDomain.appName", NULL);
loginSingleton = [LoginCheckSingleton sharedInstance];
dispatch_sync(myCustomQueue, ^{
[loginSingleton attemptToLogin];
});
if([loginSingleton.loginstat isEqual: @"true"]){
NSLog(@"Logged In");
}else{
NSLog(@"Not Logged In");
[self performSegueWithIdentifier:@"goToLoginView" sender:self];
}
}
The dispatch_sync
is not working properly here, i want to execute the function inside the dispatch_sync and get the results before executing the if
statement under it. But the if
statement is executed before the block inside the dispatch_sync has finished.
This is the Singleton Class
:
#import "LoginCheckSingleton.h"
#import "AFNetworking.h"
#import "SSKeychain.h"
#import "CustomTabBarController.h"
static LoginCheckSingleton *sharedInstance = nil;
@interface LoginCheckSingleton (){
NSString *serverURLString;
NSURL *serverURL;
NSString *userId;
NSString *password;
NSString *email;
NSMutableArray *jsonContents;
NSMutableDictionary *dictionary;
NSString *loggedInStatus;
bool loggedInTF;
}
@end
@implementation LoginCheckSingleton{
}
+ (LoginCheckSingleton*) sharedInstance {
static dispatch_once_t _singletonPredicate;
static LoginCheckSingleton *_singleton = nil;
dispatch_once(&_singletonPredicate, ^{
_singleton = [[super allocWithZone:nil] init];
});
return _singleton;
}
+ (id) allocWithZone:(NSZone *)zone {
return [self sharedInstance];
}
-(void)attemptToLogin{
// Retrieve credentials from Keychain
userId = [SSKeychain passwordForService:@"com.lazemni.iFresh"
account:@"ifreshUserId"];
password = [SSKeychain passwordForService:@"com.lazemni.iFresh"
account:@"ifreshPassword"];
email = [SSKeychain passwordForService:@"com.lazemni.iFresh"
account:@"ifreshEmail"];
if(email == nil || password == nil){
NSLog(@"empty username or password");
}else{
NSLog(@"not empty username or password");
serverURLString = @"http://www.lazemni.com/demo/ifresh/api/login/";
serverURLString = [serverURLString stringByAppendingString:email];
serverURLString = [serverURLString stringByAppendingString:@"/"];
serverURLString = [serverURLString stringByAppendingString:password];
NSLog(@"%@",serverURLString);
serverURL = [NSURL URLWithString:serverURLString];
NSURLRequest *request = [NSURLRequest requestWithURL:serverURL];
//AFNetworking asynchronous url request
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
jsonContents = [responseObject objectForKey:@"login"];
NSLog(@"%@",jsonContents);
dictionary = [jsonContents objectAtIndex:0];
loggedInStatus = [dictionary objectForKey:@"status"];
if([loggedInStatus isEqual: @"true"]){
NSLog(@"Succefully loggedin!");
[SSKeychain setPassword:[dictionary objectForKey:@"user_id"] forService:@"com.lazemni.iFresh" account:@"ifreshUserId"];
[SSKeychain setPassword:[dictionary objectForKey:@"email"] forService:@"com.lazemni.iFresh" account:@"ifreshEmail"];
[SSKeychain setPassword:[dictionary objectForKey:@"password"] forService:@"com.lazemni.iFresh" account:@"ifreshPassword"];
self.loginstat = @"true";
loggedInTF = true;
}else if([loggedInStatus isEqual: @"false"]){
NSLog(@"Wrong email/password combination!");
self.loginstat = @"false";
loggedInTF = false;
}
} failure:nil];
[operation start];
}
}
@end
I never understood how dispatch_sync really works,
Any idea how to wait for the [loginSingleton attemptToLogin];
to finish ?