在使用 SLRequest 发布 Facebook 帖子时,主要有两件事会导致问题: 1. 用户在 Facebook 上删除应用程序的权限。这会导致错误 2500,这意味着您必须“重新安装”应用程序并重新获得权限。2. 令牌已过期。您所要做的就是更新凭据。
我的问题主要是第一个。我已经能够处理更新凭据,但是在尝试“renewbigtime”(我喜欢如何称呼它)或重新安装应用程序并再次获得权限时遇到了很多困难。
这是我的 facebook 发布代码的布局(请参阅评论以了解我为什么这样做):
首先,用户必须在设置视图控制器中打开 facebook 共享:
-(void)facebookpost {
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType * facebookAccountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSArray *accounts = [accountStore accountsWithAccountType:facebookAccountType];
//why two permissions and dictionaries? Well, before you can post to Facebook, you have to get basic read permissions, such as email. If you attempt to obtain both of these permissions, you will fail. So, the app tries for permission of email first, if it succeeds, it tries for permission for publish_stream.
NSArray * permissions = @[@"email"];
NSArray * permissions2 = @[@"publish_stream"];
NSDictionary * dict = @{ACFacebookAppIdKey : @"289006474446717", ACFacebookPermissionsKey : permissions, ACFacebookAudienceKey : ACFacebookAudienceFriends};
NSDictionary * dict2 = @{ACFacebookAppIdKey : @"289006474446717", ACFacebookPermissionsKey : permissions2, ACFacebookAudienceKey : ACFacebookAudienceFriends};
[accountStore requestAccessToAccountsWithType:facebookAccountType options:dict completion:^(BOOL granted, NSError *error) {
if (granted && error == nil) {
//the following defaults just sets a key value which will be checked to see if the app should try and post anything
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"facebook"];
[[NSUserDefaults standardUserDefaults] synchronize];
//nothing gets posted yet, onto try for permissions to post
[accountStore requestAccessToAccountsWithType:facebookAccountType options:dict2 completion:^(BOOL granted, NSError *error) {
if(granted && error == nil) {
//good, it is now granted permission for both reading and writing
} else {
NSLog(@"1error is: %@",[error description]);
}
}];
} else {
NSLog(@"error is: %@",error );
if(error.code == 6){
//this is the error message that will appear if the user has not signed into Facebook from Settings app. alertmessage simply pops up an alert instructing them to please do so.
[self performSelectorOnMainThread:@selector(alertmessage)
withObject:nil
waitUntilDone:YES]; }
}
}];
}
现在,我们进入发布代码。此代码位于表视图的详细视图控制器中。表格视图列出了文章,单击其中一个使用 webView 在详细视图中显示它。在 viewWillAppear 中,应用程序检查 'facebook' 键的布尔值。如果它是 NO,它只会显示文章。如果是,它会尝试发布到墙上(再次查看评论以获取解释):
-(void)writetowall {
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSArray *accounts = [accountStore accountsWithAccountType:accountType];
ACAccount *account = [accounts lastObject];
NSDictionary *parameters = @{@"message" : [NSString stringWithFormat:@"I'm reading %@ from the blog. Click the link to read it too.", _entry.articleTitle], @"link": _entry.articleUrl};
NSURL *URL = [NSURL URLWithString:@"https://graph.facebook.com/me/feed"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodPOST
URL:URL
parameters:parameters];
[request setAccount:account];
[request performRequestWithHandler:^(NSData *responseData,
NSHTTPURLResponse *urlResponse, NSError *error) {
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData
options:kNilOptions
error:&error];
NSDictionary *errorDictionary = [responseDictionary valueForKey:@"error"];
if (errorDictionary) {
NSNumber *errorCode = [errorDictionary valueForKey:@"code"];
if ([errorCode isEqualToNumber:[NSNumber numberWithInt:190]]) {
//190 is code that you need to renew credentials. this is when tokens expire. so, if it happens, it goes to renew code (not included in this question as it is working fine)
NSLog(@"Renew");
[self renew];
}
if ([errorCode isEqualToNumber:[NSNumber numberWithInt:2500]]) {
//here is the 2500 code meaning the app has not been installed yet, or needs to be installed again with new permissions. so, I have it run the method renewbigtime which I will now list below
[self renewbigtime];
}
}
}];
}
好的,所以用户去Facebook AppCenter,点击应用旁边的X,现在当他们尝试发布时,它给了他们错误代码2500,所以它触发了这个方法,这个方法非常类似于授予initial的initial方法权限:
-(void)renewbigtime {
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType * facebookAccountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSArray *accounts = [accountStore accountsWithAccountType:facebookAccountType];
NSArray * permissions = @[@"email"];
NSArray * permissions2 = @[@"publish_stream"];
NSDictionary * dict = @{ACFacebookAppIdKey : @"289006474446717", ACFacebookPermissionsKey : permissions, ACFacebookAudienceKey : ACFacebookAudienceFriends};
NSDictionary * dict2 = @{ACFacebookAppIdKey : @"289006474446717", ACFacebookPermissionsKey : permissions2, ACFacebookAudienceKey : ACFacebookAudienceFriends};
[accountStore requestAccessToAccountsWithType:facebookAccountType options:dict completion:^(BOOL granted, NSError *error) {
if (granted && error == nil) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"facebook"];
[[NSUserDefaults standardUserDefaults] synchronize];
[accountStore requestAccessToAccountsWithType:facebookAccountType options:dict2 completion:^(BOOL granted, NSError *error) {
if(granted && error == nil) {
//here is where it should be granted and no errors for anything, so we redirect to writetowall method which should simply post to the wall
[self writetowall];
} else {
NSLog(@"1error is: %@",[error description]);
}
}];
} else {
NSLog(@"error is: %@",error );
if([[error description] isEqualToString:@"Error Domain=com.apple.accounts Code=6 \"The operation couldn’t be completed. (com.apple.accounts error 6.)\""]){
[self performSelectorOnMainThread:@selector(alertmessage)
withObject:nil
waitUntilDone:YES]; }
}
}];
}
问题是应用程序此时陷入了循环。如果收到错误 2500,它会尝试更新凭据,但会继续出现错误 2500,尝试更新,2500,尝试更新。renewbigtime 部分没有触发其他错误消息,那我做错了什么?