Подтвердить что ты не робот

Странное поведение при попытке использовать Twitter ACAccount

Я немного играл с новой 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, в которых я храню соответствующую учетную запись при извлечении из хранилища учетных записей.

Проблема возникла, когда позже я попытался использовать такие объекты (я просто отправлю твиттер-метод для краткости):

        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]);
            }];
        }

При вызове setAccount: в postRequest я получал исключение с сообщением: "Недопустимый тип учетной записи для этого запроса", что было явно ложным. Я также попытался отладить код, и, как ни странно, тип accountType на _twitterAccount был установлен равным нулю перед отправкой в ​​объект ACAccount. Более странно, если я поставлю

NSLog(@"%@",_twitterAccount);

прямо под

_twitterAccount = [arrayOfAccounts lastObject]

в первом разделе кода, он работает без проблем.

Я просмотрел свой код, и я не думаю, что я делаю что-то неправильно, так что я думаю, что это может быть ошибкой в ​​фреймворке? Похоже, что ACAccountType выпускается, когда он не должен, но я хотел проверить, не видел ли кто-нибудь из вас что-то не так с моим кодом, который провоцировал его, и/или нашел объяснение проблемы, что я не могу решить самостоятельно.

Спасибо

UPDATE

Кажется, у некоторых других людей такая же проблема, я принимаю один из ответов, потому что он действительно решает проблему, но я буду с нетерпением ждать любого, кто найдет объяснение проблемы.

4b9b3361

Ответ 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;

Ответ 2

Вы должны сохранить ACAccountStore:

@property (nonatomic, strong) ACAccountStore *accountStore;

В документации ACAccount никогда не указано, что вы должны сохранить ACAccountStore, но он утверждает, что

"Чтобы создать и получить учетные записи из базы данных учетных записей, вы должны создайте объект ACAccountStore. Каждый объект ACAccount принадлежит к единственный объект ACAccountStore."

Когда вы вызываете:

NSArray *accounts = [accountStore accountsWithAccountType:accountType]

Эти объекты accountStore в массиве необязательно имеют все свои свойства, полученные из базы данных. Некоторые свойства (например, тип accountType) извлекаются только из базы данных учетных записей, если это необходимо. Это вызвало странное поведение, которое вы видели при регистрации учетной записи и все, что было волшебным образом. Когда вы регистрировали учетную запись, объект ACAccountStore все еще находился в памяти, и журнал вызвал поиск свойства AccountType. В этот момент AccountType был сохранен с помощью ACAccount, и все было возможно работать позже даже после выхода ACAccountStore.

Ответ 3

Сохраняете ли вы хранилище ACAccountStore, которое вы использовали для получения arraryOfAccounts?

Ответ 4

Я использую этот код без проблем. (Только для Twitter)

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 с TWRequest