How to Send a Protobuf from iPhone Client to Server

After linking the protocol buffer static library into the XCode project, we can finally use it! If you recall from the generating Objective-C classes from protocol buffer post, we had a StoryRequest that takes two character names and an object to be sent to the server, and the server will send back a StoryResponse using the information supplied.

To refresh your memory,
This is a StoryRequest:

message StoryRequest {
	required string character1 = 1;
	required string character2 = 2;
	optional string secret_weapon = 3;
}

And this is StoryResponse:

message StoryResponse {
	enum ResponseType {
		SUCCESS = 0;
		FAILED = 1;
	}
	required ResponseType status = 1;
	optional string story = 2;
}

So you will have four files to include into your XCode project:
StoryRequest.pb.h, StoryRequest.pb.m, StoryResponse.pb.h, and StoryResponse.pb.m

I created three UITextFields to get user input for the character names and the object. The variables are named character1Field, character2Field and secretWeaponField. And finally, here is how to use the protobuf.

To build a protobuf, you use a _builder. In this case, you want to build a StoryRequest, so you will be using a StoryRequest_builder. Both of these classes were already generated. You can find them in StoryRequest.pb.h and StoryRequest.pb.m. You first create a StoryRequest_Builder, fill it with all the necessary info, and then use it to actually build a StoryRequest.

//StoryRequest builder
StoryRequest_Builder* newStoryRequestBuilder = [[StoryRequest_Builder alloc] init];
[newStoryRequestBuilder setCharacter1:self.character1Field.text];
[newStoryRequestBuilder setCharacter2:self.character2Field.text];
[newStoryRequestBuilder setSecretWeapon:self.secretWeaponField.text];
 
//build StoryRequest to be sent to server
StoryRequest* newStoryRequest = [newStoryRequestBuilder build];		//newStoryRequestBuilder is invalid from this point onward, do not use again

Now that you have a StoryRequest, it’s time to send it over to the server. You will need to have a URL for the server side script (STORY_URL that I defined elsewhere in code) and the serialized StoryRequest data. And then you use those to build an NSURLRequest.

NSURL* url = [NSURL URLWithString:STORY_URL];
NSMutableURLRequest* theRequest = [NSMutableURLRequest requestWithURL:url];
[theRequest setHTTPMethod:@"POST"];
[theRequest setHTTPBody:[self.storyRequest data]];
[theRequest setValue:@"application/x-protobuf" forHTTPHeaderField:@"Content-Type"];

Notice a few things:
1) The HTTP method should be POST, so that we can set raw bytes to the HTTP body.
2) You use the “data” method to turn the StoryRequest into an NSData, and then just attach that as the HTTP body. Of course there are other ways to do it if you want to send other information along with the protobuf, but in this case that’s all we want to send.
3) Set your content type to application/x-protobuf. You can probably set it to other types that send byte streams (as long as it’s not text), but hey, if we have one specifically defined for protobuf, there’s no reason not to use it.

But we are not done. All we have now is an NSURLRequest. It’s simply a request. It represents what you intend to do, but you haven’t actually establish a connection yet. To do that, we create an NSURLConnection like so:

NSURLConnection* theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];
self.mHTTPConnection = theConnection;
[theConnection release];

At this point, a connection will be established. And everything goes as planned, your protobuf is now sent to the server side!

Next time… hm, I haven’t decided yet. We’ll either talk about how the server side generates a response or how the client side will use it. For now, enjoy the sense of satisfaction from knowing that you’ve sent the request out without thinking about whatever happened to it!

This entry was posted in Protobuf. Bookmark the permalink.

7 Responses to How to Send a Protobuf from iPhone Client to Server

  1. CDF says:

    Thank you very much for your hard work 🙂

  2. Kelvin Kao says:

    🙂

  3. Hoang Le says:

    Hi Kelvin!
    that is really, really helpful for me.
    Can you continue follow this entry?
    Thanks a lot, Kelvin.

  4. Kelvin Kao says:

    Yeah. I just submitted another app to Apple last Friday (four days ago) so I have more time on my hand now. Will write a few more posts.

  5. Hoang Le says:

    That is a good news, congratulations!.
    I have a trouble when combine ZeroMQ and ProtocolBuffer to send and receive data to server.

  6. Hoang Le says:

    Can you explain more details about the serialize and deserialize data on Objective-C. That’s really hard to understand for me.

  7. Kelvin Kao says:

    Serializing is as simple as calling the data method on the Protobuf object. You saw this as
    [self.storyRequest data]
    in the code. The library we’ve included takes care of the serialization for you.

    I’ll talk about deserialization in another post.

Leave a Reply

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