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.
Related
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...)
When linking my iOS with Facebook through Parse with the following code I get the following error:
+[PFDateFormatter sharedFormatter]: unrecognized selector sent to class 0x1001f31d0
Unsure of how to handle this, and this error executes when the following block is called:
[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
[_activityIndicator stopAnimating]; // Hide loading indicator
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!");
}
[self.navigationController popToRootViewControllerAnimated:YES];
}
}];
I fixed this by removing all the Parse and Facebook frameworks from my project, and then adding this to my podfile:
pod 'Facebook-iOS-SDK'
pod 'Parse'
pod 'ParseFacebookUtils'
and reinstalling my podfile. For whatever reason, something is missing from the Parse or Facebook frameworks downloaded from the website. The podfiles fixed the issue for me.
When I submit with empty textbox page is change and UIAlertView show after that, but I want to UIAlertView show in current page and page can not change (Stay on Signin Viewcontroller).
Thanks
- (IBAction)btnSignin:(id)sender {
[PFUser logInWithUsernameInBackground:_txtSigninUsername.text password:_txtSigninPassword.text block:^(PFUser *user, NSError *error) {
if (!error) {
NSLog(#"Login user!");
_txtSigninUsername.text = nil;
_txtSigninPassword.text = nil;
[self performSegueWithIdentifier:#"Signin" sender:self];
}
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"ooops!" message:#"Sorry we had a problem logging you in" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}];
}
My Storyboard :
You're performing the Segue with "Signin" identifier with the condition "error".
So when there's an error first your code performs the segue and then performs the error message.
Change "!error" with "user" and it should hopefully work. Let me know.
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.
I updated both Parse and Facebook iOS SDKs to the latest versions, and when I try to login using Facebook my app crashes, and from the debugger I can see that it is calling 3-4 methods in an endless loop.
My login code looks like this:
- (void)openSession
{
UIViewController *topViewController = self.window.rootViewController;
NSArray *permissions = [NSArray arrayWithObjects:#"user_likes", #"friends_likes", nil];
// Login PFUser using Facebook
[PFFacebookUtils logInWithPermissions:permissions block:^(PFUser *user, NSError *error) {
if (!user) {
if (!error) {
NSLog(#"Uh oh. The user cancelled the Facebook login.");
} else {
NSLog(#"Uh oh. An error occurred: %#", error);
}
} else if (user.isNew) {
NSLog(#"User with facebook signed up and logged in!");
if ([[topViewController presentedViewController] isKindOfClass:[PALoginViewController class]]) {
[topViewController dismissViewControllerAnimated:YES completion:nil];
}
} else {
NSLog(#"User with facebook logged in!");
if ([[topViewController presentedViewController] isKindOfClass:[PALoginViewController class]]) {
[topViewController dismissViewControllerAnimated:YES completion:nil];
}
}
}];
}
The error occurs when logInWithPermissions is called. It crashes into Xcode and Debugger is showing an awful lot of calls to FB login methods - thousands actually:
What could be wrong?
This issue was reported as a bug on Facebook: https://developers.facebook.com/bugs/188127071335876?browse=search_5176d24c698df3761093726
It has now been fixed, and I can confirm that logging in now works - even with Sandbox enabled.
Sandbox off, then it should works.