How to Get URL when application launch via facebook? - ios

I am sharing a facebook link using this method presentShareDialogWithLink in my application. When user tap on the post in facebook application then this opens my application automatically, at that time i want to get the url on what user tap in facebook application. How do i get that url and where i'll get that url?

You can get the URL by method handleOpenURL in AppDelegate
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
/* Do something with the url */
}

If you've set up a handler during the present* call, something like:
[FBDialogs presentShareDialogWithLink:url
handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
if(error) {
NSLog(#"Error: %#", error.description);
} else {
NSLog(#"Success!");
}
}];
Then in your AppDelegate, override the application:openURL:sourceApplication:annotation: method:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
BOOL urlWasHandled = [FBAppCall handleOpenURL:url
sourceApplication:sourceApplication
fallbackHandler:^(FBAppCall *call) {
NSLog(#"Unhandled deep link: %#", url);
}];
return urlWasHandled;
}
Then your handler should get a callback.
For more info, see https://developers.facebook.com/docs/ios/share-dialog/, in particular, https://developers.facebook.com/docs/ios/share-dialog/#handling-responses

Related

Facebook login: persisting across app launches

I'm logging in users with the following method, which works fine. However, each time the app relaunches, I need to run this method again to regain access.
The Facebook documentation seems to be very limited, and all the advice I can find (including on Stack Overflow) is related to the old Facebook SDK.
From what I can understand, a FBSDKAccessToken should be being cached when the user is first logged in. However, when I check [FBSDKAccessToken currentAccessToken] on subsequent launches, nothing is returned.
Any advice very welcome.
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login logInWithPublishPermissions:#[#"publish_actions"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
// Process error
} else if (result.isCancelled) {
// Handle cancellations
} else {
if ([result.grantedPermissions containsObject:#"publish_actions"]) {
// success
}
}
}];
Lol, searched for hours then came here 5 minutes too soon. The problem was that I needed to add the following in AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
return [[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
}
You ALSO want to add this in the following method:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
BOOL facebookCheck = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
if (!facebookCheck){
...
}
return true;
}
You probably wont need it now, but it doesn't hurt. :)

domain: #"com.facebook.sdk" - code 5 error using PFFacebookUtils

I'm trying to retrieve Facebook user friend list using this code:
FBRequest* friendsRequest = [FBRequest requestForMyFriends];
[friendsRequest startWithCompletionHandler: ^(FBRequestConnection *connection,
NSDictionary* result,
NSError *error) {
NSArray* friends = [result objectForKey:#"data"];
NSLog(#"Found: %i friends", friends.count);
for (NSDictionary<FBGraphUser>* friend in friends) {
NSLog(#"I have a friend named %# with id %#", friend.name, friend.id);
}
}];
The login as Facebook user has been implemented using parse "PFFacebookUtils"
From this tutorial https://parse.com/tutorials/login-and-signup-views
and here exactly what I've done:
1. configured my .plist file.
2. In the AppDelegate.m I've added these methods:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[Parse setApplicationId:#"your_application_id" clientKey:#"your_client_key"];
[PFFacebookUtils initializeFacebook];
}
// Facebook oauth callback
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [PFFacebookUtils handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [PFFacebookUtils handleOpenURL:url];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Handle an interruption during the authorization flow, such as the user clicking the home button.
[FBAppEvents activateApp];
[FBSession.activeSession handleDidBecomeActive];
}
3.In the logInViewController.m:
logInViewController.fields = PFLogInFieldsLogInButton | PFLogInFieldsUsernameAndPassword | PFLogInFieldsFacebook | PFLogInFieldsSignUpButton | PFLogInFieldsPasswordForgotten;
logInViewController.facebookPermissions = #[ #"public_profile",#"email",#"user_friends"];
I can Login successfully, but when I retrieve the user friend I get this error: (Note: I'm using test users and created a friend list for them)
Please I would appreciate any help.

FBSDKLoginManager logInWithPublishPermissions always returns isCancelled=YES

I am having trouble figuring out how to log a user into my app. [FBSDKAccessToken currentAccessToken] is nil, so I am calling:
[[[FBSDKLoginManager alloc] init] logInWithPublishPermissions:#[#"publish_actions"] handler:…];
as per the included sample project. This switches to the Facebook app, but the message says "You have already authorized App Name.". I click OK and it goes back into the app, but grantedPermissions and declinedPermissions are both nil on the result, and isCancelled is YES. [FBSDKAccessToken currentAccessToken] is still nil.
I can't figure out how I'm supposed to get currentAccessToken to be filled in. It seems to me the call to logInWithPublishPermissions should do that, but it isn't.
You should try adding in your AppDelegate didFinishLaunchingWithOptions :
return [[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
This would get u [FBSDKAccessToken currentAccessToken] when user is logged in.
and
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
If this method is not present into AppDelegate then it results into cancelled state.
Refer to : https://developers.facebook.com/docs/ios/getting-started#startcoding
This can happen when your Facebook App doesn't have "publish_actions" permission, or you're not using a test user.
On Facebook, go to manage your app, then make sure that the Facebook user you're using is defined under "Roles" as an admin or tester.
If it's not a test user or admin - Facebook will require "publish_actions" permission to be reviewed and approved before allowing your app to use it, until then you'll receive a "isCancelled=YES" result.
After testing your app with this permission, it is possible to submit this permission for review, you'll need to upload a binary that demonstrates usage of this permission with exact details on how to use it. After it's approved, you'll be able to use it with non-test Facebook users.
Since FBSDKLoginKit 4.6.0, the logInWithReadPermissions and logInWithPublishPermissions methods of FBSDKLoginManager seems to have additional fromViewController argument and use that to present modals.
I was calling logInWithPublishPermissions inside the callback of logInWithReadPermissions, which at that point the modal is not fully dismissed yet. (I know it's a bad practice to ask permission when it's not needed, but in my case this seems to be the right place to do.) This cause it to fail with isCancelled equals to YES. I added some delay and wait for the modal to be fully dismissed fixed the problem.
I had the same problem when I landed here, turns out I was only using the deprecated application openURL method because i was using google sign in too. To support iOS 8 and before you have to implement both the current and the deprecated method:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return GIDSignIn.sharedInstance().handle(url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String!, annotation: options[UIApplicationOpenURLOptionsKey.annotation]) || FBSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String, annotation: options[UIApplicationOpenURLOptionsKey.annotation])
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return GIDSignIn.sharedInstance().handle(url, sourceApplication: sourceApplication, annotation: annotation) || FBSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
}
The deprecated is the second.
Note: The FBSDK method is added after the google one with an or "||" operator but the order doesn't matter and if you wanna only use facebook method just erase the method and the or operator.
Note 2: As swift 3 still stabilizing the method name can change I suggest you always use the auto complete from XCode when overriding and implementing a delegate's method.
Hope this Helps o/
FBSDKLoginManagerLoginResult.isCancelled is unexpectedly YES:
The SDK will report a cancellation if the user explicitly taps a cancel button in the login dialogs, or if they manually app switch back to your app (known as an implicit cancellation). You should make sure you are not initiating a login flow as part of your app delegate's lifecycle (such as starting a login inside application:openURL:sourceApplication:annotation:) as that will mimic an implicit cancellation. If you must, dispatch the login initiation later to the main queue so that the app delegate's lifecycle completes first.
This method works in iOS 9
// Facebook Login Completion delegate
- (void)loginButton:(FBSDKLoginButton *)loginButton didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error
{
if (result){
NSLog(#"%#",result);
NSLog(#"%#",result.grantedPermissions);
[self getFacebookData:result];
}
}
- (void)getFacebookData:(FBSDKLoginManagerLoginResult *)result{
if (![result.grantedPermissions containsObject:#"email"])
{
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
login.loginBehavior = FBSDKLoginBehaviorWeb;
[login logInWithReadPermissions:#[#"email"] fromViewController:self handler:^(FBSDKLoginManagerLoginResult *result, NSError *error)
{
if (error)
{
// Process error
}
else if (result.isCancelled)
{
// Handle cancellations
}
else
{
if ([result.grantedPermissions containsObject:#"email"])
{
NSLog(#"result is:%#",result);
if ([FBSDKAccessToken currentAccessToken]) {
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:#{#"fields": #"first_name, last_name, email, id"}]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(#"fetched user:%#", result);
[self registerWithFacebook:result];
}else{
NSLog(#"%#",error);
}
}];
}
}
}
}];
}else{
if ([FBSDKAccessToken currentAccessToken]) {
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:#{#"fields": #"first_name, last_name, email, id"}]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(#"fetched user:%#", result);
[self registerWithFacebook:result];
}else{
NSLog(#"%#",error);
}
}];
}
}
}
NOTE : Use FBSDKLoginBehaviorWeb instead of FBSDKLoginBehaviorBrowser. This will surely work
Also, make sure you are not calling for FBSDKAccessToken.currentAccessToken INSIDE your didFinishLaunchingWithOptions method. The setup in didFinishLaunchingWithOptions needs to complete so the token can initialize before you try to log in to Facebook.
I also faced the same issue and i spent almost 2 hours to resolve the issue. What i did is
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
**[login logOut];** // adding this single line fixed my issue
[login logInWithReadPermissions: #[#"public_profile"] fromViewController:self handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
NSLog(#"Process error");
} else if (result.isCancelled) {
NSLog(#"Cancelled");
} else {
NSLog(#"Logged in");
[self GetData];
}
}] // I called this logout function
and the issue was fixed
i was using both google and Facebook login so i had to implement my openURL method like this, iOS 9+
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if ([[url absoluteString] containsString:#"YOURFBID"]) {
return [[FBSDKApplicationDelegate sharedInstance] application:app openURL:url options:options];
} else {
return [[GIDSignIn sharedInstance] handleURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}
return NO;
}
// you can perform further any operations using the access token
- (void)GetData {
if ([FBSDKAccessToken currentAccessToken]) {
NSDictionary *AccessToken = [FBSDKAccessToken currentAccessToken];
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:#{#"fields": #"id, name, first_name, picture.type(large) ,last_name"}]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
//NSLog(#"fetched user:%#", result);
//NSDictionary *Result = result;
NSDictionary *params = [NSMutableDictionary dictionaryWithObject:[AccessToken tokenString] forKey:#"access_token"];
} else {
[self showAlertController:#"Error" message:error.localizedDescription];
}
}];
} }
(BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
options:options];
}
// **Still need this for iOS8**
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(nullable NSString *)sourceApplication
annotation:(nonnull id)annotation
{
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
1.check already added
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
2.check already added
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(nullable NSString *)sourceApplication
annotation:(nonnull id)annotation
{
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
3.
write this statement [FBSDKProfile enableUpdatesOnAccessTokenChange:YES];
before
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
4.call logInWithReadPermissions method in dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{}
call this methord,
FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init];
[loginManager logInWithReadPermissions:#[#"user_friends"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
code
}];

Facebook and twitter login with Parse iOS only works once

I'm using the twitter and Facebook login in the Parse SDK. For every app launch I can log into each service once, but when I logout using [PFUser logOut] I am unable to log in again. The [PFFacebookUtils logInWithPermissions] block never gets called either with a user or an error.
My (Facebook) Login Code is:
- (IBAction)facebookLogin:(id)sender {
NSArray *permissionsArray = #[ #"user_about_me" ];
// 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!");
}
}
}];
}
My logout code is:
- (IBAction)loginButton:(id)sender {
if([PFUser currentUser]) {
[PFUser logOut];
NSLog(#"User is %#", [PFUser currentUser]);
NSLog(#"Facebook session is %#", [PFFacebookUtils session]);
NSLog(#"Facebook session is %#", FBSession.activeSession.observationInfo);
} else {
[self performSegueWithIdentifier:#"loginScreenSegue" sender:self];
}
}
Everything logs (null).
I assumed that as the behaviour was the same with Twitter, that it might be related to the OAuth related methods in my AppDelegate:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [FBAppCall handleOpenURL:url
sourceApplication:sourceApplication
withSession:[PFFacebookUtils session]];
}
- (BOOL) application:(UIApplication *)application
handleOpenURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [FBAppCall handleOpenURL:url
sourceApplication:sourceApplication
withSession:[PFFacebookUtils session]];
}
But have done a lot of research and don't seem to be missing anything...
I also have these in the AppDelegate:
- (void)applicationWillResignActive:(UIApplication *)application {
[[PFFacebookUtils session] close];
}
- (void)applicationWillTerminate:(UIApplication *)application {
[[PFFacebookUtils session] close];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBAppCall handleDidBecomeActiveWithSession:[PFFacebookUtils session]];
}
Any help would be very gratefully received!
In you logout method, you should clear the Facebook session token as well like below:
[[FBSession activeSession]closeAndClearTokenInformation];
This will clear the active Facebook session's token.
OK, I finally solved this. The problem was that in my app setup on twitter, the permissions were set to 'Read only', not 'Read and Write'.
Changing this setting solved the problem with both facebook and twitter.

Google+ Sign-In button customization

How to customize Google+ Sign-In button ios ?
is there a way to go directly for sign in with out clicking Google+ Sign-In button ?
Yes, there is way to directly sign in Google+.
In AppDelegate, add this,
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
return [GPPURLHandler handleURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
And your login view controller this code parts should be added.
- (void)loginWithGooglePlus
{
[GPPSignIn sharedInstance].clientID = kClientID;
[GPPSignIn sharedInstance].scopes= [NSArray arrayWithObjects:kGTLAuthScopePlusLogin, nil];
[GPPSignIn sharedInstance].shouldFetchGoogleUserID=YES;
[GPPSignIn sharedInstance].shouldFetchGoogleUserEmail=YES;
[GPPSignIn sharedInstance].delegate=self;
[[GPPSignIn sharedInstance] authenticate];
}
- (void)finishedWithAuth:(GTMOAuth2Authentication *)auth
error:(NSError *)error
{
if (!error)
{
NSLog(#"Google+ login successful");
}
else
{
NSLog(#"Error: %#", error);
}
}
kClientID is your app client id taken from google your registered apps. Of course you need to set the delegate ( GPPSignInDelegate ).

Resources