One login view, sign up or login - iphone

I want to be able to have just one login screen. The user will enter the username, email and password every time they login. I am having the problem where I sign up, logout and then try to login using the same credentials and I just get an error back saying that the username is already taken. How can I just log them in if they give me the correct credentials?
PFUser *user = [PFUser user];
user.email = emailEntry;
user.username = nickNameEntry;
user.password = passwordEntry;
[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error)
{
if (!error)
{
[MYAlertView showAlertWithTitle:#"Successful login"
message:#"success"
cancelButtonTitle:#"OK"];
}
else
{
NSString *errorString = [[error userInfo] objectForKey:#"error"];
[MyAlertView showAlertWithTitle:#"There was an error signing up."
message:errorString
cancelButtonTitle:#"OK"];
}
}];

If user needs to sign up (first time), you need to use –signUpInBackgroundWithBlock:, as you are doing.
However, if he is already signed up, I guess you should use +logInWithUsernameInBackground:password:block:.
I'm getting this infos from this page, however, I never used this SDK.
The easier way to do that is :
Having two buttons, that pushes different view controllers, one for signing up, the other for logging in
The same form, and two buttons, one which calls a methods that calls –signUpInBackgroundWithBlock:, and the other that calls +logInWithUsernameInBackground:password:block:.
With the second solution, the problem is that if you have the same form, you can't ask special informations (name, date of birth, etc.) on sign up.
EDIT :
You might want to have a look at :
PFSignUpViewControllerDelegate,
PFLoginViewControllerDelegate,
Parse API Documentation (where I've found the two links above).

Related

Getting error ACErrorPermissionDenied (error code 7) for Facebook when using Social Framework

I am fetching the user’s Facebook account ID and name using ACAccountStore.
When an alert comes up asking the user for permission (“XYZ would like to access your news feed and profile”) and the user taps on “Don’t Allow”, I get error code 7, i.e ACErrorPermissionDenied.
But after that, if I go to Settings and switch on the Facebook settings for my app and back in the app the alert pops up again and the user taps on “OK”, I’m still getting error code 7 (ACErrorPermissionDenied). So it’s enabled in Settings and I’ve tapped “OK” in the app, but it’s still giving me this error.
If the first time I allow access and after that switch access on or off from Settings, it gives me the proper error or success. This problem occurs only if the user taps “Don’t Allow” the first time. If he doesn’t allow it in the app when it asks, then he will not be able to allow FB access to my app.
I’ve tested this on iOS 6.0 and 6.0.1 using the following code:
NSMutableArray *acAccountArray = [[NSMutableArray alloc] init];
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType =
[accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
[accountStore
requestAccessToAccountsWithType:accountType
options:[self getOptionDictionary:ACAccountTypeIdentifierFacebook permission:[[NSArray alloc]initWithObjects:#"read_stream",#"user_about_me",#"email", nil]]
completion:^(BOOL granted, NSError *error) {
if(granted) {
// Doing what I want
} else {
NSLog(#"Error: %#", error);
}
}];
-(NSDictionary *)getOptionDictionary:(NSString * const)accountTypeIdentifier
permission:(NSArray*)permissionArray {
NSDictionary *options = nil;
if (accountTypeIdentifier == ACAccountTypeIdentifierFacebook) {
options = #{
#"ACFacebookAppIdKey" : #"dhksadhakjdhkshd",
#"ACFacebookPermissionsKey" : permissionArray,
#"ACFacebookAudienceKey" : ACFacebookAudienceFriends};
}
return options;}
Is your app still in "sandbox mode" on Facebook? If yes, it will be visible only to administrators and developers. If you're logged in to Facebook on your device with a non-administrator for your app, you might receive this error. Disabling the sandbox mode fixed the problem for me.
This is because you have removed your app in facebook, even i am facing same problem. If you try to login using any method other than iOS native login then it adds facebook app if it is not there or removed by the user in facebook settings but it is currently not happening if you try to login using iOS native login.
Please inform me if you come across ant solution for this issue and also is their a way i can remove my app being listed in iOS facebook settings in this case because if i remove and then user retries for login then it works correctly.

iOS: How to authenticate a user after login (for auto login)?

I'd like to use an auto-login function. So when the user opens the app, he gets delegated to a "login screen". When he logged in successfully he should be directed to his account. I call this the "account screen". Now when the user restarts the app, he should directly get directed to his account, without seeing the "login screen".
The login function already works fine in my project (username and password are saved in UserDefault), but every time I close the app, I have to login again. So my question is: How do auto login the user? Or better said: How do I check if the data (saved in UserDefault) is the same as in the database (MYSQL)?
For the first time when the user login, you save the user
credentials in iPhone's keychain.
When the app is opened again, you check whether user credentials are
present in keychain and if yes, you code should call the login
logic and do auto login and go to screen after login screen. If no,
then you should show login screen. You can do this logic in AppDelegates applicationDidFinishLaunching.
Whenever user clicks the logout button, remove user credentials from
keychain first, and go back to login controller.
Simply you add login credentials to keychain when user logs in and only remove it once user clicks the logout button. If user quits the app without logout then the credentials will still be in keychain and you can retrieve them when user returns to the app.
EDIT: I think I must add one more thing..If your login logic takes time (like you login using web request or something), put the login logic code in your Login ViewController rather than ApplicationDelegate, and use any Activity Indicator during auto login process.
EDIT : I edited the entire answer, replaced NSUserDefault with Keychain. This thread explains why.
While saving Username and Password, it is highly advised to save in Keychain rather than the NSUserDefaults. Refer this post for a better understanding.
To answer the question: if you want to auto-login with keychain data, use the free framework "SFHFKeychainUtils". It saves username, password and servicename in keychain. if you want to retrieve it, just save the username in NSUserDefaults and you can get the password with ease.
Here we go:
SiFi HiFi Framework: https://github.com/ldandersen/scifihifi-iphone/tree/master/security
SiFi Hifi Framework (ARC compatible): https://stackoverflow.com/a/10348964/1011125
How to use SFHFKeychainUtils: http://gorgando.com/blog/technology/iphone_development/simple-iphone-tutorial-password-management-using-the-keychain-by-using-sfhfkeychainutils
I used a combination of NSUserDefaults and SSKeychain. I used NSUserDefaults to store the username nad SSKeychain to store the password.
This is the code I used to save the credentials
NSString *user = self.username.text;
NSString *password = self.pass.text;
[SSKeychain setPassword:password forService:#"achat" account:user];
NSUserDefaults *dUser = [NSUserDefaults standardUserDefaults];
[dUser setObject:user forKey:#"user"];
[dUser synchronize];
This is the code I used to retrieve the credentials
NSUserDefaults *eUser = [NSUserDefaults standardUserDefaults];
NSString *savedUser = [eUser objectForKey:#"user"];
if (!savedUser) {
UIAlertView *uhoh = [[UIAlertView alloc] initWithTitle:#"Oops!" message:#"Please enter your username and password." delegate:self cancelButtonTitle:#"Okay" otherButtonTitles:nil, nil];
[uhoh show];
}
else {
NSString *savedPass = [SSKeychain passwordForService:#"achat" account:savedUser];
self.username.text = savedUser;
self.pass.text = savedPass;
}

Verify Twitter login from iPhone on the server side

Ok, so I've currently implemented Facebook login in my app the following way:
I use the official FB framework to login the user. When I login, I get a authentication token, which is sent to my server. I then do another verification of the user (e.g. get "me" from Facebook, using the auth-token), and then return 32 char random key, which is used to identify the user in subsequent API-calls (to my server). An example.
I'm trying to figure out how to do the same with twitter, but I can't understand how to get the oath token in iOS? I have the server-side part working in another app, but no token to verify...
Please advice – is this (the FB way) how I should be doing this, or how would you go about the verification process?
Sean Cook, engineer # Twitter has a github repo with a simple app that do exactly what you are trying to do, I'using this code in my app and it works like a charm.
There's a good article at dev.twitter.com describing exactly that. Basically you'll have to first get a special request token by setting the x_auth_mode parameter to the value reverse_aut and then get the proper access token by sending what you got in the first step as x_reverse_auth_parameters.
If you are going for an iOS 5 solution, you can import this into your header file
#import < Twitter/TWTweetComposeViewController.h >
and then in the .m file where you want to authenticate
if ([TWTweetComposeViewController canSendTweet])
{
TWTweetComposeViewController* twc = [[TWTweetComposeViewController alloc] init];
[twc addImage:uiImage
[self presentModalViewController:twc animated:YES];
twc.completionHandler = ^(TWTweetComposeViewControllerResult result)
{
if (result == TWTweetComposeViewControllerResultCancelled)
NSLog(#"Tweet compostion was canceled.");
else if (result == TWTweetComposeViewControllerResultDone)
NSLog(#"Tweet composition completed.");
// Dismiss it
[self dismissModalViewControllerAnimated:YES];
};
[twc release];
} else
{
//can't tweet
}
You can also add URLs, text and other sorts of information.
Edit: You can find a tutorial on adding the needed Library to your project here,
https://dev.twitter.com/docs/ios/how-add-twitter-framework-your-ios-project

TWTweetComposeViewController cansendtweet is true even when user revoked app in twitter

IOS 5.x using the TWTweetComposeViewController class. All is well even with the
if ( [TWTweetComposeViewController canSendTweet] )
UNLESS the user revokes access for the app on twitter, then the above is still true and when trying to send a tweet an error message appears with
Cannot be sent because the connection to Twitter failed.
This can be fixed if the user goes to SETTINGS / TWITTER / USERNAME
A message will come up
The user name of password is incorrect.
If the password is retyped, the app will be re authenticated on twitter and all is good again.
1) Is there anyway to capture the error under program control and then can inform the user to redo the settings?
2) How come the canSendTweet is true even when the app has been revoked?
1) No as it's a system level issue so not something you can control or manage directly from you apps sandbox
2) canSendTweet merely confirms that twitter is accessible on that device and that an account has been set up. It's not intended to identify if the user has given you access to their twitter account.
If you want to know if your app can access the users twitter you should use:
- (void)requestAccessToAccountsWithType:(ACAccountType *)accountType
withCompletionHandler:(ACAccountStoreRequestAccessCompletionHandler)handler;
located in the Accounts Framework
#import <Accounts/Accounts.h>
As an example this is one way of doing it:
accountStore = [[ACAccountStore alloc] init];
twitterAccountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:twitterAccountType
withCompletionHandler:^(BOOL granted, NSError *error) {
if (!granted) {
// Access denied by the user - do what you need to do
NSLog(#"Authenticated : User rejected access to his account.");
}
else {
// Access granted
// Do what you want here to send the tweet or whatever
}
}];
This issue can also be caused by having the time and date of your device set to a time other than the current time. Twitter will not allow you to authenticate from the Settings app in this case, and it also causes the TWTweetComposeViewController to fail with the "connection to Twitter failed" error message, even though canSendTweet returns true.

How to keep me logged in with facebook connect on iPhone?

Hey, I am using facebook connect sdk for iPhone, every time I start my app and click login, there would be a login screen asking me to input my name and password.
Is there any way to keep me logged in once I input my name and password, that's to say, I needn't to input my name and password again the next time I start my app?
According to the Platform Guidelines 1.3, you are not allowed to store a Facebook user's credentials. The best you can hope for is that your user checks the "Keep me logged in" option. She should be able to post without having to login any time soon, even if she restarts your app.
The following snippet works with the above scenario:
NSString *fbAPIKey = ...;
NSString *fbApplicationSecret = ...;
_session = [[FBSession sessionForApplication:fbAPIKey secret:fbApplicationSecret delegate:self] retain];
// checks whether session can be resumed - whether login is required
if (![_session resume]) {
FBLoginDialog *loginDialog = [[[FBLoginDialog alloc] initWithSession:_session] autorelease];
[loginDialog show];
}
Store the password (or the requisite hash of it) somewhere.
You need to use the keychain. Have a look to this article: http://log.scifihifi.com/post/55837387/simple-iphone-keychain-code