![](/img/trans.png)
[英]posting status on facebook from ios app using facebook 3.1 SDK
[英]Facebook SDK 3.1 iOS: Handle login if user remove app from Facebook Settings
我想在我的应用程序中添加一些Facebook集成。 在这一点上,我已经成功登录,发布到朋友墙,检索朋友列表等。除了一件事之外,其他一切都还可以。
如果用户从您的Facebook设置/应用程序中删除了该应用程序 ,然后输入iOS应用程序,则该代码无法识别该Facebook应用程序已从用户设置中删除,并假定已登录(这是因为如果用户尝试将其发布到朋友的墙上,则该应用不执行任何操作)。
然后,用户关闭iOS应用并重新启动...通过重新启动,iOS应用“已修复”并检测到用户不再登录。
为了将登录流程带给用户,我无法设法检测到用户从设置中删除Facebook应用之后的那一刻...
这是我的代码:
在我的应用的第一个场景中...
if([FBSession activeSession].state == FBSessionStateCreatedTokenLoaded)
{
NSLog(@"Logged in to Facebook");
[self openFacebookSession];
UIAlertView *alertDialog;
alertDialog = [[UIAlertView alloc] initWithTitle:@"Facebook" message:@"You're already logged in to Facebook" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[alertDialog show];
[alertDialog release];
return YES;
}
else{
NSLog(@"Not logged in to Facebook"); //Show the login flow
return NO;
}
这是openFacebookSession的代码
-(void)openFacebookSession
{
NSArray *permissions = [[NSArray alloc] initWithObjects:
@"publish_stream",
nil];
[FBSession openActiveSessionWithPublishPermissions:permissions defaultAudience:FBSessionDefaultAudienceFriends allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
[self sessionStateChanged:session state:status error:error];
}];
}
sessionStateChanged的代码...
-(void)sessionStateChanged:(FBSession *)session state:(FBSessionState)state error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen: {
NSLog(@"Session opened");
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[FBSession.activeSession closeAndClearTokenInformation];
break;
default:
break;
}
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:@"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
}
}
非常感谢你!
我也发现这也发生在我自己身上。...是在用户更改了Facebook密码后才发现的,我们无法再进行身份验证。 手动重新同步/清除帐户会话可以使他们再次登录。
-(void)syncFacebookAccount
{
[self forceLogout];
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountTypeFB = [accountStore accountTypeWithAccountTypeIdentifier:@"com.apple.facebook"];
if (accountStore && accountTypeFB) {
NSArray *fbAccounts = [accountStore accountsWithAccountType:accountTypeFB];
id account;
if (fbAccounts && [fbAccounts count] > 0 && (account = [fbAccounts objectAtIndex:0])) {
[accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
// Not actually using the completion handler...
}];
}
}
}
实际上,解析和检测这些类型的错误非常困难,原因有两个:
FBRequest
传递的NSError
对象很难以任何功能方式解析和使用。 下面是我写的一个疯狂方法,实际上是为了吸引一个通宵人员而写的。 它处理来自失败的FBRequest
尝试的NSError *error
对象,并将其传递给相关方法,或者显示我可以找到的最明智的错误(或触及所有错误)。
请注意注释-特别是关于innerError
和parsedResponse
的注释-详细说明了到目前为止我发现的内容。 祝你好运,勇敢的士兵:
- (void)handleFacebookError:(NSError *)error
withPermissionType:(RMFacebookPermissionsType)type // this is just a typedef enum specifying Write or Read permissions so I can react accordingly
withCompletion:(void (^)(BOOL retry))completionBlock {
newMethodDebugLog;
NSParameterAssert(error);
NSParameterAssert(type);
NSParameterAssert(completionBlock); // the completion block tells the controller whether the error is 'fatal' or can be recovered - if YES, it can be recovered
// this is the parsed result of the graph call; some errors can appear here, too, sadly
NSDictionary *parsedResponse = [error.userInfo objectForKey:@"com.facebook.sdk:ParsedJSONResponseKey"];
int parsedErrorCode = [[[[parsedResponse objectForKey:@"body"]
objectForKey:@"error"]
objectForKey:@"code"]
intValue];
// this is an instance of NSError created by Facebook; it contains details about the error
NSError *innerError = [error.userInfo objectForKey:@"com.facebook.sdk:ErrorInnerErrorKey"];
// innerError is usually un-recoverable
if (innerError) {
// innerError seems to be the response given in true HTTP problems;
DebugLog(@"______innerError FOUND______");
DebugLog(@"innerError: %@",innerError);
DebugLog(@"innerError.code: %d",innerError.code);
// digging deep enough, you can actually find a coherent error message! :D
DebugLog(@"innerError.localizedDescription: %@",innerError.localizedDescription);
if (![alert isVisible]) {
NSString *errorString = @"Facebook Connection Failed";
NSString *okString = @"OK";
alert = [[UIAlertView alloc] initWithTitle:errorString
message:innerError.localizedDescription
delegate:nil
cancelButtonTitle:okString
otherButtonTitles:nil];
[alert show];
} else {
DebugLog(@"Alert already showing!");
}
completionBlock(NO);
} else if (parsedResponse &&
parsedErrorCode != 2) { // I honestly forget what error 2 is.. documentation fail :(
// parsedResponses can usually be recovered
DebugLog(@"parsed response values: %@",[parsedResponse allValues]);
switch (parsedErrorCode) {
case 2500:
case 200:
case 190:
{
DebugLog(@"parsedError code hit! forcing re-login.");
// all errors in case 190 seem to be OAuth issues
// http://fbdevwiki.com/wiki/Error_codes#Parameter_Errors
// if needed, "error_subcode" 458 == user has de-authorized your app
// case 2500 reported while grabbing from a photo album & not logged in
// case 200 "requires extended permission: publish_actions"
if (type == RMFacebookPermissionsTypeRead) {
[self _getFacebookReadPermissionsWithUI:YES
completion:completionBlock];
} else if (type == RMFacebookPermissionsTypeWrite) {
[self _getFacebookWritePermissionsWithUI:YES
completion:completionBlock];
}
break;
}
default:
completionBlock(YES);
break;
}
} else {
if (![alert isVisible]) {
NSString *errorString = @"Facebook Error";
NSString *messageString = @"Mixture Photos was unable to connect to Facebook on your behalf. This is usually a temporary problem. Please try again later.";
NSString *okString = @"OK";
alert = [[UIAlertView alloc] initWithTitle:errorString
message:messageString
delegate:nil
cancelButtonTitle:okString
otherButtonTitles:nil];
[alert show];
} else {
DebugLog(@"Alert already showing!");
}
completionBlock(NO);
}
}
我有同样的问题,在Facebook SDK网站上找不到有关错误代码的正确文档。
我通过比较[error code];
解决了问题[error code];
或[error userInfo];
值。
您的会话将具有状态FBSessionStateClosedLoginFailed
并且userInfo错误字典将具有以下形式
"com.facebook.sdk:ErrorLoginFailedReason" = "com.facebook.sdk:ErrorLoginFailedReason";
另一方面,错误代码向我显示2
以便您可以在sessionStateChanged :::函数的末尾进行处理
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState)state
error:(NSError *)error {
switch (state) {
case FBSessionStateOpen: {
//update permissionsArrat
[self retrieveUSerPermissions];
if (!needstoReopenOldSession) {
//First User information
[self getUserInformation:nil];
}
NSNotification *authorizationNotification = [NSNotification notificationWithName:facebookAuthorizationNotification object:nil];
[[NSNotificationCenter defaultCenter] postNotification:authorizationNotification];
}
case FBSessionStateClosed: {
break;
}
case FBSessionStateClosedLoginFailed: {
[FBSession.activeSession closeAndClearTokenInformation];
break;
}
default:
break;
}
if (error)
{
NSNotification *authorizationNotification = [NSNotification notificationWithName:faceBookErrorOccuredNotification object:error];
[[NSNotificationCenter defaultCenter] postNotification:authorizationNotification];
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.