使用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'键的bool值。如果它是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,所以它触发了这个方法,这与初始方法非常相似授予初始权限:
-(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部分没有触发其他错误消息,所以我做错了什么?