我一直在使用新的Social.Framework,特别是SLRequest,它们都可以在iOS 6及更高版本上使用。事实上,我对尝试发布此类请求时遇到的崩溃感到非常惊讶。
我一直在Facebook和Twitter帐户崩溃,这就是为什么我知道它与其中一个特定问题无关。它必须与ACAccount对象相关,我以这种方式得到它:
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {
//iOS 6
if (_twitterEnabled) {
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) {
//Set up account
[accountStore requestAccessToAccountsWithType:accountTypeTwitter options:nil completion:^(BOOL granted, NSError *error) {
if (granted && !error) {
//Get account and get ready to post.
NSArray *arrayOfAccounts = [accountStore accountsWithAccountType:accountTypeTwitter];
if ([arrayOfAccounts count] > 0) {
_twitterAccount = [arrayOfAccounts lastObject];
}
}
}];
}
}
if (!_facebookEnabled) {
ACAccountType *accountTypeFacebook = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
NSArray *permissions = @[@"user_about_me",@"user_likes",@"email"];
NSMutableDictionary *options = [NSMutableDictionary dictionaryWithObjectsAndKeys:kFacebookAppIDString, ACFacebookAppIdKey, permissions, ACFacebookPermissionsKey, ACFacebookAudienceFriends, ACFacebookAudienceKey, nil];
[accountStore requestAccessToAccountsWithType:accountTypeFacebook options:options completion:^(BOOL granted, NSError *error) {
if (granted && !error) {
[options setObject:@[@"publish_stream",@"publish_actions"] forKey:ACFacebookPermissionsKey];
[accountStore requestAccessToAccountsWithType:accountTypeFacebook options:options completion:^(BOOL granted, NSError *error) {
if (granted && !error) {
NSArray *arrayOfAccounts = [accountStore accountsWithAccountType:accountTypeFacebook];
if ([arrayOfAccounts count] > 0) {
_fbAccount = [arrayOfAccounts lastObject];
}
}
}];
}
}];
}
}
}
_twitterAccount和_fbAccount都是ACAccount对象,我从帐户存储区检索时存储相关帐户。
问题来自于后来我尝试使用这些对象(为了简洁起见,我将发布twitter方法):
NSDictionary *twitterMsg = @{@"status" : message};
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {
SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:kTwitterUpdateStatusURL parameters:twitterMsg];
[postRequest setAccount:_twitterAccount];
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSLog(@"Twitter HTTP response: %d", [urlResponse statusCode]);
}];
}
在postRequest上调用setAccount时,我收到一条例外消息:“此请求的帐户类型无效”,这显然是错误的。我也尝试调试代码,奇怪的是_twitterAccount上的accountType在发送到ACAccount对象之前设置为nil。更奇怪的是,如果我把
NSLog(@"%@",_twitterAccount);
正好在
之下_twitterAccount = [arrayOfAccounts lastObject]
在代码的第一部分,它没有问题。
我已经查看了我的代码,我认为我没有做错什么,所以我认为它可能是框架上的错误?看起来ACAccountType正在发布它不应该发布,但是我想检查一下你是否有人发现我的代码有什么问题引起了它并且/或找到问题的解释,我无法我自己解决。
谢谢
更新
似乎其他一些人也有同样的问题,我接受其中一个答案,因为它实际上解决了这个问题,但我会期待任何可以找到问题解释的人。
答案 0 :(得分:31)
当对通过以下两种方式检索到的帐户使用SLRequest时,我也收到“此请求的帐号类型无效”
ACAccountStore *account_store = [[ACAccountStore alloc] init];
ACAccountType *account_type_twitter = [account_store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
// A.
NSArray *accounts = [account_store accountsWithAccountType:account_type_twitter];
// B.
NSString *account_id = @"id from doing account.identifier on one of the above";
ACAccount *account = [account_store accountWithIdentifier:account_id];
帐户上的NSLog已按预期填充所有内容,但类型设置为null。猜猜这是Apple的SDK的一个错误。执行以下操作为我修复了帐户,以便我可以将它们与SLRequest一起使用:
ACAccountType *account_type_twitter = [account_store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
account.accountType = account_type_twitter;
答案 1 :(得分:17)
您必须保留ACAccountStore:
@property (nonatomic, strong) ACAccountStore *accountStore;
ACAccount文档从未明确说明您必须保留ACAccountStore,但它确实说明了
“要从Accounts数据库创建和检索帐户,您必须 创建一个ACAccountStore对象。每个ACAccount对象属于一个 单个ACAccountStore对象。“
致电时:
NSArray *accounts = [accountStore accountsWithAccountType:accountType]
数组中的那些accountStore对象不一定要从数据库中获取所有属性。如果需要,仅从Accounts数据库中检索某些属性(如accountType)。这导致您在登录帐户时看到的奇怪行为,并且一切都神奇地起作用。记录帐户时,ACAccountStore对象仍在内存中,日志记录导致检索AccountType属性。此时,AccountType与ACAccount一起保留,即使在ACAccountStore发布后,一切都能够工作。
答案 2 :(得分:5)
您是否保留了用于获取arraryOfAccounts的ACAccountStore?
答案 3 :(得分:1)
我没有问题地使用这段代码。 (仅推特)
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) {
if (!granted) {
NSLog(@"Access denied.");
}
else {
NSArray *accounts = [accountStore accountsWithAccountType:accountType];
if (accounts.count > 0) {
twitterAccount = [accounts objectAtIndex:0];
}
}
}];
我认为有关accountStore init问题的内容吗?
Twitter的官方参考在这里。 Twitter: API requests with TWRequest