iphone - guide - Comportamiento extraño al tratar de usar Twitter ACAccount
swift ios documentation (4)
¿Está reteniendo el ACAccountStore que usó para obtener arraryOfAccounts?
He estado jugando un poco con el nuevo Social.Framework y, en particular, con SLRequest, ambos disponibles en iOS 6 y versiones posteriores. Lo cierto es que me sorprendió mucho un choque que he tenido al intentar publicar dicha solicitud.
He estado teniendo problemas tanto con las cuentas de Facebook como con las de Twitter, por eso sabía que no estaba relacionado con ningún problema en particular con una de ellas. Tenía que estar relacionado con el objeto ACAccount, que estoy obteniendo de esta manera:
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];
}
}
}];
}
}];
}
}
}
Tanto _twitterAccount como _fbAccount son objetos ACAccount en los que almaceno la cuenta relevante cuando se recupera del Almacén de cuentas.
El problema surgió cuando más tarde intenté usar esos objetos (solo publicaré el método de Twitter por brevedad):
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]);
}];
}
Al llamar a setAccount: en postRequest recibí una excepción con el mensaje: "Tipo de cuenta no válido para esta solicitud", que obviamente era falso. También intenté depurar el código y, extrañamente, el tipo de cuenta en _twitterAccount se estableció en cero justo antes de ser enviado al objeto ACAccount. Más extraño, si lo pongo
NSLog(@"%@",_twitterAccount);
justo debajo
_twitterAccount = [arrayOfAccounts lastObject]
En la primera sección del código, funciona sin problemas.
He revisado mi código y no creo que esté haciendo nada mal por lo que creo que puede ser un error en el marco. Parece que ACAccountType se está publicando cuando no debería, pero quería comprobar si alguno de ustedes pudo ver algo incorrecto en mi código que lo provocaba y / o encontrar una explicación para el problema, que no puedo ver. resolver por mi mismo.
Gracias
ACTUALIZAR
Parece que otras personas tienen el mismo problema, estoy aceptando una de las respuestas porque realmente resuelve el problema, pero estaré esperando a cualquiera que pueda encontrar una explicación para el problema.
También estaba obteniendo "Tipo de cuenta no válido para esta solicitud" cuando utilizaba SLRequest en cuentas recuperadas a través de los dos siguientes
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 en la cuenta tenía todo poblado como se esperaba, pero el tipo se estableció como nulo. Adivinar esto es un error con el SDK de Apple. Al hacer lo siguiente, me arreglé las cuentas para poder usarlas con SLRequest:
ACAccountType *account_type_twitter = [account_store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
account.accountType = account_type_twitter;
Tienes que conservar ACAccountStore:
@property (nonatomic, strong) ACAccountStore *accountStore;
La documentación de ACAccount nunca establece específicamente que debe conservar ACAccountStore, pero sí establece que
"Para crear y recuperar cuentas de la base de datos de Cuentas, debe crear un objeto ACAccountStore. Cada objeto ACAccount pertenece a un solo objeto ACAccountStore".
Cuando usted llama:
NSArray *accounts = [accountStore accountsWithAccountType:accountType]
Los objetos accountStore en la matriz no necesariamente tienen todas sus propiedades recuperadas de la base de datos. Algunas propiedades (como accountType) solo se recuperan de la base de datos de Cuentas si es necesario. Esto causó el extraño comportamiento que vio cuando inició sesión en la cuenta y todo funcionó mágicamente. Cuando inició sesión en la cuenta, el objeto ACAccountStore todavía estaba en la memoria y el registro provocó la recuperación de la propiedad AccountType. En ese momento, AccountType se conservó con ACAccount y todo fue capaz de funcionar más tarde, incluso después de la publicación de ACAccountStore.
Utilizo este código sin problema. (Twitter solamente)
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];
}
}
}];
¿Pienso algo sobre el problema de inicio de cuenta?
La referencia oficial de Twitter está aquí. Twitter: solicitudes de API con TWRequest