I'm calling up a session in my LoginViewController as seen below. The problem is that, after it authenticates and closes the popupview... the session returns nil. So it initially reaches out to the api and starts a session (the first log records nil as the session is open and the second log records "Signed in as..." with the username) then when it closes the login view it records nil again. Not exactly use what I could be doing wrong...
Could it be because I'm using TWTRSession* session to check the session? Could that be logging me off? Or is it related to me closing the popupview?
I do essentially the same thing with my facebook login but the facebook session stays open until I logout...
- (void)viewDidLoad
{
[super viewDidLoad];
self.email.delegate = self;
self.pass.delegate = self;
//self.view.frame = CGRectMake(self.bounds.size.width, self.bounds.size.height);
[Fabric with:#[[Twitter sharedInstance]]];
TWTRSession* session;
if (session) {
NSLog(#"Early bird %#", [session userName]);
[self closePopup];
}
else {
NSLog(#"No dice");
}
/*
TWTRLogInButton *logInButton = [TWTRLogInButton buttonWithLogInCompletion:^(TWTRSession *session, NSError *error) {
// play with Twitter session
}];
logInButton.center = self.view.center;
[self.view addSubview:logInButton];
*/
TWTRLogInButton* logInButton = [TWTRLogInButton
buttonWithLogInCompletion:
^(TWTRSession* session, NSError* error) {
if (session) {
NSLog(#"signed in as %#", [session userName]);
[self closePopup];
} else {
NSLog(#"error: %#", [error localizedDescription]);
}
}];
I decided to include my actionsheet as well so you could see how I'm handling the login/logout situation:
- (void)sheet: (id) sender {
NSString *email = [[NSUserDefaults standardUserDefaults] objectForKey:#"email"];
UIActionSheet *sheet;
TWTRSession *session;
//if ([FBSDKAccessToken currentAccessToken]) {
if (email == nil && [FBSDKAccessToken currentAccessToken] == nil && session == nil) {
sheet = [[UIActionSheet alloc] initWithTitle:#"Profile"
delegate:nil // Can be another value but will be overridden when showing with handler.
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:#"Login"
otherButtonTitles:nil];
}
else
{
sheet = [[UIActionSheet alloc] initWithTitle:#"Profile"
delegate:nil // Can be another value but will be overridden when showing with handler.
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:#"Logout"
otherButtonTitles:#"User page", nil];
}
[sheet showInView:self.view
handler:^(UIActionSheet *actionSheet, NSInteger buttonIndex) {
if (buttonIndex == [actionSheet cancelButtonIndex]) {
NSLog(#"Cancel button index tapped");
} else if (buttonIndex == [actionSheet destructiveButtonIndex]) {
if (email == nil && [FBSDKAccessToken currentAccessToken] == nil && session == nil) {
LoginViewController *loginView = [[LoginViewController alloc] initWithNibName:#"LoginView" bundle:[NSBundle mainBundle]];
//[self.view modalViewController:loginView animated:YES];
//[self presentModalViewController:loginView animated:YES];
//[self.navigationController pushViewController:loginView animated:YES];
loginView.delegate = (id) self;
[self presentPopupViewController:loginView animationType:MJPopupViewAnimationSlideTopBottom];
NSLog(#"Login View");
}
else
{
[[NSUserDefaults standardUserDefaults] setObject:nil forKey:#"email"];
FBSDKLoginManager *logout = [[FBSDKLoginManager alloc] init];
[logout logOut];
}
} else {
NSLog(#"Button %i tapped", buttonIndex);
if (buttonIndex == 1) {
UserViewController * userView = [[UserViewController alloc] initWithNibName:#"UserView" bundle:[NSBundle mainBundle]];
[userView setUEmail:email];
[self presentViewController:userView animated:YES completion:nil];
}
}
}];
}
So I ended up creating my own custom IBAction to handle twitter logins. This works much better. Basically you just have to be careful with how you check if a session is active:
-(IBAction)twlogin:(id)sender
{
[Fabric with:#[[Twitter sharedInstance]]];
[[Twitter sharedInstance] logInWithCompletion:^
(TWTRSession *session, NSError *error) {
if (session) {
NSLog(#"signed in as %#", [session userName]);
TWTRShareEmailViewController* shareEmailViewController =
[[TWTRShareEmailViewController alloc]
initWithCompletion:^(NSString* email2, NSError* error) {
NSLog(#"Email %#, Error: %#", email2, error);
}];
[self presentViewController:shareEmailViewController
animated:YES
completion:nil];
[self closePopup];
NSLog(#"session check %#", [session userName]);
} else {
NSLog(#"error: %#", [error localizedDescription]);
}
}];
[[Twitter sharedInstance] logOut];
}
As you can see TWTR *session has to be included with Twitter shared instance like so:
[[Twitter sharedInstance] logInWithCompletion:^
(TWTRSession *session, NSError *error) {
I didn't do that before, and that's why it wasn't working. Hopefully this helps someone. (now if someone would help me getting Twitter emails to work... that would be greatly appreciated...)
Related
I have downloaded Parse's app, Anypic, but cannot get it to run properly on my phone. I have completed all of the required steps and it says "build succeeded" when I run it.
However, all that shows up is a black screen and a Facebook "login" button. When the button is clicked, you can login to Facebook but then it just changes the button to say "log out" which is not exactly wha
I have attached a picture with all my warnings I get. Are the warnings the issue or is there something else I need to change in the code? Thanks!
You should change handleFacebookSession part to look like this:
- (void)handleFacebookSession {
if ([PFUser currentUser]) {
if (self.delegate && [self.delegate respondsToSelector:#selector(logInViewControllerDidLogUserIn:)]) {
[self.delegate performSelector:#selector(logInViewControllerDidLogUserIn:) withObject:[PFUser currentUser]];
}
return;
}
NSArray *permissionsArray = #[ #"public_profile",
#"user_friends",
#"email"];
self.hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
// Login PFUser using Facebook
[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
if (!user) {
NSString *errorMessage = nil;
if (!error) {
NSLog(#"Uh oh. The user cancelled the Facebook login.");
errorMessage = #"Uh oh. The user cancelled the Facebook login.";
} else {
NSLog(#"Uh oh. An error occurred: %#", error);
errorMessage = [error localizedDescription];
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Log In Error"
message:errorMessage
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"Dismiss", nil];
[alert show];
} else {
if (user.isNew) {
NSLog(#"User with facebook signed up and logged in!");
} else {
NSLog(#"User with facebook logged in!");
}
if (!error) {
[self.hud removeFromSuperview];
if (self.delegate) {
if ([self.delegate respondsToSelector:#selector(logInViewControllerDidLogUserIn:)]) {
[self.delegate performSelector:#selector(logInViewControllerDidLogUserIn:) withObject:user];
}
}
} else {
[self cancelLogIn:error];
}
}
}];}
Found here.
I released my app yesterday and few units were sold so far. But I figured out that the leaderboard doesn't work properly. I can only see my own score when I'm done with my game. Is there some kind of delay until the leaderboard is updated or is it a problem on my implementation? I'd really appreciate if I have my implementation checked by someone who knows how to do it properly. On a side note, I already configured my leaderboard on itunes-connect and enabled it as well. I'm not sure if GKLocalPlayer's instance method loadDefaultLeaderboardIdentifierWithCompletionHandler:^(NSString *leaderboardIdentifier, NSError *error) is the right method to use to load the correct leaderboardID. Do I manually have to declare my leaderboard ID on Xcode somewhere with the leaderboardID I created on itunes-connect? because I find it odd that I never get to use it on the actual implementation... I want this error fixed as soon as possible and I need you guys' help. Thanks.
(void)authenticateLocalPlayer {
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error){
if (viewController != nil) {
[self presentViewController:viewController animated:YES completion:nil];
}
else{
if ([GKLocalPlayer localPlayer].authenticated) {
_gameCenterEnabled = YES;
NSLog(#"authenticated");
// Get the default leaderboard identifier.
[[GKLocalPlayer localPlayer] loadDefaultLeaderboardIdentifierWithCompletionHandler:^(NSString *leaderboardIdentifier, NSError *error) {
if (error != nil) {
NSLog(#"here");
NSLog(#"%#", [error description]);
}
else{
_leaderboardIdentifier = leaderboardIdentifier;
}
}];
}
else{
_gameCenterEnabled = NO;
}
}
};
}
- (void)reportScore:(NSNotification *) notification {
if (_gameCenterEnabled) {
NSDictionary *userInfo = notification.userInfo;
NSNumber *score = [userInfo objectForKey:#"highestScore"];
GKScore *gkscore = [[GKScore alloc]initWithLeaderboardIdentifier:_leaderboardIdentifier];
gkscore.value = [score integerValue];
[GKScore reportScores:#[gkscore] withCompletionHandler:^(NSError *error) {
if (error != nil) {
NSLog(#"%#", [error localizedDescription]);
}
}];
}
}
- (void)showLeaderboard{
GKGameCenterViewController *gcViewController = [[GKGameCenterViewController alloc] init];
gcViewController.gameCenterDelegate = self;
gcViewController.viewState = GKGameCenterViewControllerStateLeaderboards;
gcViewController.leaderboardIdentifier = _leaderboardIdentifier;
[self presentViewController:gcViewController animated:YES completion:nil];
}
- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController
{
[gameCenterViewController dismissViewControllerAnimated:YES completion:nil];
}
I'm having trouble coming up with a solution to the following from the Simple Login iOS quick start:
Since it is possible for a device to have more than one Twitter account attached, you will need to provide a block which can be used to determine which account to log in. Replace "[yourApp selectUserName:usernames]" below with your own code to choose from the list of usernames.
This is the code that is provided:
[authClient loginToTwitterAppWithId:#"YOUR_CONSUMER_KEY"
multipleAccountsHandler:^int(NSArray *usernames) {
// If you do not wish to authenticate with any of these usernames, return NSNotFound.
return [yourApp selectUserName:usernames];
} withCompletionBlock:^(NSError *error, FAUser *user) {
if (error != nil) {
// There was an error authenticating
} else {
// We have an authenticated Twitter user
}
}];
Would a UIActionSheet that allows the user to pick which account to use be best? How would that be done?
#import <Twitter/Twitter.h>
#import <Accounts/Accounts.h>
For login:
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
// Create an account type that ensures Twitter accounts are retrieved.
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) {
// Request access from the user to use their Twitter accounts.
// [accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
//NSLog(#"%#",error);
if(granted) {
// Get the list of Twitter accounts.
NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
//NSLog(#"%#",accountsArray);
twitterAccountsArray=[accountsArray mutableCopy];
if ([twitterAccountsArray count] > 0){
sheet = [[UIActionSheet alloc] initWithTitle:#"Choose an Account" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
for (ACAccount *acct in twitterAccountsArray) {
[sheet addButtonWithTitle:acct.username];
}
}
}
else{
dispatch_async(dispatch_get_main_queue(), ^{
//NSLog(#"%#",error);
if (![error.localizedDescription isEqual:[NSNull null]] &&[error.localizedDescription isEqualToString:#"No access plugin was found that supports the account type com.apple.twitter"]) {
}
else
[Utility showAlertWithString:#"We could not find any Twitter account on the device"];
});
}
}];
It will open an action sheet which will show you the list of accounts your device has.
For posting :
There must be at least one valid twitter account added on your iPhone device.
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
{
NSString *initialText=#"Text to be posted";
SLComposeViewController *tweetSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
tweetSheet.completionHandler = ^(SLComposeViewControllerResult result) {
switch(result) {
// This means the user cancelled without sending the Tweet
case SLComposeViewControllerResultCancelled:{
}
break;
case SLComposeViewControllerResultDone:{
}
break;
}
};
[tweetSheet setInitialText:initialText];
if (initialText) {
[self presentViewController:tweetSheet animated:YES completion:nil];
}
}
I've found a nice example of how to do this with Awesome Chat's code. It uses a UIActionSheet like I was attempting to.
//-------------------------------------------------------------------------------------------------------------------------------------------------
- (IBAction)actionTwitter:(id)sender
//-------------------------------------------------------------------------------------------------------------------------------------------------
{
[ProgressHUD show:#"In progress..." Interaction:NO];
//---------------------------------------------------------------------------------------------------------------------------------------------
selected = 0;
//---------------------------------------------------------------------------------------------------------------------------------------------
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
//---------------------------------------------------------------------------------------------------------------------------------------------
[account requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error)
{
if (granted)
{
accounts = [account accountsWithAccountType:accountType];
//-------------------------------------------------------------------------------------------------------------------------------------
if ([accounts count] == 0)
[self performSelectorOnMainThread:#selector(showError:) withObject:#"No Twitter account was found" waitUntilDone:NO];
//-------------------------------------------------------------------------------------------------------------------------------------
if ([accounts count] == 1) [self performSelectorOnMainThread:#selector(loginTwitter) withObject:nil waitUntilDone:NO];
if ([accounts count] >= 2) [self performSelectorOnMainThread:#selector(selectTwitter) withObject:nil waitUntilDone:NO];
}
else [self performSelectorOnMainThread:#selector(showError:) withObject:#"Access to Twitter account was not granted" waitUntilDone:NO];
}];
}
//-------------------------------------------------------------------------------------------------------------------------------------------------
- (void)selectTwitter
//-------------------------------------------------------------------------------------------------------------------------------------------------
{
UIActionSheet *action = [[UIActionSheet alloc] initWithTitle:#"Choose Twitter account" delegate:self cancelButtonTitle:nil
destructiveButtonTitle:nil otherButtonTitles:nil];
//---------------------------------------------------------------------------------------------------------------------------------------------
for (NSInteger i=0; i<[accounts count]; i++)
{
ACAccount *account = [accounts objectAtIndex:i];
[action addButtonWithTitle:account.username];
}
//---------------------------------------------------------------------------------------------------------------------------------------------
[action addButtonWithTitle:#"Cancel"];
action.cancelButtonIndex = accounts.count;
[action showInView:self.view];
}
//-------------------------------------------------------------------------------------------------------------------------------------------------
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
//-------------------------------------------------------------------------------------------------------------------------------------------------
{
if (buttonIndex != actionSheet.cancelButtonIndex)
{
selected = buttonIndex;
[self loginTwitter];
}
else [ProgressHUD dismiss];
}
//-------------------------------------------------------------------------------------------------------------------------------------------------
- (void)loginTwitter
//-------------------------------------------------------------------------------------------------------------------------------------------------
{
Firebase *ref = [[Firebase alloc] initWithUrl:FIREBASE];
FirebaseSimpleLogin *authClient = [[FirebaseSimpleLogin alloc] initWithRef:ref];
//---------------------------------------------------------------------------------------------------------------------------------------------
[authClient loginToTwitterAppWithId:TWITTER_KEY multipleAccountsHandler:^int(NSArray *usernames)
{
return (int) selected;
}
withCompletionBlock:^(NSError *error, FAUser *user)
{
if (error == nil)
{
if (user != nil) [delegate didFinishLogin:ParseUserData(user.thirdPartyUserData)];
[self dismissViewControllerAnimated:YES completion:^{ [ProgressHUD dismiss]; }];
}
else
{
NSString *message = [error.userInfo valueForKey:#"NSLocalizedDescription"];
[self performSelectorOnMainThread:#selector(showError:) withObject:message waitUntilDone:NO];
}
}];
}
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.
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.