IOS - Touch ID Authentication takes more time after loading - ios

I have made one demo for login application with touch id authentication.
It is going fine with touch id authentication but,
My Problem is
When I do authentication with my touch id it gives me immediate response according the finger scans , But after messaging it took so much time for further process like move forward or display result which I have placed on success.
I have also used Switch Case Statements in my code.
Code is
- (IBAction)touchidRegistration:(id)sender {
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
NSString *myLocalizedReasonString = #"Authenticate using your finger";
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
self.myHud.hidden = NO;
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:myLocalizedReasonString
reply:^(BOOL succes, NSError *error) {
if (succes) {
self.btnRegister.enabled = YES;
// self.myHud.hidden = YES;
self.registrationFlag = #"YES";
self.flag = #"";
self.verifiedImage.hidden = NO;
NSLog(#"flag Value is %#",self.flag);
NSLog(#"Done!!!");
[self showMessage:#"Authentication is successful" withTitle:#"Success"];
NSLog(#"User authenticated");
} else {
switch (error.code) {
case LAErrorAuthenticationFailed:
self.myHud.hidden = YES;
[self showMessage:#"Authentication is failed" withTitle:#"Error"];
NSLog(#"Authentication Failed");
break;
case LAErrorUserCancel:
self.myHud.hidden = YES;
[self showMessage:#"You clicked on Cancel" withTitle:#"Error"];
NSLog(#"User pressed Cancel button");
break;
case LAErrorUserFallback:
self.myHud.hidden = YES;
[self showMessage:#"You clicked on \"Enter Password\"" withTitle:#"Error"];
NSLog(#"User pressed \"Enter Password\"");
break;
default:
self.myHud.hidden = YES;
[self showMessage:#"Touch ID is not configured" withTitle:#"Error"];
NSLog(#"Touch ID is not configured");
break;
}
NSLog(#"Authentication Fails");
}
}];
} else {
self.myHud.hidden = YES;
NSLog(#"Can not evaluate Touch ID");
[self showMessage:#"Can not evaluate TouchID" withTitle:#"Error"];
}
}
Please help me guys or suggest me any link I do not able to search this type of problem on here.I have seen one but its for Swift,I need for OBJECTIVE - C
link:- swift - touchID takes long time to load
Note:-I am using I-Phone 6 device for testing.
Thanks in advance.

Finally I got the answer ,
Its Working Fine For me thank you
if (succes) {
NSOperationQueue *myQueue = [[NSOperationQueue alloc] init];
[myQueue addOperationWithBlock:^{
// Background work
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// Main thread work (UI usually)
NSMutableDictionary *userInfo = [StaticClass getTouchIdData:#"userInfo"];
if(!([userInfo count] == 0))
{
self.myHud.hidden = YES;
self.flag = #"";
TestViewController *testView = [[TestViewController alloc]initWithNibName:#"TestViewController" bundle:nil];
[testView setUserInfo:userInfo];
[self.navigationController pushViewController:testView animated:YES];
}
else
{
self.myHud.hidden = YES;
self.flag = #"YES";
self.registrationFlag = #"";
[self showMessage:#"For The First time user ,You have to login manually" withTitle:#"Error"];
self.touchIdLoginView.hidden = YES;
}
NSLog(#"User Id is %#",userInfo);
NSLog(#"Done!!!");
NSLog(#"User authenticated");
}];
}];

Related

LAContext showing pop up every times

- (void)touchIdIntegration{
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:#"Authenticate via Touch ID to unlock the app"
reply:^(BOOL success, NSError *error) {
if (success) {
dispatch_async(dispatch_get_main_queue(), ^{
[[AppManager instance].helpManager setDontShowInterstialAd:TRUE];
[[AppManager instance].cycleManager setUserAuthenticated:TRUE];
[self.delegate showAlertViewsOnServerData];
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
switch (error.code) {
case kLAErrorAuthenticationFailed:
NSLog(#"kLAErrorAuthenticationFailed");
break;
case kLAErrorTouchIDNotEnrolled:
NSLog(#"kLAErrorTouchIDNotEnrolled");
break;
case LAErrorPasscodeNotSet:
NSLog(#"LAError code ");
break;
default:
break;
}
});
}
}];
} else {
dispatch_async(dispatch_get_main_queue(), ^{
self.m_imgFingerPrint.hidden = YES;
NSLog(#"LAError code %ld",authError.code);
NSString *alertMessage =nil;
switch (authError.code) {
case kLAErrorAuthenticationFailed:
{
alertMessage = #"kLAErrorAuthenticationFailed" ;
}
break;
case kLAErrorTouchIDNotEnrolled:
alertMessage = #"kLAErrorTouchIDNotEnrolled" ;
break;
case LAErrorPasscodeNotSet:
alertMessage = #"LAErrorPasscodeNotSet" ;
break;
default:
break;
}
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:alertMessage
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
[alertView show];
});
}
}
I don't want this pop up each every time when user moves to this screen.Is it possible or not ?Please let me know.
please find the screen shot below:
Anyways thanks in advance.
Don't write this code viewDidLoad or viewDidAppear. Write it only when it is absolutely required to ask for touchID.

how to Use Default LoginWithFacebook Button in my code

here is my code which is running properly but I want to use LoginWithFacebook default button which is provided by facebook.
Is there any image provided by facebook then please give me suggestion.
thankx in advance.....
#import "FacebbokViewController.h"
#import "UserAppAppDelegate.h"
#interface FacebbokViewController ()
#end
#implementation FacebbokViewController
- (id)init
{
self = [super init];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// button which I have used
UIButton *login=[[UIButton alloc]initWithFrame:CGRectMake(100,100, 200,80)];
[login setBackgroundColor:[UIColor blueColor]];
[login setTitle:#"login With facebook" forState:UIControlStateNormal];
[login setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[login addTarget:self action:#selector(loginWithFacebook) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:login];
}
// method which excute on my button click
-(IBAction)loginWithFacebook{
UserAppAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"email", nil];
if(!appDelegate.session.isOpen)
{
// create a fresh session object
appDelegate.session = [[FBSession alloc] init];
[FBSession setActiveSession: appDelegate.session];
[FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
else{
NSLog(#"hi");
}
}
- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error
{
// If the session was opened successfully
if (!error && state == FBSessionStateOpen){
NSLog(#"Session opened");
[self userData]; // method created to fetch user’s data.
// Show the user the logged-in UI
// do all the things as you have the info you requested from facebook
return;
}
if (state == FBSessionStateClosed || state == FBSessionStateClosedLoginFailed){
// If the session is closed
NSLog(#"Session closed");
// Show the user the logged-out UI
[FBSession.activeSession closeAndClearTokenInformation];
}
// Handle errors
if (error){
NSLog(#"Error");
NSString *alertText;
NSString *alertTitle;
// If the error requires people using an app to make an action outside of the app in order to recover
if ([FBErrorUtility shouldNotifyUserForError:error] == YES){
alertTitle = #"Something went wrong";
alertText = [FBErrorUtility userMessageForError:error];
[self showMessage:alertText withTitle:alertTitle];
} else {
// If the user cancelled login, do nothing
if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryUserCancelled) {
NSLog(#"User cancelled login");
// Handle session closures that happen outside of the app
} else if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryAuthenticationReopenSession){
alertTitle = #"Session Error";
alertText = #"Your current session is no longer valid. Please log in again.";
[self showMessage:alertText withTitle:alertTitle];
// Here we will handle all other errors with a generic error message.
// We recommend you check our Handling Errors guide for more information
// https://developers.facebook.com/docs/ios/errors/
} else {
//Get more error information from the error
NSDictionary *errorInformation = [[[error.userInfo objectForKey:#"com.facebook.sdk:ParsedJSONResponseKey"] objectForKey:#"body"] objectForKey:#"error"];
// Show the user an error message
alertTitle = #"Something went wrong";
alertText = [NSString stringWithFormat:#"Please retry. \n\n If the problem persists contact us and mention this error code: %#", [errorInformation objectForKey:#"message"]];
[self showMessage:alertText withTitle:alertTitle];
}
}
// Clear this token
[FBSession.activeSession closeAndClearTokenInformation];
}
}
-(void)showMessage:(NSString*)alertMessage withTitle:(NSString*)alertTitle
{
[[[UIAlertView alloc] initWithTitle:alertTitle
message:alertMessage
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] show];
}
-(void)userData
{
// Start the facebook request
[FBRequestConnection startWithGraphPath:#"me" parameters:[NSDictionary dictionaryWithObject:#"id,email" forKey:#"fields"] HTTPMethod:#"GET" completionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *result, NSError *error)
{
//if(!error){
// NSLog(#"result %#",result);
NSString *fbid =result[#"email"];
NSLog(#"result %#",fbid);
//}
}];
}
you can use FBLoginView to have the the functionality as your requirement , you can use like this
FBLoginView *loginView = [[FBLoginView alloc] init];
loginView.frame = YOURFRAME;
[self.view addSubview:loginView];
Take a look at FBLoginView in the Facebook SDK. Official link/tutorial. In the later part of the tutorial, implementing custom views and logging in with API calls is also covered. But note that you would have to design your button on your own in the latter case.

Spotify EXC_BAD_EXE while second time tap on Login Button after dismiss LoginViewController

Hi i Intigrate SpotifyLib CocoaLibSpotify iOS Library 17-20-26-630 into my Project. I open its SPLoginViewController using Bellow Method:-
-(void)OpenSpotify
{
NSError *error = nil;
[SPSession initializeSharedSessionWithApplicationKey:[NSData dataWithBytes:&g_appkey length:g_appkey_size]
userAgent:#"com.mycomp.spotify"
loadingPolicy:SPAsyncLoadingImmediate
error:&error];
if (error != nil) {
NSLog(#"CocoaLibSpotify init failed: %#", error);
abort();
}
[[SPSession sharedSession] setDelegate:self];
[self performSelector:#selector(showLogin) withObject:nil afterDelay:0.0];
}
-(void)showLogin
{
SPLoginViewController *controller = [SPLoginViewController loginControllerForSession:[SPSession sharedSession]];
controller.allowsCancel = YES;
//controller.view.frame=;
[self presentViewController:controller animated:YES completion:nil];
}
At First time that Appear Spotify Login Screen. After that I tap On Cancel Button, and Try to open again login screen then i got crash EXC_BAD_EXE at this line. sp_error createErrorCode = sp_session_create(&config, &_session);
UPDATE
I Found exet where is got BAD_EXC
in this method
+(void)dispatchToLibSpotifyThread:(dispatch_block_t)block waitUntilDone:(BOOL)wait {
NSLock *waitingLock = nil;
if (wait) waitingLock = [NSLock new];
// Make sure we only queue one thing at a time, and only
// when the runloop is ready for it.
[runloopReadyLock lockWhenCondition:1];
CFRunLoopPerformBlock(libspotify_runloop, kCFRunLoopDefaultMode, ^() {
[waitingLock lock];
if (block) { #autoreleasepool { block(); } }
[waitingLock unlock];
});
if (CFRunLoopIsWaiting(libspotify_runloop)) {
CFRunLoopSourceSignal(libspotify_runloop_source);
CFRunLoopWakeUp(libspotify_runloop);
}
[runloopReadyLock unlock]; // at hear when my debug poin reach after pass this i got bad_exc
if (wait) {
[waitingLock lock];
[waitingLock unlock];
}
}
after doing lots of search i got Solution i check that whether the session already exists then i put if condition like:-
-(void)OpenSpotify
{
SPSession *session = [SPSession sharedSession];
if (!session) {
NSError *error = nil;
[SPSession initializeSharedSessionWithApplicationKey:[NSData dataWithBytes:&g_appkey length:g_appkey_size]
userAgent:#"com.mycomp.spotify"
loadingPolicy:SPAsyncLoadingImmediate
error:&error];
if (error != nil) {
NSLog(#"CocoaLibSpotify init failed: %#", error);
abort();
}
[[SPSession sharedSession] setDelegate:self];
}
[self performSelector:#selector(showLogin) withObject:nil afterDelay:0.0];
}
-(void)showLogin
{
SPLoginViewController *controller = [SPLoginViewController loginControllerForSession:[SPSession sharedSession]];
controller.allowsCancel = YES;
[self presentViewController:controller animated:YES completion:nil];
}
Now no crash and working fine.

App crashed after enable or disable calendar from settings

I have implemented EKEventStore, EKCalendar in my app to make the EKEvent within the app. It is working fine until or unless I didn't change permissions from the settings. But when I changed the requested access (on/off or off/on) from the settings, the app get crashed. I am unable to find the error. If someone has idea then please help me out. Here is the code I have implemented :
self.eventStore = [[EKEventStore alloc] init];
[self checkEventStoreAccessForCalendar];
-(void)checkEventStoreAccessForCalendar
{
EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent];
switch (status)
{
case EKAuthorizationStatusAuthorized: [self accessGrantedForCalendar];
break;
case EKAuthorizationStatusNotDetermined: [self requestCalendarAccess];
break;
case EKAuthorizationStatusDenied:
case EKAuthorizationStatusRestricted:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Privacy Warning" message:#"Permission was not granted for Calendar"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
break;
default:
break;
} }
-(void)requestCalendarAccess
{
[self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted,
NSError *error)
{
if (granted)
{
dispatch_async(dispatch_get_main_queue(), ^{
});
}
}];
}
-(void)accessGrantedForCalendar
{
self.defaultCalendar = self.eventStore.defaultCalendarForNewEvents;
EKEvent *addEvent = [EKEvent eventWithEventStore:self.eventStore];
addEvent.title = [NSString stringWithFormat:#"%#", textcontainer.text];
}
#pragma mark EKEventEditViewDelegate
-(void)eventEditViewController:(EKEventEditViewController *)controller
didCompleteWithAction:(EKEventEditViewAction)action{
[self dismissViewControllerAnimated:YES completion:^
{
if (action != EKEventEditViewActionCanceled)
{
dispatch_async(dispatch_get_main_queue(), ^{
});
}
}];
}
- (EKCalendar *)eventEditViewControllerDefaultCalendarForNewEvents:(EKEventEditViewController *)controller
{
return self.defaultCalendar;
}
When your app goes to the background it should save all its states and should be prepared to get killed. When someone switches off access to calendar, the easiest way for the system to deals with that is to kill your app, and that is why its happening. If you switch back to your app by clicking 'Back to Your-App' on top, you can notice that your app will be launching from the beginning, not from where you left. Try not using the breakpoint and you will notice the change.
So its not a crash actually.

about Game Center's [Finding a Match Programmatically]

My project need a online play.
GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
request.minPlayers = 2;
request.maxPlayers = 2;
GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];
mmvc.matchmakerDelegate = self;
[presentingViewController presentModalViewController:mmvc animated:YES];
the above code made a GameCenter view,if i press button named"Play now",it will call "GKMatchDelegate's [- (void)match:(GKMatch *)theMatch player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state]", its works ok.
but now, i need use "Finding a Match Programmatically", find match directly with out the official view.
[[GKMatchmaker sharedMatchmaker]findMatchForRequest:request withCompletionHandler:^(GKMatch *hasmatch, NSError *error) {
if(error)
{
NSLog(#"has error match!!!");
}
else if(hasmatch)
{
NSLog(#"has match!!!");//in test we really find the match.
[presentingViewController dismissModalViewControllerAnimated:YES];
self.match = hasmatch;
self.match.delegate = self;
}
}];
now the "GKMatchDelegate's [- (void)match:(GKMatch *)theMatch player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state]" didn't work.
what should i do,to start the online match?
- (void)match:(GKMatch *)theMatch player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state {
if (self.match != theMatch) return;
switch (state) {
case GKPlayerStateConnected:
// handle a new player connection.
NSLog(#"Player connected!");
if (!matchStarted && theMatch.expectedPlayerCount == 0) {
NSLog(#"Ready to start match!");
[self lookupPlayers];//i start game here
}
break;
case GKPlayerStateDisconnected:
// a player just disconnected.
NSLog(#"Player disconnected!");
matchStarted = NO;
[delegate matchEnded];
break;
}
}

Resources