19

我一直在使用新的 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 对象,当我从 Account Store 检索时,我将相关帐户存储在其中。

后来我尝试使用此类对象时出现了问题(为简洁起见,我将发布 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 是在不应该发布的时候发布的,但我想检查你们中的任何人是否可以看到我的代码有什么问题导致它和/或找到问题的解释,我无法自己解决。

谢谢

更新

似乎其他一些人也有同样的问题,我接受其中一个答案,因为它实际上解决了这个问题,但我期待任何能找到该问题解释的人。

4

4 回答 4

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;
于 2012-11-22T07:16:01.737 回答
17

您必须保留 ACAccountStore:

@property (nonatomic, strong) ACAccountStore *accountStore;

ACAccount 文档从未明确声明您必须保留 ACAccountStore,但它确实声明了

“要从 Accounts 数据库创建和检索帐户,您必须创建一个 ACAccountStore 对象。每个 ACAccount 对象都属于一个 ACAccountStore 对象。”

你打电话时:

NSArray *accounts = [accountStore accountsWithAccountType:accountType]

数组中的那些 accountStore 对象不一定具有从数据库中获取的所有属性。某些属性(如 accountType)仅在需要时从 Accounts 数据库中检索。这导致了您在登录帐户时看到的奇怪行为,并且一切都神奇地起作用了。当您记录帐户时,ACAccountStore 对象仍在内存中,并且记录导致检索 AccountType 属性。那时,AccountType 保留在 ACAccount 中,即使在 ACAccountStore 发布之后,一切都可以正常工作。

于 2013-01-11T20:15:16.577 回答
5

您是否保留了用于获取 arraryOfAccounts 的 ACAccountStore?

于 2012-11-17T06:47:05.890 回答
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 初始化问题的事情?

Twitter 的官方参考资料在这里。 Twitter:使用 TWRequest 的 API 请求

于 2012-11-14T20:42:30.860 回答