2011-08-29 62 views
2

我正在製作一個應用程序,我需要在多個視圖控制器中調用請求。我不希望Facebook登錄屏幕在應用程序啓動時顯示。只有在用戶未登錄時用戶點擊另一個視圖控制器中的按鈕時才應該打開它,因此將代碼放在應用程序委託中並不能解決問題。而且,在Facebook API中請求數據的整個異步過程正在令我失望,我開始鬆散了頭髮。如何在iOS上正確使用Facebook Graph 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 

實現上述

#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 

在課堂上使用Facebook的會議代表當你從兩個班見上面,我利用的通知,讓我知道什麼時候A類用戶登錄/離開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; 
} 

如預期,因爲愚蠢的異步請求的這ofcourse不工作。只有當用戶登錄時它才能正確工作。所以當我第一次打開應用程序時,它調用[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; 
} 

回答

2

我將開始重組你的代碼通過傳遞你想在得到您的回答從FB回到執行塊工作。這與您在jQuery中如何使用ajax相似。

- (void)viewDidLoad { 
[super viewDidLoad]; 

Facebook *facebook = [PBSocialMedia sharedFacebook]; 

[self withGraphAPIDo: ^{ 
    [facebook requestWithGraphPath:@"106378916135129/photos" andDelegate:self]; 
    }]; 
} 
+0

謝謝回答!你能解釋更多嗎?你的意思是多少重組?我應該放棄通知嗎?當我調用「sharedFacebook」函數時,它幾乎會立即繼續到塊的下一行。我很抱歉,但我不明白如何做到這一點。 – LuckyLuke

+0

我正在使用MGTwitterEngine來完成這個工作,它會爲每個請求返回一個唯一的字符串,您可以使用它來跟蹤響應。所以我調整它將響應塊存儲到由請求ID鍵入的字典中。當請求回調進入時,我通過請求ID查找字典中的塊,然後執行它。 – 2011-08-30 18:02:44

相關問題