Parseを使用して、iOSアプリにFacebookログインを実装しようとしています。
let permissionsArray = ["public_profile", "email"]
PFFacebookUtils.logInInBackgroundWithReadPermissions(permissionsArray)
{ (user: PFUser?, error: NSError?) in
if let user = user {
//we logged in!
}
else {
//login error!
}
}
これはシミュレータではうまく機能しますが、デバイスでは機能しません。デバイスで、次のエラーが表示されます。
エラーDomain = com.facebook.sdk.login Code = 308 "操作を完了できませんでした。(com.facebook.sdk.loginエラー308.)
エラーコード308は、 FBSDKLoginBadChallengeString
、「ログイン応答に有効なチャレンジ文字列がありませんでした」
Facebookでアプリを承認すると、次のように呼び出されます。
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
}
URLは次のとおりです。
fb1640722449492705://authorize/#state=%7B%22challenge%22%3A%225OKWv3wN%2BEH%2BeQu48Xv6ty%2BRuek%3D%22%2C%22com.facebook.sdk_client_state%22%3Atrue%2C%223_method%22%3A1%2C%220_auth_logger_id%22%3A%22564CD915-2CFC-4989-9AF6-CEA389908D51%22%7D&granted_scopes=user_birthday%2Cpublic_profile&denied_scopes=&signed_request=c8SBBDeaNpF-R_XTYx4LRA0BWm5p9IwXDr8M4nL3YXI.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImNvZGUiOiJBUURhTXJibGw4Q3dITkd5M0xnQmNkVTNuYWRkeEVoTU5mMmx3eFpZU2IwZl9SU284YXhZdXZaRS02RnA2bU5Cdy1CWkVoRmt2Zk1xX1AxSHltUG00aWhkWE9hYmlvWFBiMnpCYkVnR1RRX3lzZVFIZXdHU19OcmpkNUF6WGtob1dfVE4wTmRrSGk5MzY0V2hFWUJDV0dfcE16RXpQVExHWE13X1dzb0QzZGtITm5fM0tHNjFxUjJyM3RDWVlNQTE4WENpS1dXTHUyM2dIRVhmTXc3ZTQ0M2xDQUtGRl9KSXcyVk1sS01FOTQ4dHQ2U1Fqb0tlVkp4RmJNSEFsWDZFYWxlUnQ2aGRrTGZlU2xuVTV5VjZ1bFhldHkxeEV5RmRDZVFHb2RXQ0dULVVCd3QyM0haY0dxNk8zbnE1cDRNWjNFZ012U2JhSGZyMmF6Wm8xUXk2X2xSQVNWcFlMVDZUdU5wZnMwVkJqNEdSaFEiLCJpc3N1ZWRfYXQiOjE0MzM0MTg2MDksInVzZXJfaWQiOiIxNDM3MzM0ODk5OTIwNDA5In0&access_token=CAAXUOnbG6uEBANtAd9DzWBSu4LLOEcPsu86Ny0Ir
はい、 ParseのFacebookログインガイド (すべてのバンドルIDが一致することを確認し、必要なAppDelegateメソッドをすべて実装するなど)のすべてに従いました。
このエラーは正確に何を意味し、どのように解決しますか?
それを修正しました。この問題は、FBSDKLoginButton
を使用してParseandでログインすると発生しました。
私がやっていたことは次のとおりです。
_//in my UI setup code:
let fbLoginButton = FBSDKLoginButton()
fbLoginButton.addTarget(self, action: "fbButtonTouched:", forControlEvents: UIControlEvents.TouchUpInside)
....
func fbButtonTouched() {
let permissionsArray = ["public_profile", "email"]
PFFacebookUtils.logInInBackgroundWithReadPermissions(permissionsArray)
{ (user: PFUser?, error: NSError?) in
if let user = user {
//we logged in!
}
else {
//login error!
}
}
}
_
tapping a FBSDKLoginButton
がユーザーのログインを試みることを(難しい方法で)見つけました! _PFFacebookUtils.logInInBackgroundWithReadPermissions
_を使用してユーザーをログインさせる必要もありませんでした。だから私はfbButtonTouched()
を取り除き、うまくログインできました。
そこで起こったのは、同時に2つのログインを試行していたことで、シミュレーターは満足していましたが、デバイスは満足していませんでした。
理由を知りたい場合は、受信したログイン認証チャレンジが didが期待していたものと一致しなかったためです 2番目のログイン試行の1つであり、したがって2番目のログイン試行の認証チャレンジを待っていました。
FBSDKLoginButton
のドキュメントでは、現在、anythingに言及していませんが、タップするとログフローが開始され、UIButton
のサブクラスであるため、それにaddTarget
を使用し、ログインフローを自分で実装する必要があると思います。また、2つのログインを同時に行うと、誤解を招くFBSDKLoginBadChallengeString
につながります。災害のレシピ...
EDIT:ドキュメントはそれに応じて更新されました:
FBSDKLoginButton
は_[FBSDKAccessToken currentAccessToken]
_と連携して、何を表示するかを決定し、タップすると自動的に認証を開始します(つまり、アクションターゲットを手動でサブスクライブする必要はありません)。
(私の強調)
FBSDKLoginKit 4.7.1およびFBSDKCoreKit 4.8を使用している場合、totvosの回避策とその動作を確認しました。
回避策...アプリをビルドして電話にコピーし、デバイスから(デバッガーではなく)アプリを起動します。次に、実行中のプロセスにデバッガーを接続します。これは、タイミングの問題がこれを壊しているものを回避するようであり、デバッグ中にさまざまなキーチェーン操作が正しく機能するように見えます。
リファレンス: https://forums.developer.Apple.com/thread/4743#85335
更新:
この回避策は常に機能しなかったので、上記の@cocoの回答を使用することになりました: https://stackoverflow.com/a/31480026/877225
このエラーは、ログアウトしてから再度ログインしたときにしか見られませんでした。
ログインとログアウトに関連するUIがまったく異なるため、ログインとログアウトのコードは異なるファイルにあり、2つの個別のFBSDKLoginManagerインスタンスをインスタンス化しました。 1つのインスタンスに統合するだけで問題は解決しました。
どうやら私のために働いた唯一の解決策は、ターゲットにキーチェーン共有資格を追加することです。
Project_name-> target_name-> Capabilities-> Keychain Sharingで見つけることができます
次のようにアップグレードしたときにこの問題が見つかりました。
FBSDKCoreKit 4.4.0
FBSDKLoginKit 4.4.0
FBSDKShareKit 4.4.0.
私がダウングレードすると消えました:
FBSDKCoreKit 4.2.0
FBSDKLoginKit 4.1.0
FBSDKShareKit 4.1.0
どの時点でアップグレードがこれを引き起こすのかを発見する機会がありませんでした-たとえば、3つすべてで4.3.0を使用できませんでしたか?
Xcodeから起動せずに、デバイスから直接アプリを実行してみてください。次に、308に煩わされずにFacebookにログインします。その後、同じ問題なしにXcodeからデバイスへの起動を再開できます。
これは、FB SDKとiOSの間の問題であり、Parseに関連していないようです。誰かがこの主題について私たちを啓発できれば幸いです。
Xcodeのバージョンは7.1、FB SDKは4.8.xです。
私は使っています
pod 'FBSDKCoreKit', '~> 4.8.0'
pod 'FBSDKLoginKit', '~> 4.8.0'
pod 'FBSDKShareKit', '~> 4.8.0'
...そして、同じセッション中にログアウトしてログインしたときにcode 308
問題が発生しました。 [[FBSDKLoginManager alloc] logOut]
を呼び出す直前に[facebookLoginManager logOut]
またはlogInWithReadPermissions:
(永続マネージャーを使用)を使用しても機能しませんでしたが、
[FBSDKAccessToken setCurrentAccessToken:nil];
[FBSDKProfile setCurrentProfile:nil];
logInWithReadPermissions:
呼び出しが正常に機能する前。 (iOS 9.2でテスト済み。)
ダウングレードする前に、ローカルキャッシュをクリアしようとしました。 Facebookアカウントを切り替えるときにこの問題が発生しました。アプリを削除し、Facebookを強制終了してからすべてを再実行し、それが持続するかどうかを確認します。 Facebookが無効になった古いキャッシュキーを渡すバグがある可能性があります。ダウングレードするとキャッシュがクリアされるか、古いバージョンにバグがありません。
このアプリを終了せずにログアウトして再度ログインすると、このエラーも発生します。
let deletepermission = FBSDKGraphRequest(graphPath: "me/permissions/", parameters: nil, HTTPMethod: "DELETE")
deletepermission.startWithCompletionHandler({(connection,result,error)-> Void in
println("the delete permission is \(result)")
dispatch_async(dispatch_get_main_queue(), { () -> Void in
FBSDKAccessToken.setCurrentAccessToken(nil)
FBSDKProfile.setCurrentProfile(nil)
fbLoginManager.logOut()
AppDelegate.sharedAppDelegte().logout()
})
})
エラー308も発生しましたが、Parse SDKを使用していませんでした。
これらのエラーは、Facebook iOS SDKをバージョン4.0.1
(FacebookSDKs-iOS-20150402
)新しいバージョンのいずれか(4.2.0
-FacebookSDKs-iOS-20150528
または4.3.0
-FacebookSDKs-iOS-20150625
)。
Facebook iOS SDKをバージョン4.0.1
私のためにこの問題を解決しました。
サイドノートとして:SDKの新しいバージョンは、6月初旬のSO.
そのようなエラーを解決するには、次の手順に従います。
PFFacebookUtils 1.9.0とFBSDKLoginKit 4.7.0を使用している私は、ログアウトとログイン(アプリを再起動せずに)した後、解決策を見つけました-目的C:[[PFFacebookUtils facebookLoginManager] logOut];
前 [PFFacebookUtils logInInBackgroundWithReadPermissions
ログアウトするまで同じFBSDKLoginManagerインスタンスを使用してから、新しいインスタンスを作成します。
[fbLoginManager logOut];
fbLoginManager = [[FBSDKLoginManager alloc] init];
Facebookからの公式の回答:
すでに別のバグレポートでこの問題を追跡しており、Apple側ではエラーのようです。
このためにダウングレードする必要はありません。
次のことを実行すると動作します。-派生データを消去します(Xcode->設定->場所->派生データの横にある小さな矢印をクリックします)。これを実行する前に、派生データについて必ず読んでください。複雑なプロジェクトがあり、いくつかのばかげたミスをした場合(例:ファイルを削除した場合)、アプリを再実行する前に問題を把握する必要があります。しかし、それほど難しくはありません。 -デバイス/シミュレータからアプリを削除します-FacebookからFacebookアプリの承認を削除します([設定]-> [アプリ]-> [x]をクリックしてアプリを削除します)
アプリを再実行すると、すべてが機能するはずです。
がんばろう!
私はそれを修正します:1. Bolts.frameworkを追加2. AppDelegateで:#import
これは、誤って同時に2回ログインしようとするとauthenticationChallengeの問題が原因であり、その後のログインではデバッグ中にコンソールでキーチェーンの警告が表示されます。このエラーはデバイスでデバッグするときに顕著になります。デバッグモードがなければ、このエラーは発生しません。理由は、デバッグしていないときにキーチェーンが正常に機能するためです。
これにはいくつかの回避策があります。1.デバッグモードなしでログインしてみてください。成功したら、デバッグモードでさらにログインできます。 2.エラーコードを確認しますFBSDKLoginBadChallengeStringを呼び出して[FBSDKAccessToken setCurrentAccessToken:nil]
トークンをクリアして、再度ログインを実行します。
エラーコード308はFBSDKLoginBadChallengeStringです。
FBSDKLoginManagerに共有インスタンスを使用すると、問題が解決します。 1つのFBSDKLoginManagerのみがインスタンス化されることを確認するシングルトンを作成しました。
私はそれがiOS9 Safariログインに関係していると思いますが、100%確かではありません
以下のようにログインおよびログアウトイベントをキャッチしようとしたときに同じ問題が発生しました
loginButton = [[FBSDKLoginButton alloc] init];
// Handle clicks on the button
[loginButton
addTarget:self
action:@selector(loginButtonClicked) forControlEvents:UIControlEventTouchUpInside];
// Once the button is clicked, show the login dialog
-(void)loginButtonClicked
{
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[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");
}
}];
}
ただし、これはカスタムログインボタンにのみ適しています。デフォルトのfbログインボタンを使用している場合、FBSDKLoginManagerはすでに初期化されているため、別のボタンを作成しようとするとエラーが発生します。
そのため、ログインおよびログアウトイベントをキャッチするには、ログインボタンのデリゲートを設定し、次のように処理します。
loginButton = [[FBSDKLoginButton alloc] init];
loginButton.delegate = self;
- (void)loginButton:(FBSDKLoginButton *)loginButton didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error {
if (!error) {
[self getFBProfile];
}
}
- (void)loginButtonDidLogOut:(FBSDKLoginButton *)loginButton {
[self logout];
}
Facebook SDKを最新バージョンに更新すると、これが解決しました。