I'm utilizing the facebook log in from Azure SDK, I'm utilizing the following code in a button:
-(void)fblogin
{
[_azureService.client loginWithProvider:#"facebook" urlScheme:#"dribel" controller:self animated:YES completion:^(MSUser * _Nullable user, NSError * _Nullable error)
{
if (error)
{
NSLog(#"Login failed with error: %#, %#", error, [error userInfo]);
}
else
{
_azureService.client.currentUser = user;
NSLog(#"User logged in: %#", user.userId);
[self fblogin];
}
}];
}
A webview like this, opens and does all the facebook log in process...
And when it ends, it calls the following method in the app delegate and since it's true, it resumes the log in flow...
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
if ([[url.scheme lowercaseString] isEqualToString:#"dribel"])
{
// Resume login flow
return [self.azureService.client resumeWithURL:url];
}
else {
return NO;
}
}
but the webview is supposed to be dismissed and after being dismissed the code is supposed to land on the else statement of the first piece of code, but it's not doing anything. I have to press done and lands on the if true statement and it says I canceled it. Does anyone has an idea of what could be wrong?
We have set up the external url in the azure portal to redirect to the correct appname:// so that's why it we get true in the app delegate. But what else is missing?
Related
I have a very strange behaviours with one user when trying to post. (ipad 2, ios8.3, parse 1.7.4)
(from my device, all ok).
bGranted_publish_actions = always false
bGranted_user_photos = always false
When I call linkUserInBackground, i can see the facebook app opening(very long), and then close directly(not event the time to see the permission screen), and my ios app reopen.
error=nil
succeeded= no
Any idea?
-(void)postShareToFacebookWithDescription:(NSString *)description andBlock:(void (^)(NSError *))completionBlock{
NSLog(#"ℹ️--[%s:%d]",__PRETTY_FUNCTION__,__LINE__);
bool bGranted_publish_actions=[[FBSDKAccessToken currentAccessToken] hasGranted:#"publish_actions"];
bool bGranted_user_photos=[[FBSDKAccessToken currentAccessToken] hasGranted:#"user_photos"];
if (!bGranted_user_photos || !bGranted_publish_actions ){
//withPublishPermissions:#[#"publish_actions", #"user_photos"
[PFFacebookUtils linkUserInBackground:[PFUser currentUser] withPublishPermissions:#[#"publish_actions"] block:^(BOOL succeeded, NSError *error) {
if (succeeded) {
NSLog(#"User now has read and publish permissions!");
[self postDataWithPhoto:nil];
} else {
if (completionBlock) {
completionBlock(error);
}
}
}];
} else {
NSLog(#"Got Facebook publish permissions and about to share");
[self postDataWithPhoto:nil];
}
}
I got my answer:
FBSDKLoginManager logInWithPublishPermissions always returns isCancelled=YES
"This can happen when your Facebook App doesn't have "publish_actions"
permission, or you're not using a test user."
I've got an app that is nearing completion, and we've decided to allow users to login using Facebook.
At some point in the past, this feature was working, and now it simply hangs.
I've included the latest Parse SDK (1.6.1) and the latest Facebook SDK (3.21.1).
I think I've set up the app correctly. Here are the calls that I am making:
// AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[Parse setApplicationId:#"appId" clientKey:#"clientKey"];
[PFFacebookUtils initializeFacebook];
return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBAppCall handleDidBecomeActiveWithSession:[PFFacebookUtils session]];
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
[[PFFacebookUtils session] close];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [FBAppCall handleOpenURL:url sourceApplication:sourceApplication withSession:[PFFacebookUtils session]];
}
// Login View Controller
- (void)loginWithFacebok {
[PFFacebookUtils logInWithPermissions:#[#"public_profile", #"email"] block:^(PFUser *user, NSError *error) {
if (error != nil) {
// Error handling here.
} else {
if (user == nil) {
// Something odd happened; error handling here.
} else {
// A further Facebook method...
[self authorizeFacebookPublish];
}
}
}];
}
Basically, although it was working at a previous time, it's non-functional now in the sense that block is never called. I do get the "app jump" to the Facebook app/web page (can't remember which now, and it "jumps" there and back too fast for me to tell, since I've approved this in the past). What's interesting is that if I force-quit the app (the app is basically in a "hung" state) and re-launch the app, the app loads and the user is logged in.
This is a fairly important point, but I can't find anyone else having this particular issue.
I saw this question, but we're not using Twitter.
This question isn't related to Parse.
EDIT:
I was working through this more and kept being slightly confused by breakpoint catching. For instance, in my -loginWithFacebook method, I placed a breakpoint on the first line (the loginWithPermissions call) and the first line of the returned block (if (error != nil) {..., and the first breakpoint would be hit twice each time. I finally thought to try something new, so I added an NSLog line above the first line and moved the first breakpoint there. Subsequent runs had the first breakpoint (now on NSLog) hit once and then the first line of the block hit second. Therefore, I was able to determine that my problem is not, in fact, in my loginWithFacebook method. It's in my authorizeFacebookPublish method. Here's that code:
- (void)authorizeFacebookPublish {
NSLog(#"authorizing for Facebook publish..."); // First breakpoint here...
[PFFacebookUtils reauthorizeUser:[PFUser currentUser]
withPublishPermissions:#[#"publish_actions"]
audience:FBSessionDefaultAudienceFriends
block:^(BOOL succeeded, NSError *error) {
if (error != nil) { // Second breakpoint here...
// Error handling...
} else {
if (succeeded == YES) {
// Our app now has publishing permissions for the user
[PFUser currentUser][#"canPublishToFacebook"] = #(YES);
} else {
// Our app was refused publishing permissions
[PFUser currentUser][#"canPublishToFacebook"] = #(NO);
[[PFUser currentUser] saveInBackground];
}
// Log in was successful, so do other stuff....
}
}];
}
I'm now seeing the issue that's also listed here, which is that some breakpoint (apparently named "breakpoint 2.1" is being hit each time). This guy, however, isn't reporting the same problem I'm seeing, which is that the return block is never firing. Therefore, I am concluding that there is some problem in the authorization (or maybe re-authorization) block.
As I mentioned above, this code was working at some point in the past. Is it possible that "re-authorizing" causes an error? Is there a way for me to check whether the user has already authorized my app in the past and skip the authorization process (since it's already been done)? If that IS the problem, what's the correct procedure for logging a user back in after a logout (using Facebook)?
First of all, why are you calling [[PFFacebookUtils session] close] in your applicationWillTerminate: callback ?
The Facebook session uses a token stored on disk, which means the session is kept open across app launches and has no reason to be closed when the app is terminated.
If you want to log the user out, you should call [PFUser logOut] and then [[PFFacebookUtils session] close] or better [[PFFacebookUtils session] closeAndClearTokenInformation] (but I'm not sure this is even necessary).
If you don't want to log the user out (which I think is better), just don't call anything.
Secondly, I too have had a lot of problems in the past with [PFFacebookUtils reauthorizeUser: ...]. One workaround that I found was to use the Facebook API directly :
[[PFFacebookUtils session] requestNewPublishPermissions:[NSArray arrayWithObject:#"publish_actions"] defaultAudience:FBSessionDefaultAudienceFriends completionHandler:^(FBSession *session, NSError *error) {
if (!error) {
if ([[PFFacebookUtils session].permissions indexOfObject:#"publish_actions"] == NSNotFound) {
// Permission not granted, tell the user we will not share to Facebook
NSLog(#"Permission not granted, we will not share to Facebook.");
} else {
// Permission granted.
}
} else {
// An error occurred. See: https://developers.facebook.com/docs/ios/errors
NSLog(#"Error : Requesting \"publish_actions\" permission failed with error : %#", error);
}
}];
It does exactly the same thing but seems to be working better.
Also, concerning your multiple breakpoint issues, if you put a breakpoint at the beginning of a block, it will usually stop twice : when the block is created and when the block is called. The block is only called once though, you can check that with an NSLog(...) call as you did.
I'm using facebook-ios-sdk-3.10, Using this SDK I'll login and fetch user details from FB Its working fine for me.
This is the code I'm uisng
- (IBAction)fbLogin_click:(id)sender
{
if (AppDelegate.fbsession.state != FBSessionStateCreated) {
// Create a new, logged out session.
NSArray *permissions = [NSArray arrayWithObjects:#"offline_access", #"email", #"publish_stream", #"read_stream",#"read_friendlists",#"manage_friendlists",#"friends_about_me",#"publish_actions", nil];
// create a session object, with defaults accross the board, except that we provide a custom
// instance of FBSessionTokenCachingStrategy
AppDelegate.fbsession = [[FBSession alloc] initWithAppID:nil
permissions:permissions
urlSchemeSuffix:nil
tokenCacheStrategy:nil];
}
FBSessionLoginBehavior behavior = FBSessionLoginBehaviorForcingWebView;
if (AppDelegate.fbsession.state != FBSessionStateCreatedTokenLoaded) {
// even though we had a cached token, we need to login to make the session usable
[AppDelegate.fbsession openWithBehavior:behavior completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
if (error)
{
NSLog(#"Error");
}
[self GetFBUserDetails];
}];
}
}
-(void) GetFBUserDetails
{
if (AppDelegate.fbsession.isOpen)
{
[HUD show:YES];
// fetch profile info such as name, id, etc. for the open session
FBRequest *me = [[FBRequest alloc] initWithSession:AppDelegate.fbsession graphPath:#"me"];
self.pendingRequest= me;
[me startWithCompletionHandler:^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *user,
NSError *error) {
// because we have a cached copy of the connection, we can check
// to see if this is the connection we care about; a prematurely
// cancelled connection will short-circuit here
if (me != self.pendingRequest) {
return;
}
self.pendingRequest = nil;
// self.pendingLoginForSlot = -1;
// we interpret an error in the initial fetch as a reason to
// fail the user switch, and leave the application without an
// active user (similar to initial state)
if (error) {
return;
}
[AppDelegate.fbsession closeAndClearTokenInformation];
[FBSession.activeSession close];
[FBSession.activeSession closeAndClearTokenInformation];
FBSession.activeSession=nil;
[self FacebookCustomerRegister:user];
}];
}
}
In such case some user create Facebook account and not very his account through email, when he try to login via my app it shows empty screen after click login button, there is no action further. how can I notify the user "You not yet verify your FB account" and it not return to my app. how can I fetch the response from there ? refer screen short.
I give login details, after click login button that blank screen will appear after this no response from SDK and not return to App.
can anyone help me for this ?
add this code to your AppDelegate
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
return [FBSession.activeSession handleOpenURL:url];
}
read more :https://developers.facebook.com/docs/ios/login-tutorial
I'm having trouble with the authentication part of the SoundCloud API. I am following the tutorial located here: http://developer.soundcloud.com/docs/api/ios-quickstart#authentication
I follow their code as written and it runs/compiles, but doesn't authenticate. When requesting a login from the following bit of code:
(IBAction) login:(id) sender
{
SCLoginViewControllerCompletionHandler handler = ^(NSError *error) {
if (SC_CANCELED(error)) {
NSLog(#"Canceled!");
} else if (error) {
NSLog(#"Error: %#", [error localizedDescription]);
} else {
NSLog(#"Done!");
}
};
[SCSoundCloud requestAccessWithPreparedAuthorizationURLHandler:^(NSURL *preparedURL) {
SCLoginViewController *loginViewController;
loginViewController = [SCLoginViewController
loginViewControllerWithPreparedURL:preparedURL
completionHandler:handler];
[self presentModalViewController:loginViewController animated:YES];
}];
It returns with a console error of:
2013-12-26 16:11:23.902 SampleProject[14748:4717] -[NXOAuth2PostBodyStream open]
Stream has been reopened after close
2013-12-26 16:11:24.198 SampleProject[14748:70b] Done!
And then subsequent calls to [SCSoundCloud account] return nil.
During use of the app, the login views appear and I appear to have logged in successfully, but no account appears to have been saved / registered. Any advice?
Also, my initialization function with clientID / section / redirectURL are as directed in the tutorial and the app is registered.
Have a look at NXOAuth2Account.m where the user's client ID, client secret etc. are used to create the oauthClient.
You can also find in this file a method called description that should return everything you need to re-authenticate the user should you want to do so:
- (NSString *)description;
{
return [NSString stringWithFormat:#"<NXOAuth2Account identifier:'%#' accountType:'%#' accessToken:%# userData:%#>", self.identifier, self.accountType, self.accessToken, self.userData];
}
I am using FB sdk for iOS (3.9).
So, following the tutorial from Facebook Developers, I am having in my AppDelegate the following check.
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
// To-do, show logged in view
NSLog(#"There is token for session");
} else {
// No, display the login page.
NSLog(#"There isn't token for session");
}
When I relaunch my app, after I have requested permissions in the first launch, I can see that there is a token, as expected.
But in my next sreens, If I call this:
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
if (FBSession.activeSession.isOpen) {
NSLog(#"FBSession is open. Will populate user details.");
[self populateUserDetails];
} else {
NSLog(#"Session is not open");
}
Then I see the Session is not open.
in order to make it work I have to change my delegate function to that:
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
// To-do, show logged in view
NSLog(#"There is token for session");
[self openSession]
} else {
// No, display the login page.
NSLog(#"There isn't token for session");
}
So, do I have to explicitly open the session every time? I thought that the session does not expire once you exit your app.
Can you explain in more details because I cannot get it from the facebook developers site.