このチュートリアルFBConnect
に従って、iPhone アプリケーションに SSOを実装しました。これまでに 2 台の電話でテストしましたが、そのうちの 1 台では問題なく機能を使用できましたが、もう 1 台の電話では Facebook アプリを開いてすぐに閉じただけでした。有効なセッションを確立できますが、そのうちの 1 つでダイアログが閉じているように見えます。
何が問題なのですか?どんな助けでも大歓迎です。
3 に答える
あなたの問題は、クライアント側 (アプリ) またはサーバー側 (FB アプリの構成) のいずれかに適切な構成がないことだと思います。次の両方を確認してください。
クライアント アプリ:
正しい FBAppId を URL ハンドラーとして Info.plist に導入したことを確認してください。Facebook はこのハンドラーを使用してアプリを開こうとします。それが機能しない場合、アプリは開かれません。
(XXXXXXXXXX
を FB appID に置き換えます)
アプリ (appDelegate 内) が上で追加したカスタム URL を処理するかどうかを確認します。
- (BOOL)handleOpenURL:(NSURL*)url
{
NSString* scheme = [url scheme];
NSString* prefix = [NSString stringWithFormat:@"fb%@", facebookAppId];
if ([scheme hasPrefix:prefix]) {
return [fb handleOpenURL:url];
}
return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [self handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
return [self handleOpenURL:url];
}
サーバ側
FB 設定ページで bundleId が正しく設定されていることを確認してください。https://developers.facebook.com/appsでこれを確認し、アプリを選択してから、エディション パネルで確認できます。
両方が正しく構成されていれば、どのような場合でも動作するはずです (FBapp がインストールされている場合でも、Safari ベースの場合でも)。
私はこれを 3.0 SDK で確認しました。これが発生する理由は、Facebook がアクセス トークンをキャッシュする方法が原因です。アクセス トークンは、アプリとデバイス上の facebook アプリの両方にキャッシュされます (少なくとも概念的には)。
デバイスでアプリを初めて起動した場合、facebook はアプリにキャッシュされた有効なアクセス トークンを持っていません。ただし、アプリの facebook アプリに有効なアクセス トークンがまだある場合があります。Facebook 側で見つかった場合は、ユーザーに再度尋ねる必要がないため、ダイアログが表示されてから消え、アクセス トークンが返されます。その後、アクセス トークンがアプリにキャッシュされます。
アプリを (削除せずに) 再起動すると、アクセス トークンがアプリにキャッシュされるため、ログイン ダイアログはまったく表示されません。デバイスでアプリを削除して再度ログインすると、Facebook がその側でキャッシュされたトークンを見つけることができる限り、同じ動作が見られます。
この問題の解決策を見つけました。サンプルコードは次のとおりです。
if (![FBSession activeSession].isOpen) {
FBSession *session = [[FBSession alloc] initWithAppID:nil permissions:permissions defaultAudience:FBSessionDefaultAudienceEveryone urlSchemeSuffix:nil tokenCacheStrategy:nil];
[FBSession setActiveSession:session];
[session openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
// NOTE openActiveSessionWithPermissions causes the facebook app to hang with a blank dialog if my app is installed, authed, and then reinstalled. openWithBehavior
// does not. I think it has something to do with the FBSession activeSession.
// [FBSession openActiveSessionWithPermissions:self.permissions allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
switch (status) {
case FBSessionStateOpen:
[self getFacebookUser];
break;
case FBSessionStateClosed:
[self fbSessionClosed];
break;
case FBSessionStateCreated:
[self fbSessionCreated];
break;
case FBSessionStateCreatedOpening:
[self fbSessionOpening];
break;
case FBSessionStateClosedLoginFailed:
[self fbSessionClosedLoginFailed];
break;
case FBSessionStateOpenTokenExtended:
[self fbSessionOpenTokenExtended];
break;
case FBSessionStateCreatedTokenLoaded:
[self fbSessionCreatedTokenLoaded];
break;
}
}];
}
}
openActiveSessionWithPermissions は問題を引き起こしますが、openWithBehavior は問題を引き起こしません。openActiveSession は同じ openWithBehavior 呼び出しを行いますが、アクティブ セッションを設定するタイミングが異なり、動作しないと思います。openWithBehavior を呼び出す前にアクティブなセッションを設定すると、すべて正常に動作するように見えます。アプリとエンド ユーザーに関する限り、すべてが同じです。
コード全体に適切なログを挿入し、コードを投稿し、動作中および失敗のケースで作成されたログを投稿する必要があります。
ログを作成するには (より高度なテクニックについては、こちらを参照してください):
NSLog(@"My log text");
少なくとも、Facebook API からのすべてのコールバック (使用していないものも含む) と、アプリケーション デリゲートのhandleOpenURL および openUrlメソッドにログを追加する必要があります。
テストしているデバイスを接続すると、Xcode オーガナイザーのコンソールにログが表示され、何が起こっているかがわかります。
参考までに、Facebook SDK コードは、ネイティブ アプリがインストールされている場合は最初にそれを使用しようとします。それ以外の場合は、Safari ブラウザーを起動して、Facebook の Web バージョンを通じて承認を求めます。
Angel García Olloqui による回答で説明されているように、Facebook の URL スキームの構成を再確認する必要があります。