I am working with the Twitter REST/Streaming APIs. When I want to access the REST API, I create a NSMutableURLRequest
(that contains parameters such as access tokens and queries). I then use the request in conjunction with NSURLSession
to load the data. I am using a library which creates the mutable request object for me (if I don't use the request object, then the Twitter API will not allow me to access the relevant user data).
Now I am trying to load a Twitter timeline via the streaming API. One problem I am having is that I can't figure out how to use my custom mutable request object, with a NSStream
object. The only thing I can do is to set the host
URL link. But that is not good enough because I need to pass the user OAuth data (that is included in the mutable request object), in order for the Twitter API to allow me access to the user data.
How can I attach a request object to the stream? Here is my code:
NSURL *website = [NSURL URLWithString:@"https://userstream.twitter.com/1.1/user.json"];
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)[website host], 80, &readStream, &writeStream);
NSInputStream *inputStream = (__bridge_transfer NSInputStream *)readStream;
NSOutputStream *outputStream = (__bridge_transfer NSOutputStream *)writeStream;
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
UPDATE
Due to changes in the Twitter API, the streaming API will no longer be available. I'll keep my answer here just in case anyone is still working with the streaming API, but the API won't be up for much longer. Instead you'll have to manually refresh the data you want every few seconds/minutes - how often you refresh the data is down to your user-base, the larger the user-base the longer the refresh intervals should be.
My solution
I managed to solve my problem. I tried many solutions from CFStream
to web socket libraries.... only to find out that the Twitter Streaming API doesn't support sockets..... great start!
I ended up using NSURLSession
and its associated delegate methods, to setup and load in the continuous stream of data, from the Twitter API. Works perfectly and is incredibly easy to setup:
Set the delegate in your header: <NSURLSessionDelegate>
request
in the below code is a NSURLRequest
object I created, that stores the Twitter stream URL, query parameters and the user OAuth
authentication header data.
Create the URL request/session objects:
// Set the stream session.
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
// Start the data stream.
[[session dataTaskWithRequest:request] resume];
Finally setup the delegate methods:
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
NSError *feedError = nil;
NSDictionary *feed = [NSJSONSerialization JSONObjectWithData:data options:0 error:&feedError];
NSLog(@"%@", feed);
}
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
if (error) {
NSLog(@"%@", error);
}
}
That's it! Now all you have to do is to parse the data returned in the feed
dictionary and update your UI accordingly.