All Things Mobile

The Latest News & Knowledge

Using the Disqus API with Objective C

OBJECTIVE



Provide an Objective C example of implementing the Disqus API.



BACKGROUND



Recently Rade | Eccles developed a blog reader app for a website which uses Disqus as a commenting platform. We had a requirement to allow users to post comments from the app directly to the website’s Disqus sytem.



What is Disqus? (http://www.disqus.com)




“Disqus (dis·cuss • dĭ-skŭs’) is all about changing the way people think about discussion on the web. We’re big believers in the conversations and communities that form on blogs and other sites. Disqus Comments is for bloggers and publishers who wish to use Disqus on their sites, while Disqus Profile is for the rest of us who are commenting on sites powered by Disqus.”



Disqus provides some online API documentation; however, it is language agnostic. The Disqus API documentation can be found here: http://wiki.disqus.net/API



DISQUS API INTRO



There are three types of Disqus objects that this API provides access to: forums, threads, and posts. A post is any comment written by a Disqus user. Each post belongs to a thread, which represents a particular topic of conversation. Each thread belongs to a forum. A forum represents a website that is using Disqus. For example, your blog might constitute a single forum, and each blog post would have its own thread.



The API is executed over HTTP using the http://disqus.com/api/(method_name)/ endpoint. Some methods are a GET request and some are a POST. All responses are returned using JSON.



IMPLEMENTATION



To speed up the development process we will leverage two publicly available frameworks used by many other developers. You will need to download both frameworks and integrate them into your project before proceeding.



ASIHTTPRequest – An excellent, easy to use wrapper around the CFNetwork API that makes some of the more tedious aspects of communicating with web servers easier. It is written in Objective-C and works in both Mac OS X and iPhone applications. You can download the code and view the documentation here: http://allseeing-i.com/ASIHTTPRequest/
JSON Framework – This framework implements a strict JSON parser and generator in Objective-C. You can download the code and view the documentation here: http://code.google.com/p/json-framework/
To post a comment to Disqus we need to use the “create_post” API at the http://disqus.com/api/create_post/ endpoint. This method is an HTTP POST and requires the following parameters:



Thread ID


Message


Author Name


Author Email


The message, author name, and author email will come from our app but we need to ask Disqus what the correct thread ID is before we can successfully post a comment.



Our process flow is as follows:



User enters a comment, provides a user name and email address, and presses a “Submit” button
Request the thread ID from Disqus based on the URL of the thread using the “get_thread_by_url” method (GET)
Parse the JSON response to access the thread ID
POST the comment using the “create_post” method
STEP 1



For step one we will assume an AddCommentViewController.m exists in our project and the following three headers have been imported:




1. #import "ASIFormDataRequest.h"


2. #import "ASIHTTPRequest.h"


3. #import "SBJSON.h"



There should also be some instance variables for a user name, email address, the comment text itself, and a submit button.



STEP 2



After the user presses the submit button we want to construct our call to “get_thread_by_url”. This method requires two parameters: the forum key and the URL of the thread in which to post a comment. A forum key can be shared among trusted moderators of a forum, and is used to perform actions associated with that forum. The creator of a forum (an administrator or website owner) can get the forum’s key through the API (see below). The API documentation provides instructions on how the administrator can obtain the forum key if necessary.


- (IBAction)submit {


NSString *DisqusForumKey = [[NSUserDefaults standardUserDefaults] objectForKey:self.feed.forumKey];



NSString *urlString = [[[NSString alloc] initWithString:@"http://disqus.com/api/get_thread_by_url/"] autorelease];


urlString = [urlString stringByAppendingFormat:@"?api_version=1.1&url=%@&forum_api_key=%@", blogPostURL, DisqusForumKey];
NSURL *url = [[NSURL alloc] initWithString:urlString];



ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];


[request setDelegate:self];


[request setDidFinishSelector:@selector(requestDidFinishForThreadID:)];


[request startAsynchronous];


}




Let’s take a closer look at the code above. In line two we are setting a variable which contains the forum key for the current thread. You may or not be able to simply hard code the forum key into your code. In our case we were dealing with multiple distinct and separate forums (databases) each with their own set of threads.



In line four we construct a string with our method endpoint.



In line five we add to that string an optional api version parameter, the URL of the thread, and the forum key.



In line six we construct an NSURL object from our new URL string.



In line eight we construct an ASIHTTPRequest object using our NSURL object.



In line nine we set the delegate to self so we can handle the callback when a response is received.



In line 10 we need to specify a custom callback method because we will be handling two different types of JSON responses in our view controller since we are making two different API calls. If we didn’t specify a custom didFinishSelector the default callback method would be - (void)requestFinished:(ASIHTTPRequest *)request. Here we will set requestDidFinishForThreadID as our desired callback.



Finally in line eleven we kick off the asynchronous HTTP request.



STEP 3



Now we need to parse the thread ID out of the JSON response in our custom callback method. All responses are JSON objects with three fields:



succeeded: Indicates whether the call completed successfully or encountered an error.


code: “ok” if succeeded, otherwise an short description of the error that occurred.


message: The body of the response, which will depend on the method being used. In case of error, contains a longer description of the error that occurred.



- (void)requestDidFinishForThreadID:(ASIHTTPRequest *)request {


NSString *responseString = [request responseString];


SBJSON *jsonParser = [SBJSON new];


NSDictionary *dict = (NSDictionary*)[jsonParser objectWithString:responseString];


[jsonParser release];

// get thread id


NSDictionary *messageDictionary = (NSDictionary *)[dict objectForKey:@"message"];


NSString *threadID = (NSString *)[messageDictionary objectForKey:@"id"];

}



In line two we extract the response string from the HTTP request.



In line three we create a JSON Parser.



In line four we use the JSON parser to return a dictionary of parameters.



In line eight we get a dictionary from the “message” field of the JSON response. The call to the “get_thread_by_url” method returns a thread object in the message field. This object has several parameters which are documented in the Disqus API; however, we are only interested in the ID parameter.



In line ten we retrieve the actual thread ID for the specified URL from the message dictionary.



STEP 4



After we have parsed the thread ID we are ready to construct the call to the “create_post” method to submit the comment to the Disqus database. Add the code below to the requestDidFinishForThreadID method so it looks like this:

- (void)requestDidFinishForThreadID:(ASIHTTPRequest *)request {


// Use when fetching text data NSString *responseString = [request responseString];

SBJSON *jsonParser = [SBJSON new];


NSDictionary *dict = (NSDictionary*)[jsonParser objectWithString:responseString];


[jsonParser release];

// get thread by url results


NSDictionary *messageDictionary = (NSDictionary *)[dict objectForKey:@"message"];


NSString *threadID = (NSString *)[messageDictionary objectForKey:@"id"];

// assemble the POST data


NSString *DisqusForumKey = [[NSUserDefaults standardUserDefaults] objectForKey:self.feed.forumKey];

NSURL *url = [[NSURL alloc] initWithString:@" "target="_blank">http://disqus.com/api/create_post/"];


ASIFormDataRequest *requestPostComment = [ASIFormDataRequest requestWithURL:url];


[requestPostComment setPostValue:@"1.1" forKey:@"api_version"];


[requestPostComment setPostValue:threadID forKey:@"thread_id"];


[requestPostComment setPostValue:userName.text forKey:@"author_name"];


[requestPostComment setPostValue:userEmail.text forKey:@"author_email"];


[requestPostComment setPostValue:userComment.text forKey:@"message"];


[requestPostComment setPostValue:DisqusForumKey forKey:@"forum_api_key"];


[requestPostComment setDelegate:self];


[requestPostComment startAsynchronous];

}


Lines 14 and 16 should be familiar as we are getting the forum key and constructing the POST for the “create_post” method.



In line 17, this time we will use ASIFormDataRequest which is used to make an HTTP POST.



In lines 18-23 we set the required parameters for this method call.



Next, we set the delegate to self to receive the response in the callback method. In this case, since we didn’t specify a didFinishSelector the default requestFinished method will be called. Here we could check for errors/failures an issue an appropriate message to the user if necessary.



Finally we kick off the asynchronous HTTP POST.



SOLUTION



At this point as long as the forum keys and the thread URL is correct you should have posted a comment successfully in Disqus.



LINK SUMMARY



Disqus – http://www.disqus.com



Disqus API – http://wiki.disqus.net/API



ASIHTTPRequest – http://allseeing-i.com/ASIHTTPRequest/



JSON Framework – http://code.google.com/p/json-framework/

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>