我正在使用Facebook集成的社交框架Facebook &。爲此我跟着這link 一切工作正常,除非我的應用程序收到ACAccountStoreDidChangeNotification,它崩潰。 應用程序崩潰時在iOS 6+中處理Facebook和Twitter的ACAccountStoreDidChangeNotification
1)我第一次安裝應用程序&用戶沒有在設置中配置Facebook/Twitter帳戶。
2)當我打電話給Facebook/Twitter的任何方法時,它給了我錯誤代碼6,因爲我沒有帳戶配置,這是正確的。
3)我點擊HOME按鈕,所以我的應用程序進入背景&在Settigs中添加帳戶。
4)一旦我配置了賬戶&回到應用程序,我的應用程序從後臺啓動&收到ACAccountStoreDidChangeNotification。
5)在ACAccountStoreDidChangeNotification的選擇器中,我的帳戶對象爲零,所以我的應用程序崩潰。所以,我檢查了零
這裏是我的代碼
#pragma mark - Request Facebook Account Access
-(void)requestFacebookAccountAccess
{
requestType = kNoOpRequest;
// Register for Account Change notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(accountChanged:) name:ACAccountStoreDidChangeNotification object:nil];
self.accountStore = [[ACAccountStore alloc]init];
ACAccountType *FBaccountType= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
// Set facebook permissions
NSArray *permissions = nil;
// We need to ask for Basic permission first
if (![kUserDefaults boolForKey:FACEBOOK_BASIC_PERMISSION]) {
permissions = @[@"email",@"user_about_me",@"user_location",@"friends_about_me"];
self.isBasicFacebookPermissionsRequested = YES;
}
else {
permissions = @[@"email",@"user_about_me",@"user_location",@"friends_about_me",@"publish_stream"];
}
//use ACAccountStore to help create your dictionary
NSDictionary *dictFacebook = @{
ACFacebookAppIdKey: kFacebookAppIDKey,
ACFacebookPermissionsKey: permissions,
ACFacebookAudienceKey: ACFacebookAudienceFriends
};
[self.accountStore requestAccessToAccountsWithType:FBaccountType options:dictFacebook completion:^(BOOL granted, NSError *error) {
if (granted) {
if (self.isBasicFacebookPermissionsRequested) {
self.isBasicFacebookPermissionsRequested = NO;
[kUserDefaults saveBasicFacebookPermissionsGrantedStatus:YES];
//[self requestFacebookAccountAccess];
}
// User granted permission to Accout
NSArray *accountsArray = [self.accountStore accountsWithAccountType:FBaccountType];
if ([accountsArray count]>0) {
//It will always be the last object with SSO
self.facebookAccount = [accountsArray lastObject];
NSLog(@"In %s::IS MAIN THREAD:- %@",__PRETTY_FUNCTION__,[NSThread isMainThread][email protected]"YES":@"NO");
if ([self.delegate respondsToSelector:@selector(didFacebookAccountAccessGranted)]) {
dispatch_async(dispatch_get_main_queue(),^{
[self.delegate didFacebookAccountAccessGranted];
});
}
}
else {
[self showAlertWithTitle:@"Error" andMessage:@"You don't have any Facebook accounts set up yet.Please set a Facebbok account and try again."];
}
}
else {
DLog(@"User denied permission to Accout::Localized Error:- %@",error.localizedDescription);
if([error code]==6) {
[self showAlertWithTitle:@"Error" andMessage:@"Please setup facebook account from Settings"];
if ([self.delegate respondsToSelector:@selector(didFacebookAccountAccessDenied:)]) {
dispatch_async(dispatch_get_main_queue(),^{
[self.delegate didFacebookAccountAccessDenied:error];
});
}
}
else if ([self.delegate respondsToSelector:@selector(didFacebookAccountAccessDenied:)]) {
dispatch_async(dispatch_get_main_queue(),^{
[self.delegate didFacebookAccountAccessDenied:error];
});
}
else {
// User denied permission to Account
[self showAlertWithTitle:@"Error" andMessage:[NSString stringWithFormat:@"User denied permission to Accout::Error:- %@",error.localizedDescription]];
}
}
}];
}
#pragma mark - Get Logged In User Info
-(void)getLoggedInUserInfo
{
NSURL *requestURL = [NSURL URLWithString:@"https://graph.facebook.com/fql"];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"SELECT current_location,uid,name,sex,birthday,email,pic FROM user WHERE uid=me()",@"q", nil];
requestType = kGetLoggedInUserInfoRequest;
[self requestDataUsingURL:requestURL parameters:dict requestMethod:SLRequestMethodGET];
}
#pragma mark - Request Data From Facebook
-(void)requestDataUsingURL:(NSURL*)requestURL parameters:(NSDictionary*)params requestMethod:(SLRequestMethod)reuqestMethod
{
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:reuqestMethod
URL:requestURL
parameters:params];
request.account = self.facebookAccount;
[request performRequestWithHandler:^(NSData *data,
NSHTTPURLResponse *response,
NSError *error)
{
NSDictionary *dictData =[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if(!error)
{
if([dictData objectForKey:@"error"]!=nil)
{
DLog(@"Request Data From Facebook Errro:- %@",dictData);
[self attemptRenewCredentials];
if ([self.delegate respondsToSelector:@selector(didGetFacebookError:)]) {
dispatch_async(dispatch_get_main_queue(),^{
[self.delegate didGetFacebookError:dictData];
});
}
}
else {
// Process the response
//NSLog(@"Response Dictionary contains: %@", dictData);
if ([self.delegate respondsToSelector:@selector(didPostToFacebook:)]) {
dispatch_async(dispatch_get_main_queue(),^{
[self.delegate didPostToFacebook:dictData];
});
}
}
}
else{
if ([self.delegate respondsToSelector:@selector(didGetFacebookError:)]) {
dispatch_async(dispatch_get_main_queue(),^{
[self.delegate didGetFacebookError:dictData];
});
}
else {
[self showAlertWithTitle:@"Error" andMessage:@"Some error occured while processing Facebook request"];
}
}
}];
}
-(void)accountChanged:(NSNotification *)notif
{
if (self.facebookAccount!=nil) {
[self attemptRenewCredentials];
}
else {
[self requestFacebookAccountAccess];
}
}
#pragma mark - Attempt to Renew Credentials
-(void)attemptRenewCredentials
{
[self.accountStore renewCredentialsForAccount:(ACAccount *)self.facebookAccount completion:^(ACAccountCredentialRenewResult renewResult, NSError *error){
if(!error)
{
switch (renewResult) {
case ACAccountCredentialRenewResultRenewed:
NSLog(@"Good to go");
[self againRequestFacebook];
break;
case ACAccountCredentialRenewResultRejected:
NSLog(@"User declined permission");
break;
case ACAccountCredentialRenewResultFailed:
NSLog(@"non-user-initiated cancel, you may attempt to retry");
break;
default:
break;
}
}
else{
//handle error gracefully
NSLog(@"error from renew credentials%@",error);
}
}];
}
-(void)againRequestFacebook
{
switch (requestType) {
case kGetLoggedInUserInfoRequest:
[self getLoggedInUserInfo];
break;
case kGetFriendsInfoRequest:
[self getFacebookFriendsInfo];
break;
case kPostToWallRequest:
[self postToFacebookWallInBackgroundForUserId:fbUserIdForPost withParams:paramsToPost];
break;
default:
break;
}
}
#pragma mark - Remove Observer for Notification
-(void)dealloc
{
requestType = kNoOpRequest;
[[NSNotificationCenter defaultCenter] removeObserver:ACAccountStoreDidChangeNotification];
}
但accountChanged方法被調用多次。 這有什麼問題?我該如何處理這種情況? 高度讚賞任何形式的幫助。
在此先感謝。
感謝您的回覆。如果用戶每天更改帳戶,我們應該怎麼做?我們應該在哪裏重置calledAccountChanged? – iOSAppDev 2013-02-25 11:27:58
' - (void)accountChanged:(NSNotification *)notif'這個方法只會在facebook賬戶被更改並且應用程序在後臺時被調用。如果關閉應用程序,更改FB帳戶並再次打開應用程序,通知將無法工作。所做的就是將FB UID存儲在** NSUserDefaults **中,當應用程序打開時,檢查存儲的FB UID是否與當前的一致。如果它不匹配change'calledAccountChanged'。 – 2013-02-25 15:04:07
感謝您的回覆。我會試試這個,讓你知道。 – iOSAppDev 2013-02-27 07:49:04