2012-10-10 65 views
6

我正在更新應用程序以使用最新的Facebook SDK以訪問iOS6原生Facebook支持。它目前使用Facebook SDK的一個漂亮的舊版本。使用[FBSession openActiveSessionWithPublishPermissions:..]時發生錯誤

該應用程序需要Facebook的「publish_actions」權限才能使用Facebook的唯一功能。

我最初認爲我可以使用[FBSession openActiveSessionWithPublishPermissions: ...],但是當用戶在iOS6設置中配置了Facebook時,iOS6會失敗。它失敗的,因爲這個要求,from the Facebook docs

注意,使用iOS 6的本地身份驗證,應用程序需要改變他們的請求用戶 權限的方式 - 爲讀 和寫入權限的應用程序必須分開他們的請求。面向iOS的Facebook SDK支持這些 功能,並幫助開發人員使用它們構建適用於多個iOS版本和設備配置的應用程序,這些應用程序適用於 。

這是一個很大的PITA,IMO。我們希望提醒用戶一次獲得許可並完成它,但是每個Apple/Facebook的「新」理想是在需要但尚未授予的情況下提示特定權限。

目前的計劃是爲iOS5用戶和iOS6用戶保留我們以前的行爲,這些用戶沒有在設置中配置Facebook。並符合使用本地訪問的iOS6用戶的新雙提示。

問題是,要做到這一點的最佳方法是什麼?我該如何去檢測Facebook SDK是否會選擇iOS6原生登錄與後備機制?我忽略了一些明顯的東西?

編輯:

gerraldWilliam把我拉到正確的軌道。他的解決方案几乎可以工作,但ACAccountTypeIdentifierFacebook在iOS5中不可用。此外,如果用戶在應用程序中阻止FB訪問,則accountsWithAccountType調用將返回一個空數組。

通過詢問賬戶類型匹配標識符「com.apple.facebook」可以解決第一個問題 - 這將在iOS5上返回nil,在iOS6上返回一個真實賬戶類型對象。

但第二個問題是無法解決的。我的新計劃是始終在iOS6上打開具有隻讀權限的初始會話,並在稍後的上下文中根據需要提示發佈權限。在iOS5上,我仍會打開指定所需publish_actions權限的初始會話。下面的代碼:如果

ACAccountStore* as = [[ACAccountStore new] autorelease]; 
ACAccountType* at = [as accountTypeWithAccountTypeIdentifier: @"com.apple.facebook"]; 
if (at != nil) { 
    // iOS6+, call [FBSession openActiveSessionWithReadPermissions: ...] 

} else { 
    // iOS5, call [FBSession openActiveSessionWithPublishPermissions: ...] 
} 

回答

5
ACAccountStore *store = [[ACAccountStore alloc] init]; 

ACAccountType *accountType = [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook]; 
NSArray *accounts = [store accountsWithAccountType:accountType]; 
NSLog(@"accounts:%@", accounts); 

賬戶爲零(或者它返回一個空數組,我不知道),然後在iOS6的用戶沒有配置的Facebook。你可以測試一下,如果該值表明Facebook還沒有配置iOS6,你可以調用你的回退機制。

+0

這幾乎工程。兩個問題是1)ACAccountTypeIdentifierFacebook在iOS5和2上不可用)如果用戶在設置中配置了FB但阻止了對調用應用程序的訪問,accountsWithAccountType將返回一個空數組。標記爲正確的答案,因爲它使我走上了最終解決方案的道路,我將在這個問題中提出。 – TomSwift

+0

'accountsWithAccountType'爲我返回一個空數組,即使我在iOS 6中,Facebook集成已配置並且可以發佈。 – jowie

+0

也是空的我,並得到這個惱人的錯誤com.facebook.sdk錯誤2 ...任何意見? – D33pN16h7

0

抱歉,但我在iOS6的 行

ACAccountType* at = [as accountTypeWithAccountTypeIdentifier: @"com.apple.facebook"]; 

不回零,即使用戶沒有配置帳戶...

這意味着你可以檢查什麼是用戶的IOS版本(5或6)

NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; 

This link能有所幫助。

6

根據我在Facebook的開發人員網站上閱讀的所有內容(這有些矛盾),「僅發佈」應用程序的工作流程並非他們所想的,Apple和iOS似乎忽視了這一點共。

的Facebook提供了docs you referenced一些指導:

提示5:禁用本地登錄對話框

在某些情況下,應用程序可以選擇禁用本地登錄對話框使用Facebook的新版本但是爲了避免重寫他們向用戶請求權限的方式。要使用fast-app-switch以前的行爲進行登錄,請使用不推薦使用的FBSession方法openActiveSessionWithPermissions和reauthorizeWithPermissions。

這是我目前正在關注的路線。略有不同,但總體效果相同。

if (FBSession.activeSession.isOpen == NO) { 
    // This will bypass the ios6 integration since it does not allow for a session to be opened 
    // with publish only permissions! 
    FBSession* sess = [[FBSession alloc] initWithPermissions:[NSArray arrayWithObject:@"publish_actions"]]; 
    [FBSession setActiveSession:sess]; 
    [sess openWithBehavior:(FBSessionLoginBehaviorWithFallbackToWebView) completionHandler:^(FBSession *session, FBSessionState status, NSError *error) { 
     [self onSessionStateChange:session 
          andState:status 
          andError:error]; 
    }]; 

其結果是,應用程序將始終繞過簽署關於發佈iOS6的整合,在大多數情況下切換至Facebook的應用程序(因爲用戶通常已經安裝在手機上的Facebook)的單認證審批。

如果用戶選擇使用他們的Facebook帳戶登錄我們的應用程序,我打電話openActiveSessionWithReadPermissions,它將使用IOS6 Facebook集成(如果存在)。如果他們隨後決定分享,我會打電話給reauthorizeWithPublishPermissions,如果有的話也會使用IOS6集成。

鑑於可用的最小和混亂的文檔,我不能確定這是否是「正確」的方法來處理這個問題,但它似乎工作。您可以對IOS5或IOS6應用使用相同的代碼,因爲它只能通過Facebook SDK進行調用。它也贊同Facebook正在推廣的相同請求中不混合的讀取/發佈權限。

+0

這就是我所做的。我認爲這是一個糟糕的設計,需要先閱讀授權,然後再發布。如果用戶想要在我的應用程序中將照片分享到Facebook,我寧願一口氣授權他們,而不是讓他們使用Facebook登錄我的應用程序,然後再請他們在共享照片時授權分享。 – jjxtra

+0

霍華德,謝謝你拯救我的一天 – John

2

而不是使用以下的:

NSArray *readPermissions = [[NSArray alloc]   initWithObjects:@"email",@"friends_location",@"status_update",@"publish_actions",nil]; 
[FBSession openActiveSessionWithPublishPermissions:readPermissions defaultAudience:FBSessionDefaultAudienceEveryone allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState state, NSError *error) { 
//Your code here for handling forward things; 
} 

使用此代碼:

NSArray *readPermissions = [[NSArray alloc] initWithObjects:@"email",@"friends_location",@"status_update",@"publish_actions",nil]; 
FBSession* sess = [[FBSession alloc] initWithPermissions:[NSArray arrayWithObject:readPermissions]]; 
[FBSession setActiveSession:sess]; 
[sess openWithBehavior:(FBSessionLoginBehaviorWithFallbackToWebView) completionHandler:^(FBSession *session, FBSessionState status, NSError *error) { 
    [self onSessionStateChange:session 
         andState:status 
         andError:error]; 

//Your code here for handling forward things; 

}];