Trying to switch views using a button only in a specific case - iphone

Using a Parse Framework, I am trying to have a user login to an app and if the login works when the user presses the login button, I want the view to change. In this specific case if(!error) I want the view to switch. Assuming the second view is called PostingViewController, how could I make this work?
-(IBAction)signUpButton:(id)sender
{
NSString *userInput = usernameInputField.text;
NSString *userPassword = passwordInputField.text;
PFUser *user = [PFUser user];
user.username = userInput;
user.password = userPassword;
[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if(!error){
}
else{
NSLog(#"there was a problem");
}
}];
}

simply create an object of PostingViewController object and push it to the current navigationController
some thing similar to this might be of help...
PostingViewController *vc = [[PostingViewController alloc] initWithNibName:#"your_nib_name" andBundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:vc withAnimation:YES];
[vc release];

Related

iPhone App Crash with error [UIApplication _cachedSystemAnimationFenceCreatingIfNecessary:]

I have an iPhone App in the app store which is using Touch ID. If Touch ID is enabled, the user is authenticated with it, else user needs to enter his PIN to login to the application.
After IOS 10.1 release, when I checked the crash report, the crash count has increased. From the crash report, it is pointing on [UIApplication _cachedSystemAnimationFenceCreatingIfNecessary:] and when I opened the app in Xcode, it is focussing on [self dismissViewControllerAnimated:YES completion:nil];.
The code I have written is as below:
-(void) showTouchIDAuthentication{
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
NSString *myLocalizedReasonString = #"Authenticate using your finger to access My Account Menu.";
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:myLocalizedReasonString
reply:^(BOOL success, NSError *error) {
if (success) {
NSLog(#"User is authenticated successfully");
[self dismissViewControllerAnimated:YES completion:nil];
} else {
}];
}
}
When I tested in iPhone 6, IOS 10, everything is working fine. Don't know how to simulate the issue.
Can anyone please figure out if I am missing something? Please help me out in resolving this crash issue.
Usually completion handlers are not running on main thread. All UI related stuff must be done on main thread (including dismissing a view controller).
I suggest to add the dismiss line on a main thread block like this:
-(void) showTouchIDAuthentication{
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
NSString *myLocalizedReasonString = #"Authenticate using your finger to access My Account Menu.";
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:myLocalizedReasonString
reply:^(BOOL success, NSError *error) {
if (success) {
NSLog(#"User is authenticated successfully");
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
[self dismissViewControllerAnimated:YES completion:nil];
}];
} else {
}];
}
}

LinkedIn iOS integration

I am integrating Linked-in in my iOS application to Login my app.it works fine for me ..it login successfully when i enter the credentials in the app and enters in the app successfully ....but when i logout and login again it ask for the Access-->allow access button without asking the credientials but I want allow access page should not come on the next login ...means after logout when again i click on the linkedin``login...it should directly access to the app ..should not ask for image 2..
image 2 which comes on the second time login..which i dont want to come
.
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
NSMutableArray *toolbarButtons = [toolBar.items mutableCopy];
// toolbarItems = [[NSMutableArray arrayWithArray:toolbar.items]
// This is how you remove the button from the toolbar and animate it
// This is how you add the button to the toolbar and animate it
if (!firstTime1||![loginView canGoBack])
{
[toolbarButtons removeObject:backButton];
[toolBar setItems:toolbarButtons animated:YES];
firstTime1=YES;
}
NSURL *url = request.URL;
NSString *urlString = url.absoluteString;
BOOL requestForCallbackURL = ([urlString rangeOfString:[LinkedIn linked].linkedInCallbackURL].location != NSNotFound);
if ( requestForCallbackURL )
{
BOOL userAllowedAccess = ([urlString rangeOfString:#"user_refused"].location == NSNotFound);
if ( userAllowedAccess )
{
if ([self logoutPreviousSession])
{
[[NSUserDefaults standardUserDefaults] setInteger:1 forKey:#"SuccessfulLogin"];
[DelegateClass magazine]._loggedThrough=#"LinkedIn";
[[LinkedIn linked].requestToken setVerifierWithUrl:url];
[[LinkedIn linked] accessTokenFromProvider];
}
}
else
{
[self dismissModalViewControllerAnimated:YES];
}
}
return YES;
}

Integrate facebook login and fetch user details along with tabbarcontroller in ios6

I have implemented facebook login in my app.
1----> I was able to do facebook login but after that logged in user is able to continue with my app i.e a tabbarController with three tab items appears and simultaneously I need to fetch facebook user details (email,firstname,lastname etc)
But I was unable to retrieve details. I do not understand where am I going wrong.
In my ViewController.m:
- (IBAction)performLogin:(id)sender
{
AppAppDelegate *appDelegate = (AppAppDelegate *) [[UIApplication sharedApplication] delegate];
[appDelegate openSessionWithAllowLoginUI:YES];
UITabBarController *tabBarController=[[UITabBarController alloc]init];
SearchViewController *searchViewController=[[SearchViewController alloc]initWithNibName:#"SearchViewController" bundle:nil];
UProfile *uprofile=[[UProfile alloc]initWithNibName:#"UProfile" bundle:nil];
userprofile.title=#"My Profile";
LogOut *logout=[[LogOut alloc]initWithNibName:#"LogOut" bundle:nil];
logout.title=#"Sign out";
tabBarController.viewControllers=[NSArray arrayWithObjects:searchViewController,uprofile,logout, nil];
[self presentModalViewController:tabBarController animated:YES];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(sessionStateChanged:)
name:FBSessionStateChangedNotification
object:nil];
}
- (void)sessionStateChanged:(NSNotification*)notification {
if (FBSession.activeSession.isOpen) {
[FBRequestConnection
startForMeWithCompletionHandler:^(FBRequestConnection *connection,
id<FBGraphUser> user,
NSError *error) {
if (!error) {
NSString *fbUserEmail= #"";
NSLog(#"%#",user);
fbUserEmail=[user objectForKey:#"email"];
AppAppDelegate *appDelegate = (AppAppDelegate *) [[UIApplication sharedApplication] delegate];
appDelegate.fbEmail=fbUserEmail;
}
}
];
}
}
But here without showing facebook login page I am getting tabbarController and I am unable to retrieve user details.
How can I show facebook login page first and then tabbarController with user details?
After successful login into facebook how can I continue with my app with a tabbarcontroller with first tabitem(corresponding view )selected?
Please help me out in sorting this issue...Please
You will need to set the readPermissions for getting the email for this method, by passing it an NSArray with object "email". The remaining information such as name etc is returned by default.
+ (BOOL)openActiveSessionWithReadPermissions:(NSArray*)readPermissions
allowLoginUI:(BOOL)allowLoginUI
completionHandler:(FBSessionStateHandler)handler;
of the facebook sdk. If im not mistaken, unless specified permission is "email" then the email object of the user dictionary is nil. Modify your state changed handler perhaps to request the user details such as email. Inside the sessionStateChanged: handler if session is open u may call a method that simply does this
if (FBSession.activeSession.isOpen) {
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *user,
NSError *error) {
if (!error) {
NSLog(#"%#", user);
NSLog(#"%#", [user objectForKey:#"email"]);
}
}];
}

Open Twitter Setting from ACAccountStore (iOS 5.1 TWITTER)

in iOS 5.0 i was opening Twitter setting from my app by
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"prefs:root=TWITTER"]];
but , this features is removed in iOS 5.1 , hence i can not able to open twitter setting .
Now i am using
+ (void)makeRequestsWithURL: (NSURL *)url {
// Create an account store object.
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
// Create an account type that ensures Twitter accounts are retrieved.
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[self canTweetStatus];
// Request access from the user to use their Twitter accounts.
[accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
if(granted) {
// Get the list of Twitter accounts.
NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
// For the sake of brevity, we'll assume there is only one Twitter account present.
// You would ideally ask the user which account they want to tweet from, if there is more than one Twitter account present.
if ([accountsArray count] > 0) {
// Grab the initial Twitter account to tweet from.
ACAccount *twitterAccount = [accountsArray objectAtIndex:0];
// Create a request, which in this example, posts a tweet to the user's timeline.
// This example uses version 1 of the Twitter API.
// This may need to be changed to whichever version is currently appropriate.
TWRequest *postRequest = [[TWRequest alloc] initWithURL:url parameters:nil requestMethod:TWRequestMethodPOST];
// Set the account used to post the tweet.
[postRequest setAccount:twitterAccount];
// Perform the request created above and create a handler block to handle the response.
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSString *output = [NSString stringWithFormat:#"HTTP response status: %i", [urlResponse statusCode]];
iOS5Twitter *twitter5 = [[iOS5Twitter alloc] init];
[twitter5 performSelectorOnMainThread:#selector(displayText:) withObject:output waitUntilDone:NO];
[twitter5 release]; }];
}
}
}];
}
for making request, i am able to check wether i am loged in or not by the
if ([TWTweetComposeViewController canSendTweet])
but now i want : if i am not loged in it would be show an alert like shown in image and want to move to the twitter setting . is it possible ? or i have to manually go ti twitter setting ?
It is little tricky , i get by the removing the subviews in *TWTWeetComposeViewController*, so it shows only alert when user is not loged in and by the clicking on setting button , we can open Setting page in my app.
+ (void)setAlertForSettingPage :(id)delegate
{
// Set up the built-in twitter composition view controller.
TWTweetComposeViewController *tweetViewController = [[TWTweetComposeViewController alloc] init];
// Create the completion handler block.
[tweetViewController setCompletionHandler:^(TWTweetComposeViewControllerResult result) {
[delegate dismissModalViewControllerAnimated:YES];
}];
// Present the tweet composition view controller modally.
[delegate presentModalViewController:tweetViewController animated:YES];
//tweetViewController.view.hidden = YES;
for (UIView *view in tweetViewController.view.subviews){
[view removeFromSuperview];
}
}
here , deleate is your viewcontroller , if you are using this method inside your viewcontroller just use self instead of delegate.
iOS 6 uses SLComposeViewController instead of TWTweetComposeViewController, so now you have to do this if you want it to work on iOS 6 and iOS 5:
UIViewController *tweetComposer;
if([SLComposeViewController class] != nil)
{
tweetComposer = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[(SLComposeViewController *)tweetComposer setCompletionHandler:^(SLComposeViewControllerResult result)
{
// do whatever you want
}];
}
else
{
tweetComposer = [[TWTweetComposeViewController alloc] init];
[(TWTweetComposeViewController *)tweetComposer setCompletionHandler:^(TWTweetComposeViewControllerResult result)
{
// do whatever you want
}];
}
for (UIView *view in [[tweetComposer view] subviews])
[view removeFromSuperview];
[self presentViewController:tweetComposer animated:NO completion:nil];
Building upon Senior's and PJR's answers above, this is what worked for me.
Same as Senior's, except with a dimissViewController in the completion handler. For me this got around the problem that the empty view controller would stick around after I returned to the app from the settings. It would overlay my view controller and make it useless.
Brilliant solution, thanks Senior and PJR.
UIViewController *tweetComposer;
if([SLComposeViewController class] != nil)
{
tweetComposer = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[(SLComposeViewController *)tweetComposer setCompletionHandler:^(SLComposeViewControllerResult result)
{
[self dismissViewControllerAnimated:NO completion:nil];
}];
}
else
{
tweetComposer = [[TWTweetComposeViewController alloc] init];
[(TWTweetComposeViewController *)tweetComposer setCompletionHandler:^(TWTweetComposeViewControllerResult result)
{
[self dismissViewControllerAnimated:NO completion:nil];
}];
}
for (UIView *view in [[tweetComposer view] subviews])
[view removeFromSuperview];
[self presentViewController:tweetComposer animated:NO completion:nil];
To remove the post view,
instead using this code:
for (UIView *view in [[tweetComposer view] subviews])
[view removeFromSuperview];
use this:
tweetComposer.view.alpha = 0;
works both for twitter and facebook.

Game Center inviting friends programmatically

I'm facing difficulty inviting a friend to the match.
GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
request.minPlayers = 2;
request.maxPlayers = 2;
request.playersToInvite = [NSArray arrayWithObjects: #"G:1102359306",nil ];
// GKMatchmakerViewController *mv = [[GKMatchmakerViewController alloc] initWithMatchRequest:request];
// [self presentModalViewController:mv animated:YES];
[[GKMatchmaker sharedMatchmaker] findMatchForRequest:request withCompletionHandler:^(GKMatch *match, NSError *error) {
if (error) {
NSLog([error description]);
}
else if (match != nil) {NSLog(#"good match");
//self.chatMatch = match;
//self.chatMatch.delegate = self;
//[self chatReady];
}
else {
NSLog(#"other error");
}
}];
The problem is I never receive the invitation notification on second device logged to the account - G:1102359306.
When I use GKMatchmakerViewController (uncomment above 2 lines) and comment GKMatchmaker block I have automatically checked the good friend - G:1102359306 and when I invites him the notification with accept/decline is shown, that's how I know it's correct.
Do you see anything wrong with the code above? I want to use my own UI to handle the multiplayer mode. The strange problem is I also don't see in console any logs good match/other error, and the [error description] is only printed when I call the above code twice - it says that the previous req was canceled.
You cannot programmatically invite a specific set of players to a match. The findMatchForRequest:withCompletionHandler: documentation says this:
The match request’s playersToInvite property is ignored; to invite a specific set of players to the match, you must display a matchmaker view controller.
There is no public API that does what you want.