iphone - iOSでFacebook Graph APIを適切に使用する方法

iphone objective-c ios facebook delegates

複数のView Controllerでリクエストを呼び出す必要があるアプリケーションを作成しています。アプリの起動時にFacebookのログイン画面を表示したくありません。ユーザーがログインしていない場合、ユーザーが別のビューコントローラーのボタンをタップしたときにのみ開くため、コードをアプリデリゲートに配置しても問題の解決策にはなりません。そして、Facebook APIでデータを要求する非同期プロセス全体が私を殺し、髪の毛が抜け始めています。

facebookオブジェクトを取得し、それをシングルトンとして扱うための静的メソッドを持つクラス。

#import "PBSocialMedia.h"
#import "PBFacebookDelegate.h"

static Facebook *facebook;
static PBFacebookDelegate *facebookDelegate;

@implementation PBSocialMedia

+ (Facebook *)sharedFacebook {

    if (facebook == nil) {
        facebookDelegate = [[PBFacebookDelegate alloc] init];
        facebook = [[Facebook alloc] initWithAppId:@"156687441079334" andDelegate:facebookDelegate];
    }

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if ([defaults objectForKey:@"FBAccessTokenKey"] 
        && [defaults objectForKey:@"FBExpirationDateKey"]) {
        facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"];
        facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"];
    }

    NSArray *permissions = [NSArray arrayWithObjects:@"user_photo_video_tags", @"friends_photo_video_tags", @"user_photos", @"friends_photos", nil];

    if (![facebook isSessionValid]) {
        [facebook authorize:permissions];
    } else {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"connectedToFacebook" object:self];
    }

    return facebook;
}

+ (Facebook *)sharedFacebookWithoutAuthorizing {
    return facebook;
}

@end


上記のクラスで使用されているFacebookセッションデリゲートを実装するクラス

#import "PBFacebookDelegate.h"
#import "PBSocialMedia.h"

@implementation PBFacebookDelegate

/**
 * Called when the user successfully logged in.
 */
- (void)fbDidLogin {
    Facebook *facebook = [PBSocialMedia sharedFacebook];

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:[facebook accessToken] forKey:@"FBAccessTokenKey"];
    [defaults setObject:[facebook expirationDate] forKey:@"FBExpirationDateKey"];
    [defaults synchronize];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"connectedToFacebook" object:self];
}

/**
 * Called when the user dismissed the dialog without logging in.
 */
- (void)fbDidNotLogin:(BOOL)cancelled {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"dismissedFacebookDialog" object:self];
}

/**
 * Called when the user logged out.
 */
- (void)fbDidLogout {
   [[NSNotificationCenter defaultCenter] postNotificationName:@"disconnectedFromFacebook" object:self];
}


@end


上記の2つのクラスからわかるように、ユーザーがFacebookにログイン/ログアウトするタイミングを知るために、通知を利用しています。以下のコードは、私がそれを使用しようとしている方法の例です:

- (void)viewDidLoad {
    [super viewDidLoad];

    Facebook *facebook = [PBSocialMedia sharedFacebook];

    if (self.canUseGraphAPI) {
        [facebook requestWithGraphPath:@"106378916135129/photos" andDelegate:self];
        NSLog(@"Can use");
    } else {
        NSLog(@"Can't use");
    }
}

- (void)connectedToFacebook {
    self.canUseGraphAPI = YES;
}

- (void)disconnectedFromFacebook {
    self.canUseGraphAPI = NO;
}


もちろん、これは愚かな非同期リクエストのため、意図したとおりに機能しません。これは、ユーザーがログインしている場合にのみ正しく機能します。そのため、アプリを初めて開いたときに[PBSocialMedia sharedFacebook];が呼び出され、リクエスト関数が続行され、sharedFacebook関数が完了するのを待機しません。誰かが以前にこの問題に遭遇したことを本当に望んでいますコードのさまざまな場所でリクエストを実行したいのですが、ユーザーがログインしているときのみであり、ユーザーがリクエストする前にログインしている間は待機する必要があります。以下のコードは機能していませんが、私が欲しいものを示しています!

- (void)viewDidLoad {
    [super viewDidLoad];

    Facebook *facebook = [PBSocialMedia sharedFacebook];

    while (self.canUseGraphAPI) {
        // WAITING FOR LOGIN IN
    }

    [facebook requestWithGraphPath:@"106378916135129/photos" andDelegate:self];
}

- (void)connectedToFacebook {
    self.canUseGraphAPI = YES;
}

- (void)disconnectedFromFacebook {
    self.canUseGraphAPI = NO;
}
答え
FBから回答を受け取ったときに実行するブロックを渡すことで、コードが再構築されて機能するようにします。これは、jQueryでajaxを実行する方法に似ています。

- (void)viewDidLoad {
[super viewDidLoad];

Facebook *facebook = [PBSocialMedia sharedFacebook];

[self withGraphAPIDo: ^{
    [facebook requestWithGraphPath:@"106378916135129/photos" andDelegate:self];
    }];
}
関連記事

iphone - 指数値が表示されない、どうすればよいですか?

iphone - iPadアプリでUITabbarItemsの幅とそれらの間のマージンを変更する

iphone - CGRectIntersectsRectの質問

iphone - アプリケーションがジェイルブレイクされたiPhoneにデプロイされた後の奇妙なGDBの動作

iphone - スクロール中のUITableViewCellアニメーション

iphone - UIActionSheetビューを変更する方法?

iphone - XCode 4を使用してもiOS PhoneGap 1.0プラグインが見つからない

iphone - 配布プロファイルのセットアップ中に問題が発生しました

iphone - iPhone-CGContextShowTextAtPointを使用して特殊文字を描画する

javascript - jQueryバインド解除イベント