2011-08-17 106 views
8

我正在使用FBConnect sdk爲了通過我的應用程序向用戶的個人資料發佈帖子。我遇到以下幾個問題:iOS上的Facebook FBConnect SDK問題

當相關代碼第一次在設備上運行時,用戶被重定向到Facebook應用程序/網站,並要求他授權它。如果用戶授權它,它將返回到應用程序,該應用程序彈出一個「連接到Facebook」視圖控制器,要求用戶登錄。這很奇怪,因爲用戶已經登錄,否則他怎麼可能授權應用程序?但我想這可能是好的,因爲他還沒有通過應用程序登錄。登錄後,它什麼都不做。只有第二次運行代碼後,他授權應用程序,用戶才能獲取發佈對話框。

如果用戶沒有授權該應用程序,當它在授權對話框後回到我的應用程序時,它會要求用戶登錄(就像他已經授權),並且在他登錄後不做任何事情。第二次代碼運行,授權對話框打開,optinos「授權」&「離開應用程序」,而不是「授權」&「不授權」/「允許」&「不允許」。另外,如果用戶通過他在Facebook上的帳戶設置刪除了他的授權,而不是隻是要求他重新授權,那麼會彈出一個facebook對話框(而不是發佈/授權對話框),並說:「An發生錯誤,請稍後再試。「以後嘗試不會有幫助。它會一直彈出,即使你重新啓動應用程序。讓它消失的唯一方法是重新安裝應用程序,這會導致它重新彈出授權對話框。

因此,這裏是我想達到的目標:用戶授權的應用程序

  1. 後,他就不必再次登錄。
  2. 在用戶授權應用程序後,發佈對話框將立即彈出,而不必重新運行代碼(這是通過按鈕觸發的)。
  3. 如果用戶未授權的應用程序,他將再次與授權對話框提示,而不是錯誤對話框
  4. 如果他拒絕授權,我將調用顯示錯誤/等功能。

下面是相關代碼:

MyViewController.m

- (void)shareOnFacebook 
{ 
    Facebook *facebook = [[Facebook alloc] initWithAppId:myAppID]; 
    [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] setFacebook:facebook]; 
    [facebook release]; 
    facebook = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] facebook]; 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    if ([defaults objectForKey:@"FBAccessTokenKey"] && [defaults objectForKey:@"FBExpirationDateKey"]) { 
     facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"]; 
     facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"]; 
    } 
    if (![facebook isSessionValid]) { 
     [facebook authorize:[NSArray arrayWithObjects:@"publish_stream", nil] delegate:(MyAppDelegate *)[[UIApplication sharedApplication] delegate]]; 
    } 

    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 
    //Giving the dictionary some parameters for posting defaults 
    [facebook dialog:@"feed" andParams:dictionary andDelegate:self]; //Note: we have 2 different delegates! appDelegate for connections & url switching, and self for dialogs 
} 

MyAppDelegate.h

@interface MyAppDelegate : NSObject <UIApplicationDelegate, FBSessionDelegate, FBDialogDelegate> 
{ 
    Facebook *facebook; // kept for facebook sharing, accessed only from MyViewController although delegate methods are handeled in here 
} 
@property (nonatomic, retain) Facebook *facebook; 

@end 

MyAppDelegate.m

- (void)fbDidLogin 
{ 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    [defaults setObject:[facebook accessToken] forKey:@"FBAccessTokenKey"]; 
    [defaults setObject:[facebook expirationDate] forKey:@"FBExpirationDateKey"]; 
    [defaults synchronize]; 
} 

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url 
{ 
    return [self.facebook handleOpenURL:url]; 
} 

是否有可能我在MyViewController上遺漏了一些委託函數?因爲我看到出於某種原因,我已經標記爲實現FBDialogDelegate協議,儘管他沒有從那裏實現任何功能。

如果你們能幫助我,我會很高興,因爲這對我來說是非常令人沮喪的。我在互聯網上找不到任何東西,我覺得我在這裏溺水了。

Tnx提前!

+0

這可能不是您的問題的答案,但在我看來,您可能遇到的一個問題是每個共享上重新創建的Facebook實例。從文檔看來,Facebook實例通常添加到AppDelegate,並且在應用程序運行時從不重新分配。也許看看我爲我正在編寫的項目編寫的代碼,它可能更容易解決您的問題(它還不完美,但似乎就分享而言工作得很好):http://stackoverflow.com/questions/7085162/facebook-connect-class-with-singleton-access-token-issue/7085809#7085809 –

回答

8

第一:

[facebook authorize:[NSArray arrayWithObjects:@"publish_stream",@"offline_access",nil] delegate:self]; 

offline_access關鍵在這裏將讓您的身份驗證令牌活着永遠(或者更具體地說,直到用戶手動取消授權在他們的Facebook的應用程序設置你的應用程序帳號設定)。此外,將您的活動VC設置爲委託(稍後會詳細介紹)。

其次:

-(void)popUserShareFeed { 
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 
    //Giving the dictionary some parameters for posting defaults 
    [facebook dialog:@"feed" andParams:dictionary andDelegate:self]; 
} 

呼叫在-fbDidLogin委託方法這個方法(或一個喜歡它)。也稱它在你原來的方法,如果會話仍然有效,即:

if (![facebook isSessionValid]) { 
     [facebook authorize:[NSArray arrayWithObjects:@"publish_stream", nil] delegate:(MyAppDelegate *)[[UIApplication sharedApplication] delegate]]; 
} else { 
    [self popUserShareFeed]; 
} 

...和你的新fbDidLogin

- (void)fbDidLogin 
{ 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    [defaults setObject:[facebook accessToken] forKey:@"FBAccessTokenKey"]; 
    [defaults setObject:[facebook expirationDate] forKey:@"FBExpirationDateKey"]; 
    [defaults synchronize]; 
    [self popUserShareFeed]; 
} 

(注:你必須在MyViewController.m定義此並用它作爲您的FBSessionDelegate。它在功能上等效。您的AppDelegate不需要也是您的FBSessionDelegate

三:

落實-fbDidNotLogin:(BOOL)cancelledFBSessionDelegate方法,像這樣:

-(void)fbDidNotLogin:(BOOL)cancelled { 
    if (cancelled) { 
     ... some alert about the user cancelling... 
    } else { 
     ... some alert about how it failed for some reason... 
    } 
} 

第四,至於你比扎羅錯誤去:A)在一般的Facebook的軟件開發工具包並不大,和B)我只設置身份驗證令牌和你facebook對象上的失效日期,如果

A)你不已經有一個實例化(即,它是nil

and

B)您設置的過期日期是未來(即, timeIntervalSinceNow [NSDate實例方法]調用它返回> 0)。

3

聽起來就像您遇到了此Facebook Platform Developer forum post中所述的相同問題。我遇到了同樣的問題,但在網絡上。該線程中只有一個來自Facebook的回覆,並且這是錯誤的信息。

Facebook有史以來最糟糕的開發人員文檔和開發人員支持,我不會屏住呼吸等待解決方案。

0

我已將FBConnect集成到如此多的應用程序中,但從未遇到過這樣的關鍵問題。所以,你的代碼中會缺少一些東西:

檢查FBAccessTokenKey &沒有檢查FBExpirationDateKey,只需使用FBConnect的FBSession類的會話對象。

只是嘗試使用我的代碼有幾個conidtions:

session = [[FBSession sessionForApplication:@"key" secret:@"AppSecretKey" delegate:self] retain]; 
     [session resume]; 
     _posting = YES; 

     // If we're not logged in, log in first... 
     if (![session isConnected]) { 
      loginDialog = nil; 
      loginDialog = [[FBLoginDialog alloc] init]; 
      [loginDialog show]; 
     } 
      // If we have a session and a name, post to the wall! 
      else if (_facebookName != nil) { 
         [self postToWall]; // Over here posting dialog will appear , if user has already logged in or session is running. 
        } 

     } 
     else { 
      [FBBtn setTitle:@"Login" forState:UIControlStateNormal]; // if you want to change the title of button 
      [session logout]; 
     } 

另外採取dealloc方法釋放會話對象的照顧而已,而不是任何其他方法將其釋放。

- (void)dealloc { 
     [super dealloc]; 
     [session release]; 
     session = nil; 
    } 

希望能解決您的問題。

+0

你能提供更多的代碼/信息嗎?我找不到這門課。我得到的只有Facebook,FBDialog,FBLoginDialog和FBRequest。 – Niv

+2

@Niv他使用舊版的Facebook SDK - FBConnect。您正在使用新版本 - Facebook iOS SDK。 –

0

不是直接的解決方案爲您的代碼的問題,但...

你有沒有考慮使用開源的庫呢? ShareKit就是一個很好的例子:http://getsharekit.com。整合非常簡單,它可以滿足您的一切需求。

+1

我從ShareKit本身收到這個錯誤(這個頁面是我在Google上第一次點擊,試圖調試ShareKit)。 ShareKit是可怕的 - Facebook的文檔總數說「沒有設置Facebook」,這顯然是不真實的。我會建議避免它 - 我即將切換回FB iOS SDK,因爲ShareKit太糟糕了。 – Adam

0

我有完全相同的問題,並用本毛思迪的響應上面,但我也決定創建一個Facebook對象一個簡單的單例類,所以,在我的AppDelegate我可以處理以下功能正常:

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url 
    sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { 

    return [[[FBManager defaultManager] facebook] handleOpenURL:url]; 

    //return [facebook handleOpenURL:url]; 
} 

我的單例類是FBSessionDelegateFBDialogDelegate,所以它處理相應的方法。

這允許我只提示用戶在他們實際嘗試發佈內容時登錄,而不是在應用程序啓動時登錄。

1

我有類似但並非相同的問題:消息「發生錯誤,請稍後再試。」始終顯示。

問題在於沒有正確配置的應用程序ID - 它是由客戶提供的(所以我不確定是什麼錯誤);一切工作正常,因爲我用我自己的測試應用程序ID(從以前的應用程序)取代它。