SLRequest and /statuses/filter.json


#1

Hi,

I followed the instructions for integrating SLRequest with the Streaming API, using the following code:

//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 options:nil completion:^(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) {
      ACAccount *account = [twitterAccounts lastObject];
      NSURL* url = [NSURL URLWithString:@"https://stream.twitter.com/1.1/statuses/filter.json"];
      NSDictionary *params = @{@"track":@"Twitter"};
         
      SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:url parameters:params];
      [request setAccount:account];
      [request performRequestWithHandler: ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
         if (responseData) {
            if (urlResponse.statusCode >= 200 && urlResponse.statusCode < 300) {
               NSError *jsonError;
               NSDictionary *timelineData = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:&jsonError];
               if (timelineData) {
                  NSLog(@"Timeline Response: %@\n", timelineData);
               }
               else {
                  // Our JSON deserialization went awry
                  NSLog(@"JSON Error: %@", [jsonError localizedDescription]);
               }
            }
         else {
            // The server did not respond ... were we rate-limited?
            NSLog(@"The response status code is %d",urlResponse.statusCode);
         }
      }
   }];
} // if ([twitterAccounts count] > 0)
} // if (granted) 
}];

However the callbackHandler for the request is never called. What I’m wrong?


#2

I found that streaming api follow a different behaviour. Since the response is not “atomic”, instead the response is progressively populated as new data coming, you should use a different behaviour within your code.

I used the following approach:

  1. use the standard SLRequest to populate a request with the correct OAuth
  2. use a standard NSURLConnection with delegate to observe new data coming from the streaming endpoint
  • (void)startStreamingWithKeyword:(NSString *)aKeyword
    {
    //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
    options:nil
    completion:^(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) {
    ACAccount *account = [twitterAccounts lastObject];

                                          NSURL *url = [NSURL URLWithString:@"https://stream.twitter.com/1.1/statuses/filter.json"];
                                          NSDictionary *params = @{@"track" : aKeyword};
                                          
                                          SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter
                                                                                  requestMethod:SLRequestMethodPOST
                                                                                            URL:url
                                                                                     parameters:params];
                                          
                                          [request setAccount:account];
                                          dispatch_async(dispatch_get_main_queue(), ^{
                                              NSURLConnection *aConn = [NSURLConnection connectionWithRequest:[request preparedURLRequest] delegate:self];
                                              [aConn start];
                                          });
                                      } // if ([twitterAccounts count] > 0)
                                  } // if (granted) 
                              }];
    

}

  • (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@“dataString: %@”, dataString);
    }