奇妙な理由により、Facebook は、実際には単なる通知オブザーバーである完了ハンドラーを作成することにしました。彼らがこれを行っている理由を無視して、コールバック内のオブジェクトを保持できないため、FBSession を開くリクエストを作成し、コールバックを 1 回だけ発生させる何らかの方法が必要です。
ユーザーがボタンを押したときに「publish_actions」権限を持つ Facebook セッションが開いていない場合、アクティビティ インジケーターを表示して、Facebook セッションが開いている間は UI との対話を防止する必要があります。
以下は、Facebook へのログインに使用されているメソッドです。
- (void)loginToFacebookFromViewController:(UIViewController *)viewController completion:(void (^)(NSString *facebookAccountName))completion
{
if([self isLoggedIntoFacebook] == NO)
{
[viewController startLoadingAnimation];
[FBSession openActiveSessionWithPublishPermissions: @[ @"publish_actions" ] defaultAudience:FBSessionDefaultAudienceFriends allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error)
{
if(error == nil)
{
[FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id<FBGraphUser> user, NSError *error)
{
NSString *accountName = [user name];
if(error == nil)
{
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
[standardUserDefaults setObject:accountName forKey:TSFacebookAccountName];
[standardUserDefaults synchronize];
}
[viewController stopLoadingAnimation];
if(completion != nil)
completion(accountName);
}];
}
else
{
[viewController stopLoadingAnimation];
if(completion != nil)
completion(nil);
}
}];
}
else
{
if(completion != nil)
completion([self facebookAccountName]);
}
}
完了ハンドラーが保持されていない場合 (セッション状態が変化したときに NSNotifications がポストされるため、これも意味をなさない理由で)、このメソッドは完全に機能します。
アプリは Facebook を中心に展開していないため、セッション状態がいつ変化するかについては関心がありません。ユーザーが何かを Facebook に共有しようとして、アクティブなセッションが開かれていない場合、ログイン プロセスが開始され、セッションが開かれている場合は共有プロセスが続行されます。そうしないと、ユーザーにエラー メッセージが表示されます。
Facebook がこの種の機能をどのように実装することを期待しているかを誰か説明してもらえますか。それはかなり一般的なユース ケースのように思われ、誰かが「デフォルトの Facebook ダイアログを使用しない理由」について言及する前に、カスタム UI をユーザーに提示する必要があるためです。 Open Graph の投稿に使用される特定の情報を収集するためのユーザー。