web-dev-qa-db-ja.com

FBSDKLoginManager logInWithPublishPermissionsは常にisCancelled = YESを返します

ユーザーをアプリにログインする方法がわかりません。 [FBSDKAccessToken currentAccessToken]はnilなので、私は次のように呼び出しています:

[[[FBSDKLoginManager alloc] init] logInWithPublishPermissions:@[@"publish_actions"] handler:…];

含まれているサンプルプロジェクトごと。これによりFacebookアプリに切り替わりますが、メッセージには「既に承認済みですアプリ名。」と表示されます。 [OK]をクリックすると、アプリに戻りますが、grantedPermissionsdeclinedPermissionsは両方とも結果でnilであり、isCancelledYESです。 [FBSDKAccessToken currentAccessToken]は、まだnilです。

currentAccessTokenをどのように埋めるかを理解することはできません。logInWithPublishPermissionsへの呼び出しがそれを行う必要があるようですが、そうではありません。

26
devios1

AppDelegate didFinishLaunchingWithOptionsに追加してみてください:

return [[FBSDKApplicationDelegate sharedInstance] application:application
                                    didFinishLaunchingWithOptions:launchOptions];

これでu [FBSDKAccessToken currentAccessToken]ユーザーがログインしているとき。

そして

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    return [[FBSDKApplicationDelegate sharedInstance] application:application
                                                          openURL:url
                                                sourceApplication:sourceApplication
                                                       annotation:annotation];
}

このメソッドがAppDelegateに存在しない場合、キャンセル状態になります。

参照: https://developers.facebook.com/docs/ios/getting-started#startcoding

50
Dheeraj Singh

これは、Facebookアプリに「publish_actions」権限がない場合、またはテストユーザーを使用していないの場合に発生する可能性があります。

Facebookでアプリを管理し、使用しているFacebookユーザーが「ロール」の下で管理者またはテスターとして定義されていることを確認します。

テストユーザーでも管理者でもない場合-Facebookでは、アプリが使用を許可する前に、「isCancelled = YES」という結果を受け取るまで、「publish_actions」権限を確認および承認する必要があります。

この許可を使用してアプリをテストした後、レビューのためにこの許可を送信することができます。この許可の使用方法を示すバイナリをアップロードする必要があります。承認されると、テスト以外のFacebookユーザーと使用できるようになります。

29
Kof

私がここに着いたときに同じ問題がありましたが、私もGoogleサインインを使用していたため、非推奨のアプリケーションopenURLメソッドのみを使用していたことがわかりました。 iOS 8をサポートする前に、現在のメソッドと非推奨のメソッドの両方を実装する必要があります。

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)
}

非推奨は2番目です。

注:FBSDKメソッドは、または「||」でgoogleの後に追加されます演算子ですが、順序は関係ありません。facebookメソッドのみを使用する場合は、メソッドとor演算子を消去します。

注2:As Swift 3メソッド名の安定化は変更される可能性があります。デリゲートのメソッドをオーバーライドおよび実装する場合は、常にXCodeのオートコンプリートを使用することをお勧めします。

これがo /

FBSDKLoginKit 4.6.0以降、FBSDKLoginManagerのlogInWithReadPermissionsおよびlogInWithPublishPermissionsメソッドには追加のfromViewController引数があり、それを使用してモーダルを表示するようです。

logInWithPublishPermissionsのコールバック内でlogInWithReadPermissionsを呼び出していましたが、その時点でモーダルはまだ完全に却下されていません。 (必要のないときに許可を求めるのは悪い習慣だと思いますが、私の場合はこれが適切な場所のようです。)これにより、isCancelledがYESになって失敗します。いくつかの遅延を追加し、モーダルが完全に却下されるのを待って問題を修正しました。

2
Hlung

この方法は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 [〜#〜]FBSDKLoginBehaviorBrowserの代わりにFBSDKLoginBehaviorWebを使用します。これは確かに動作します

1
jaya raj
(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];
}
0
Cong Wang

1.既に追加されているチェック

[[FBSDKApplicationDelegate sharedInstance] application:application
                             didFinishLaunchingWithOptions:launchOptions];

2.既に追加されているチェック

- (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.このステートメントを書く[FBSDKProfile enableUpdatesOnAccessTokenChange:YES];

[[FBSDKApplicationDelegate sharedInstance] application:application
                         didFinishLaunchingWithOptions:launchOptions];

4.dispatch_after(dispatch_time(DISPATCH_TIME_NOW、(int64_t)(1 * NSEC_PER_SEC)))、dispatch_get_main_queue()、^ {}でlogInWithReadPermissionsメソッドを呼び出します

0
Yong Piao

FBSDKLoginManagerLoginResult.isCancelledは予期せずYES

ユーザーがログインダイアログでキャンセルボタンを明示的にタップした場合、またはアプリを手動でアプリに切り替えた場合(暗黙的なキャンセルと呼ばれる)、SDKはキャンセルを報告します。アプリdelegateのライフサイクルの一部としてログインフローを開始していないことを確認する必要があります(application:openURL:sourceApplication:annotation:)それは暗黙的なキャンセルを模倣します。必要に応じて、アプリのデリゲートのライフサイクルが最初に完了するように、後でログイン開始をメインキューにディスパッチします。

0
Salman Ghumsani

また、didFinishLaunchingWithOptionsメソッド内でFBSDKAccessToken.currentAccessTokenを呼び出していないことを確認してください。 Facebookにログインする前にトークンを初期化できるように、didFinishLaunchingWithOptionsのセットアップを完了する必要があります。

0
gravy

私も同じ問題に直面し、問題を解決するためにほぼ2時間を費やしました。私がしたことは

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 

そして問題は修正されました

私はGoogleとFacebookの両方のログインを使用していたので、このようなopenURLメソッドを実装する必要がありました、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;
}

//アクセストークンを使用してさらに操作を実行できます

- (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];
             }
         }];
    } }
0
Adeel Ahmed