Archive for the ‘Research’ Category
Using POST data to “phone home”
One problem that many developers face when developing a new application, for any platform, is how to communicate with their application in the wild. The most common method used is to “phone home” periodically to check for updates, send log files, report illegal use, and perform other reporting tasks. Some of these “phone home” uses have tainted the practice though, because users are not comfortable with the idea of applications farming their data (and not knowing what data in particular is being farmed). That being said, almost every application still does this in some way, to varying degrees.
I do it too. I will continue doing it, and I hope my customers will appreciate it. I will report ethically, and will tell them what data I will be reporting in my terms of service.
Specifically, I will use a phone home mechanism for three purposes:
1.) send added content back to me, so others can use it too (if the user gives permission)
2.) retrieve new content that others have added
3.) send messages to application users
For now, I will focus on the first of these, where content created by a user is “phoned home” so that others may benefit from the newly created content. There is always an option to turn this off, and I always respect this preference.
Now for implementation. We could do this by making our application create an outbound TCP connection to our server on a certain known port, serialize our data, and send it home. Our server would then listen on that same port, accept the connection, deserialize the data, process it and store it. For most projects however, we do not have our own servers nor do we have the time to write a scalable, robust server just for this purpose. What then can we use?
For my purposes, using a POST to my webserver works great. I already have a webserver running my website for the project, it already knows how to accept POST calls, it already has a database to store my information, and it is much more robust than a TCP connection server which I would have the time to write. I don’t need to function test the low level server application logic, because Apache (or whatever you use) is pretty stable and works as expected.
As for the data itself, I can encrypt, hash, or obscure the data in any way that I wish, and can add checksums, and other verification data to ensure that the post is coming from my application. On the webserver side, I can use the same (reverse) algorithm to decode and parse the data. I can even return error codes from my POST call so my application knows whether it succeeded in sending the data or whether it needs to remember it and send it the next time.
A sample implementation similar to one I am using in VocabViewer for iPhone looks like this:
- (void)sendHTTPPost:(NSString*)pContent withName:(NSString*)username
{
//creating the url request:
// You must replace this with your url
NSURL *cgiUrl = [NSURL URLWithString:@"http://www.yoururl.com/handlePost.php"];
NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:cgiUrl];
//adding header information:
[postRequest setHTTPMethod:@"POST"];
NSString *stringBoundary = [NSString stringWithString:@"0xkhTMLbOUNDARY"];
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary];
[postRequest addValue:contentType forHTTPHeaderField: @"Content-Type"];
//setting up the body:
NSMutableData *postBody = [NSMutableData data];
// USERNAME
[postBody appendData:[[NSString stringWithFormat:@"--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"username\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithString:username] dataUsingEncoding:NSUTF8StringEncoding]];
// COUNT
[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"count\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:@"%d", [pContent length]] dataUsingEncoding:NSUTF8StringEncoding]];
// CONTENT
[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"content\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithString:pContent] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postRequest setHTTPBody:postBody];
//sending the request via a NSURLConnection:
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:postRequest delegate:self];
if (theConnection)
{
m_receivedPostData=[[NSMutableData data] retain];
}
else
{
// inform the user that the download could not be made
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[m_receivedPostData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// do something with the data
NSLog(@"Succeeded! Received %d bytes of data",[m_receivedPostData length]);
NSString * result = [[NSString alloc] initWithData:m_receivedPostData encoding: NSUTF8StringEncoding];
NSLog(@"Recieved result: %@", result);
[result release];
// release the connection, and the data object
[connection release];
[m_receivedPostData release];
m_receivedPostData = nil;
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
// release the connection, and the data object
[connection release];
// m_receivedPostData is declared as a method instance elsewhere
[m_receivedPostData release];
// inform the user
NSLog(@"Connection failed! Error - %@ %@", [error localizedDescription], [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
}
I hope this helps someone get their application up and running a bit faster. Good Luck!
Mark McElhinney
You are currently browsing the archives for the Research category.