尝试使用 Twitter 帐户时的奇怪行为

Posted

技术标签:

【中文标题】尝试使用 Twitter 帐户时的奇怪行为【英文标题】:Strange behaviour when trying to use Twitter ACAccount 【发布时间】:2012-11-12 18:16:16 【问题描述】:

我一直在使用新的 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 是在不应该发布的时候发布的,但我想检查你们中的任何人是否可以看到我的代码有什么问题导致它和/或找到问题的解释,我无法自己解决。

谢谢

更新

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

【问题讨论】:

【参考方案1】:

在通过以下两种方式检索到的帐户上使用 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;

【讨论】:

您好,感谢您的回答。我已经得出了这个结论,显式设置 accountType 似乎保留了 ACAccountType 对象。 (因为它确实将其打印到 NSLog)。我将进一步调查该主题,看看发生了什么。 哇,2 分钟就解决了。我工作了几个小时的东西。谢谢。 这看起来有点像 hack;您应该首先尝试以下解决方案(即保留帐户存储。) 正如其他解决方案所说,您需要保留 Account Store 对象(ACAccountStore)。【参考方案2】:

您必须保留 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 发布之后,一切都可以正常工作。

【讨论】:

这是真正的修复,而不是尝试接受答案中建议的修复。【参考方案3】:

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

【讨论】:

【参考方案4】:

我使用此代码没有问题。 (仅限推特)

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: API requests with TWRequest

【讨论】:

您好,感谢您的回复。绝对不是,如果是这样的话,这更像是 accountType 的问题。我已经在运行你的代码,但是你仔细阅读了我的问题,问题是这段代码在单例中运行,这可能是我的问题

以上是关于尝试使用 Twitter 帐户时的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

使用npm twit将图像上传到Twitter时“媒体类型无法识别”

通过Twit w / Node.js发布Twitter线程

如何使用 Twit NPM 包获取 Twitter 用户名和头像

尝试使用 tcc 针对 gcc 生成的 .o 文件编译源时的奇怪行为

发送广播消息时的奇怪行为

在 SwiftUI 视图中的 TextField 后面使用多个 SecureField 时的奇怪行为