11

新しい Facebook SDK for iOS を統合しようとしていますが、いくつかの概念を理解するのに問題がありました。

  1. 認証[FBSession sessionOpenWithPermissions:...]ダイアログが表示され、アプリを返します。認証成功。

  2. 次に、アプリをシャットダウンし、再起動します。[[FBSession activeSession] accessToken]以前に保存されたトークンを正常に返します。

  3. ただし、同時に を[[FBSession activeSession] isOpen]返しますNO。(これは、セッションを使用する準備ができていないことを意味します。)

  4. また、この時期です[[FBSession activeSession] state]ここFBSessionStateCreatedTokenLoadedのチュートリアルでは、呼び出しを使用して、アクティブなセッションがロードされ、トークンで開かれていることを確認します。isOpen

では、ユーザーを認証ダイアログにリダイレクトせずにトークンをロードしたセッションを開くには、何を呼び出すのでしょうか?

ヒント:

FBSessionState列挙型では、次のようFBSessionStateOpenに述べています。

ユーザーがログインしているか、キャッシュされたトークンが使用可能であることを示すオープン セッション状態。

ただしFBSessionStateCreatedTokenLoaded、次のように説明されています。

キャッシュされたトークンが読み込まれたことを示す 2 つの初期セッション状態の 1 つ。セッションがこの状態にある場合、open* を呼び出すと、UX やアプリの切り替えなしでセッションが開かれます。

これらのセッション遷移を理解するのを手伝ってくれませんか?

4

5 に答える 5

31

実際の 'FBLoginView' を使用することに加えて、自分の設定 UI でユーザーに「ログイン済み」/「ログインしていない」メッセージを公開するため、ログイン状態を理解するのに役立つ、私が作成した Facebook ユーティリティ クラスを含めています。ユーザーが承認状態を切り替えることができるようになると、コンポーネント。

以下のコードは、このgistからも入手できます。

switch ステートメントですべてのFBSessionState型を正しく解釈できていない可能性がありますが、これまでのところ、テストしたケースではうまく機能しています (これをまとめただけです)。

注意すべき重要なことは、他の人がほのめかしたことですが、キャッシュされた認証トークンをすぐに使用できない場合がありますが、Facebookopen呼び出しを行うと、それを再利用可能 (更新) にすることができます。このオープン呼び出しは、UI をトリガーしたり、OAuth ウィンドウ/アプリの切り替えを妨げたりすることなく、舞台裏で機能します (キャッシュされたトークンがある場合)。

メソッドのコメントを参照してくださいisLoggedInAfterOpenAttempt。状態を確認する方法に注意してください。FBSessionStateCreatedTokenLoadedその後、呼び出しを行います

-openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error).

このクラスに関するその他の情報:

  • ここには、protocol に準拠するタイプの、ログインしているユーザーをキャッシュするためのプロパティがありますFBGraphUser。ただし、ここで説明するログイン方法では使用されません。
  • Facebook SDK 3.0 for iOS のサンプル コードでは、単純なアプリ以上のものがある場合、これらの種類の操作を保持して管理する独自のクラスを構築することを提案しています。以下の私のこのクラスは、私のアプリのアイデアの始まりです。
  • これを機能させるには、'log4Info' および 'log4Debug' マクロを NSLog に置き換えることができます。
#import "UWFacebookService.h"

@implementation UWFacebookService

// 静的
static const int ddLogLevel = LOG_LEVEL_DEBUG;

// 強い
@synthesize facebookGraphUser = _facebookGraphUser;


#pragma mark - お問い合わせ

- (BOOL)isSessionStateEffectivelyLoggedIn:(FBSessionState)state {
    BOOL effectiveLoggedIn;

    スイッチ (状態) {
        ケース FBSessionStateOpen:
            log4Info(@"Facebook セッション状態: FBSessionStateOpen");
            効果的にLoggedIn = YES;
            壊す;
        ケース FBSessionStateCreatedTokenLoaded:
            log4Info(@"Facebook セッション状態: FBSessionStateCreatedTokenLoaded");
            効果的にLoggedIn = YES;
            壊す;
        ケース FBSessionStateOpenTokenExtended:
            log4Info(@"Facebook セッション状態: FBSessionStateOpenTokenExtended");
            効果的にLoggedIn = YES;
            壊す;
        デフォルト:
            log4Info(@"Facebook セッション状態: オープンまたはオープン可能なタイプのいずれでもない。");
            効果的にLoggedIn = NO;
            壊す;
    }

    効果的にLoggedInを返します。
}

/**
* Facebook セッションが承認済みの状態であるかどうかを判断します。キャッシュされている場合は、まだ開く必要がある場合があります
* トークンですが、この呼び出しの目的は、ユーザーが許可されているかどうか、少なくとも許可されていないかどうかを判断することです。
*明示的に何かを尋ねました。
*/
- (BOOL)isLoggedIn {
    FBSession *activeSession = [FBSession activeSession];
    FBSessionState 状態 = activeSession.state;
    BOOL isLoggedIn = activeSession && [self isSessionStateEffectivelyLoggedIn:state];

    log4Info(@"Facebook のアクティブなセッションの状態: %d; ログに記録された結論: %@", state, (isLoggedIn ? @"YES" : @"NO"));

    isLoggedIn を返します。
}


/**
* 有効なトークンが読み込まれている場合 (おそらくバックグラウンドで更新が必要)、Facebook セッションを静かに開こうとします。
* その試行の後、セッションが有効な許可された状態の 1 つにあるという基本概念に従います。
*/
- (BOOL)isLoggedInAfterOpenAttempt {
    log4Debug(@"FBSession.activeSession: %@", FBSession.activeSession);

    // キャッシュされたトークンがない場合、ここで open を呼び出すと、UX がログインに
    // 発生する; ユーザーが [設定] でログイン ボタンをクリックしない限り、それが発生することは望ましくありません。
    // ここで、open を呼び出す前にトークンがあることを確認します
    if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
        log4Info(@"キャッシュされたトークンがあるため、ユーザーのログインを再確立します。");
        // キャッシュされたトークンがあったとしても、セッションを使用可能にするためにログインする必要があります:
        [FBSession.activeSession openWithCompletionHandler:^(FBSession *セッション、FBSessionStateステータス、NSError *エラー) {
            log4Info(@"ログイン セッションの開始が完了しました。状態: %d", status);
        }];
    }
    そうしないと {
        log4Info(@"アクティブなセッションは状態 'FBSessionStateCreatedTokenLoaded' ではありませんでした。状態は %d です", FBSession.activeSession.state);
    }

    [自分はログインしています]を返します。
}

@終わり

于 2012-08-30T16:55:44.877 に答える
5

これは、トークンが保存されている (キャッシュされている) か、または他の方法で既に使用可能になっている場合でも、Facebook iOS ライブラリでは、open メソッドを使用してセッションを再初期化する必要があることを意味します。

そうすることで、既存のトークンを再利用できる場合 (これはあなたの場合です)、UX (ユーザー エクスペリエンス - アプリの切り替えや Facebook のログイン ポップアップ) はトリガーされません。

ユーザーの印象では、彼はログアウトしたことはありませんが、アプリで起こっていることは、Facebook に連絡してセッションを再開しようとしているということです。

これがそのように設計されている理由は、トークンが利用可能であるが有効期限が切れている場合、Facebook ライブラリが「トークンの有効期限が切れています。今すぐ新しいトークンを取得しない限り、ログアウトしたことを考慮してください」と通知するためです。

それが役立つことを願っています。

于 2012-08-12T01:07:20.933 に答える
2

次のコード サンプルを試してください。

/////////////////////////////////

-(void)CallBackOpenURLFromDelegate:(NSURL *)url
{
    [FBSession.activeSession handleOpenURL:url];
}

-(id)init
{
    self = [super init];
    FBSessionTokenCachingStrategy* pToken = [[[FBSessionTokenCachingStrategy alloc]initWithUserDefaultTokenInformationKeyName:@"STokenInfoX"]autorelease];
    FBSession.activeSession = [[FBSession alloc] initWithAppID:FACEBOOK_AppId
                                                   permissions:[NSArray arrayWithObject:@"status_update"]
                                               urlSchemeSuffix:@""
                                            tokenCacheStrategy: pToken];
    return self;
}


-(void)dealloc
{
    [FBSession.activeSession close];
    [super dealloc];
}

-(void) UploadImpl:(NSString*)strImagePath
{
    FBRequest *photoUploadRequest = [FBRequest requestForUploadPhoto: [UIImage imageWithContentsOfFile:strImagePath ]];
    [photoUploadRequest startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error)
    {
        NSLog(@"%@",[error description]);
        //self.delegate
    }];
}
于 2012-08-12T00:44:03.310 に答える
1

これは古いスレッドかもしれませんが、今は、アプリ デリゲートの (void)applicationDidBecomeActive:(UIApplication *)application 内から FBSession オブジェクトで handleDidBecomeActive を呼び出すだけです。

例えば:

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    [[[MLSocialNetworksManager sharedManager] MLFacebook] handleDidBecomeActive];
}

MLFacebook は私の FBSession オブジェクトです。

于 2013-05-26T06:28:04.347 に答える
0

init View Controllerを呼び出すだけです

self.FBloginView = [[FBLoginView alloc] init];
于 2014-04-12T22:03:01.153 に答える