2012-10-10 24 views
6

Ich aktualisiere eine App, um das neueste Facebook SDK zu verwenden, um Zugriff auf die iOS6 native Facebook-Unterstützung zu erhalten. Es verwendet derzeit eine ziemlich alte Version des Facebook SDK.Fehler bei der Verwendung von [FBSession openActiveSessionWithPublishPermissions: ..]

Die App benötigt die "publish_actions" -Erlaubnis von Facebook für das einzige, was es mit Facebook macht.

Ich dachte ursprünglich, ich könnte [FBSession openActiveSessionWithPublishPermissions: ...] verwenden, aber das scheitert an iOS6, wenn der Benutzer Facebook in iOS6-Einstellungen konfiguriert hat. Es schlägt fehl, weil diese Anforderung from the Facebook docs:

Hinweis, iOS 6 nativen Auth zu verwenden, Apps müssen, um die Art, wie sie Berechtigungen von den Benutzern verlangen ändern - Anwendungen müssen ihre Anträge getrennt für und Schreibberechtigungen lesen. Das Facebook SDK für iOS unterstützt diese -Funktionen und hilft Entwicklern beim Erstellen von Apps, die unter mehreren iOS-Versionen und Gerätekonfigurationen funktionieren.

Dies ist eine große PITA, IMO. Unsere Präferenz wäre, den Benutzer einmal um Erlaubnis zu bitten und damit fertig zu werden, aber das "neue" Ideal pro Apple/Facebook besteht darin, spezifische Berechtigungen im Kontext anzufordern, wenn sie benötigt werden, aber noch nicht gewährt werden.

Der Plan im Moment besteht darin, unser altes Verhalten für iOS5-Benutzer und iOS6-Benutzer beizubehalten, bei denen Facebook nicht in den Einstellungen konfiguriert wurde. Und konform mit der neuen doppelten Eingabeaufforderung für iOS6-Benutzer, die nativen Zugriff verwenden.

Die Frage ist, was ist der beste Weg, dies zu tun? Wie soll ich herausfinden, ob das Facebook SDK den iOS6 nativen Login gegen die Fallback-Mechanismen auswählt? Betrachte ich etwas Offensichtliches?

EDIT:

gerraldWilliam setzte mich auf dem richtigen Weg. Seine Lösung würde fast funktionieren, außer dass ACAccountTypeIdentifierFacebook in iOS5 nicht verfügbar ist. Wenn der Benutzer den FB-Zugriff in den Einstellungen für die App blockiert, gibt der Aufruf accountsWithAccountType außerdem ein leeres Array zurück.

Es ist möglich, um das erste Problem zu erhalten, indem für den Kontotyp passenden Kennung „com.apple.facebook“ zu fragen - das Null auf iOS5 zurückkehren, und ein echten Kontotyp Objekt auf iOS6.

Aber das zweite Problem ist unlösbar. Mein neuer Plan ist, die erste Sitzung auf iOS6 immer mit schreibgeschützten Berechtigungen zu öffnen und später, im Kontext, die Berechtigung zum Veröffentlichen bei Bedarf einzugeben. Unter iOS5 öffne ich immer noch die erste Sitzung mit der gewünschten publish_actions-Berechtigung. Hier ist der Code:

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

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

Antwort

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

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

wenn Konten null ist (oder vielleicht gibt es ein leeres Array, ich bin mir nicht sicher), dann hat der Benutzer nicht in Facebook iOS6 konfiguriert. Sie können dies testen und wenn der Wert anzeigt, dass Facebook nicht für iOS6 konfiguriert wurde, können Sie Ihren Fallback-Mechanismus aufrufen.

+0

Diese fast funktioniert. Zwei Probleme sind 1) ACAccountTypeIdentifierFacebook ist auf iOS5 nicht verfügbar und 2) accountsWithAccountType gibt ein leeres Array zurück, wenn der Benutzer den FB in den Einstellungen konfiguriert hat, aber den Zugriff auf die aufrufende App blockiert hat. Kennzeichnung als die richtige Antwort, da sie mich auf den Weg zu meiner ultimativen Lösung brachte, die ich in die Frage stellen werde. – TomSwift

+0

'accountsWithAccountType' gibt ein leeres Array für mich zurück, auch wenn ich in iOS 6 bin, wurde die Facebook-Integration konfiguriert und es ist möglich zu posten. – jowie

+0

Auch ist für mich leer, und bekommt diesen nervigen Fehler com.facebook.sdk Fehler 2 ... Irgendwelche Tipps? – D33pN16h7

0

Sorry, aber für mich in iOS6 die Linie

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

kehrt nicht null, selbst wenn der Benutzer nicht über ein Konto konfiguriert ...

Was bedeutet, können Sie einfach überprüfen, was die ios Version des Benutzers (5 oder 6)

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

This link hilfreich sein können.

6

Basierend auf allem, was ich auf den Facebook-Entwickler-Websites gelesen habe (was etwas widersprüchlich ist) ist der Workflow einer "nur veröffentlichen" -App nicht etwas, an das sie viel gedacht haben, und Apple/iOS scheint ignoriert zu haben insgesamt.

Facebook bietet einige Hinweise in der docs you referenced:

Tipp 5: Deaktivieren der nativen Anmeldung Dialog

In einigen Fällen Apps können die native Anmeldedialog deaktivieren neue Versionen der Facebook zu nutzen SDK, aber um zu vermeiden, die Art, wie sie Berechtigungen von Benutzern anfordern. Um das vorherige Verhalten von "fast-app-switch" für die Anmeldung zu verwenden, verwenden Sie die veralteten FBSession-Methoden "openActiveSessionWithPermissions" und "reauthorizeWithPermissions".

Dies ist die Route, die ich gerade befolge. Etwas anders, aber gleicher allgemeiner Effekt.

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]; 
    }]; 

Das Ergebnis ist, umgehen die App immer die iOS6 Integration zur Veröffentlichung über die Unterzeichnung und in den meisten Fällen (da die Benutzer in der Regel bereits am Telefon Facebook installiert haben) Umschaltung auf die Facebook-App für ein einzelnes Autorisierung

Wenn der Benutzer sich über sein Facebook-Konto bei unserer App anmeldet, rufe ich openActiveSessionWithReadPermissions an, die die IOS6-Facebook-Integration verwenden wird, falls vorhanden. Wenn sie sich dann entscheiden, zu teilen, rufe ich dann reauthorizeWithPublishPermissions an, die auch die IOS6-Integration verwenden wird, wenn sie verfügbar ist.

Angesichts der minimalen und verwirrenden Dokumentation kann ich nicht sicher sein, ob dies der "richtige" Weg ist, dies zu erreichen, aber es scheint zu funktionieren. Sie können denselben Code für eine IOS5- oder IOS6-App verwenden, da er nur über das Facebook SDK aufruft. Es ehrt auch das Nicht-Mischen von Lese-/Veröffentlichungsberechtigungen in derselben Anfrage, die Facebook jetzt promotet.

+0

Das mache ich auch. Ich denke, es ist ein schlechtes Design, eine Leseautorisierung zu verlangen und später zu veröffentlichen.Wenn ein Nutzer ein Foto in meiner App mit Facebook teilen möchte, möchte ich alle Nutzer lieber auf einmal autorisieren, anstatt sie per Facebook zur Anmeldung in meiner App aufzufordern, und sie dann erneut zur Freigabe der Freigabe auffordern, wenn sie ein Foto teilen möchten. – jjxtra

+0

Howard, Danke für die Rettung meines Tages – John

2

Statt mit folgenden:

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; 
} 

Mit diesem Code:

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; 

}]; 
Verwandte Themen