Twitter iOS Streaming API: данные не принимаются

Я пытаюсь изменить пример кода Apple для использования Twitter API, чтобы я мог использовать потоковый API для фильтрации твитов. Я пытаюсь реализовать метод, предложенный в ответ на этот вопрос:

Работает ли TWRequest для потокового API в Твиттере?

Я создал подписанные объекты NSURLRequest и NSURLConnection, как было предложено, и установил делегат для объекта соединения. Действительная учетная запись Twitter выбирается и используется для подписи URL-адреса. Проблема в том, что метод подключения делегатов: didReceiveData: никогда не вызывается.

Вот мой код:

@implementation Twitter

-(id)init{
    if (self=[super init]) {
        NSLog(@"Twitter init");

        // Tell the notification centre to inform the app if the twitter account changes
        [[NSNotificationCenter defaultCenter] addObserver:self 
                                                 selector:@selector(twitterAccountChanged) 
                                                     name:ACAccountStoreDidChangeNotification object:nil];

        // Create an account store object.
        ACAccountStore *accountStore = [[ACAccountStore alloc] init];

        // Create an account type that ensures Twitter accounts are retrieved.
        ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];


        // Request access from the user to use their Twitter accounts.
        [accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
            if(granted) {
                NSLog(@"Twitter: Access to twitter accounts granted");

                // Get the list of Twitter accounts.
                NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];

                // Pick the twitter account to use
                if ([accountsArray count] > 0) {

                    // Grab the initial Twitter account to tweet from.
                    ACAccount *twitterAccount = [accountsArray objectAtIndex:0];

                    // This is for a status filter
                    NSURL *url=[NSURL URLWithString:@"https://stream.twitter.com/1/statuses/filter.json"];

                    // Create the parameters dictionary
                    NSDictionary *dictionary=[NSDictionary dictionaryWithObjectsAndKeys:@"twitter", @"track", nil];

                    // Create TWRequest object
                    TWRequest *req=[[TWRequest alloc] initWithURL:url parameters:dictionary requestMethod:TWRequestMethodPOST];

                    // Set the account
                    [req setAccount:twitterAccount];

                    // Get a signed URL request
                    NSURLRequest *signedRequest=[req signedURLRequest];

                    // Initate the connection
                    [NSURLConnection connectionWithRequest:signedRequest delegate:self];

                } else {
                    NSLog(@"Twitter: No twitter accounts to access");
                }

            } else {
                NSLog(@"Twitter: Access to twitter accounts denied");

            }
        }];

        return self;
    }
    return nil;
}

-(void)twitterAccountChanged{
    NSLog(@"Twitter twitterAccountChanged");
}


-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    NSLog(@"data received");
}

Вывод из программы:

2012-07-24 09:50:03.668 TwitterAPITest[36722:10403] Twitter init
2012-07-24 09:50:03.836 TwitterAPITest[36722:11d03] Twitter: Access to twitter accounts granted

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

Любая помощь приветствуется...

Майк


person Michael    schedule 23.07.2012    source источник
comment
После публикации я заставил это работать без использования объекта TWRequest. Вместо этого я использую объекты NSURLRequest/Connection, получаю JSON от потокового API и анализирую текст входящих твитов. Тем не менее, было бы неплохо узнать, получил ли кто-то потоковый API, работающий с TWRequest...   -  person Michael    schedule 24.07.2012
comment
Можете ли вы опубликовать код для этого? Спасибо.   -  person EvilPenguin    schedule 09.08.2012
comment
Проблема заключалась просто в том, что ваш NSURLConnection инициировался вне основного цикла выполнения, поэтому поток завершался до того, как мог быть вызван любой из ваших делегатов. Я разместил код ниже.   -  person wfbarksdale    schedule 19.09.2012


Ответы (1)


Мне потребовалось немного времени, чтобы настроить и запустить это, поэтому я подумал, что могу опубликовать свой код для других. В моем случае я пытался сделать твиты близкими к определенному местоположению, так что вы увидите, что я использовал параметр locations и структуру местоположения, которая у меня была в области видимости. Вы можете добавить любые параметры в словарь params.

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

Удачной трансляции!

//First, we need to obtain the account instance for the user's Twitter account
ACAccountStore *store = [[ACAccountStore alloc] init];
ACAccountType *twitterAccountType = [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];

//  Request permission from the user to access the available Twitter accounts
[store requestAccessToAccountsWithType:twitterAccountType
                 withCompletionHandler:^(BOOL granted, NSError *error) {
                     if (!granted) {
                         // The user rejected your request
                         NSLog(@"User rejected access to the account.");
                     }
                     else {
                         // Grab the available accounts
                         NSArray *twitterAccounts = [store accountsWithAccountType:twitterAccountType];
                         if ([twitterAccounts count] > 0) {
                             // Use the first account for simplicity
                             ACAccount *account = [twitterAccounts objectAtIndex:0];
                             NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
                             [params setObject:@"1" forKey:@"include_entities"];
                             [params setObject:location forKey:@"locations"];
                             [params setObject:@"true" forKey:@"stall_warnings"];
                             //set any other criteria to track
                             //params setObject:@"words, to, track" forKey@"track"];

                             //  The endpoint that we wish to call
                             NSURL *url = [NSURL URLWithString:@"https://stream.twitter.com/1.1/statuses/filter.json"];

                             //  Build the request with our parameter
                             TWRequest *request = [[TWRequest alloc] initWithURL:url
                                                                      parameters:params
                                                                   requestMethod:TWRequestMethodPOST];

                             // Attach the account object to this request
                             [request setAccount:account];
                             NSURLRequest *signedReq = request.signedURLRequest;

                             // make the connection, ensuring that it is made on the main runloop
                             self.twitterConnection = [[NSURLConnection alloc] initWithRequest:signedReq delegate:self startImmediately: NO];
                             [self.twitterConnection scheduleInRunLoop:[NSRunLoop mainRunLoop]
                                                   forMode:NSDefaultRunLoopMode];
                             [self.twitterConnection start];

                         } // if ([twitterAccounts count] > 0)
                     } // if (granted) 
                 }];
person wfbarksdale    schedule 18.09.2012
comment
@wbarksdale Я получаю ответ, поскольку требуется аутентификация. У вас есть идеи по этому поводу? Поскольку мы предоставляем доступ с помощью ACAccount, он должен работать. Любая помощь будет оценена. Спасибо. - person The iCoder; 25.01.2016