Teleporting a Kangaroo

scott sappenfield

Remember this guy? He’s our friendly kangaroo lying around in the sun.

Well, he’s bored sitting in isolation in my iPhone photo gallery and wants to go up to the web to be shared with everyone. I haven’t looked up the definition of teleportation, but I have to imagine there’s a sender and a receiver.  So in this case, he’s going to be teleported from my iPhone (that’s the transmission sender) all the way up to the world wide web (that’s the transmission receiver).

Disclaimer

No actual animals have been harmed for the purposes of this post. Sorry, that’s another lame attempt at humor. It’s tough for me to make the nuts and bolts of technical stuff entertaining, but I try.

The Nuts and Bolts

Let’s see what’s going on with the code ( I took some code out, moved some other code around and added some commentary just for simplicity and clarity.)  In my actual code, there are things you don’t need to concern yourself with.  For instance, I start spinning an animator.  While that’s useful, you don’t need those details here.

The Sender

My iPhone.  Let’s send it on up to the receiver.  This method is dispatched in a separate thread, so keep that in mind.  If you don’t do that, make sure you do an asynch request so as to not tie things up unnecessarily.

(void)uploadMyNewPictureToWeb {

        //your web service that's on the lookout for Mr. Kangaroo
        NSMutableString *customWebPage = [NSMutableString stringWithString:@"your web service URL would go here"];
        NSURL *aUrl = [NSURL URLWithString:customWebPage];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl];

        //this is your POST, PUT, whatever restful protocol you support
        [request setHTTPMethod:@"POST"];

        //set the content type
        //the spec calls for a unique string of characters as a separator, so use something random, but unique
        //also, I can't stress enough how important it is to get all the \r\n's correct
        NSString *boundary = @"DK39FJK4589FDKJSW893JKLR89DFJK238934IOSO";
        NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
        [request setValue:contentType forHTTPHeaderField:@"Content-Type"];

        //body
        NSMutableData *body = [NSMutableData data];

        //add all the textual params first (I'm going to assume you have some things to transmit other than just a photo
        //let's call them param1 and param2
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", @"param1"] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"%@\r\n", _param1] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", @"param2"] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"%@\r\n", _param2] dataUsingEncoding:NSUTF8StringEncoding]];

        //now add the image data, remember in the original post, I used a button, you could get this from local documents storage or wherever
        NSData *imageData = UIImagePNGRepresentation(_profilePictureButton.imageView.image);
        if (imageData) {
            [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
            [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"mrkangaroo.png\"\r\n", @"mrkangaroo"] dataUsingEncoding:NSUTF8StringEncoding]];
            [body appendData:[[NSString stringWithFormat:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
            [body appendData:[NSData dataWithData:imageData]];
            [body appendData:[[NSString stringWithFormat:@"%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        }
        [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

        //set the body to the request
        [request setHTTPBody:body];

        //set the content length
        NSString *postLength = [NSString stringWithFormat:@"%d", [body length]];
        [request setValue:postLength forHTTPHeaderField:@"Content-Length"];

        NSURLResponse *response;
        NSError *error;

        //send it and do something with the response...response parsing is left off here for simplicity
        NSData *myJSONNetworkData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

        //parsing response...
}

The Receiver

A web service keeping an eye out for Mr. Kangaroo.

You probably don’t need an example, but sometimes it helps to see how to handle things on the receiving end.  Whatever you use (ROR, PHP, JSP) on the receiving end will be able to easily parse this data.  SitterSat.com was written in ASP.Net/VB on the server-side, so here it is in that language. Again, I’ve removed a lot because you don’t need all that, just the relevant pieces.

//ASP.Net libraries have many useful collection for you, one being files in the request object
Dim fileCollection As HttpFileCollection = Request.Files

//Code works, but is simplified here for you, meaning you'll want more robust error handling and logging
For Each uploadedFileName In fileCollection
  Dim uploadedFile As HttpPostedFile = fileCollection(uploadedFileName)
  If Not uploadedFile Is Nothing Then
    If (uploadedFile.ContentLength > 0) Then
        //Save it somewhere on the server, whatever path conventions you have
        //also, this doesn't save it with a file extension, but you could that just the same
        uploadedFile.SaveAs(Server.MapPath("~/Pictures/mrkangaroo"))
    End If
  End If
Next

I hope this will help you out should you ever need to get into the business of transporting. Best of luck, let me know if I can help with anything.  You know, now that I’m thinking about it, I went to all this trouble, why didn’t I just tweet or FB him?  Oh well.

Advertisements
Leave a comment

2 Comments

  1. I am sure transporting will be both possible (lets face it, most of Star Trek’s tricks HAVE come true!) – and easier – but you could have just popped down here to Sydney, picked up a real Kanagroo, & flown back home with it in your luggage!! 🙂

    Reply
    • Hahaha, that is awesome! My wife would have been like, “let’s go” as she wants to visit so bad. Well, in the end, I agree with you, it’s probably true, just about everything else has come to fruition. Thanks for stopping by!

      Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: