How to host an HTTP + Web Services server in an iPhone with MonoTouch

September 8th, 2010 by mythz Leave a reply »

Yep the title of this post is correct! With a little hacking to get around MonoTouch Limitations I’ve managed to shoe-horn Service Stack’s HttpListener and host it inside of an iPhone with the help of MonoTouch. Basically, in not so many words I made this happen:

Basically the above is the result of hosting a web server on your iPhone making it possible to view your iPhone content with any web browser. In a addition to a static HTTP server there is also an Embedded version of Service Stack turning your iPhone into a Web Services server. This happens to be a pretty convenient way to get at your data. As a basic example I created a simple Web Service returning all the contacts in your iPhone Address book:

namespace EmbeddedServiceStack
{
	public class ContactsService : IService<Contacts>
	{
		//Singleton defined in AppHost, Injected by Funq IOC
		public ABAddressBook AddressBook { get; set; }

		public object Execute (Contacts request)
		{
			var response = new ContactsResponse();

			foreach(var person in AddressBook.GetPeople())
			{
				var emails = person.GetEmails().GetValues();
				response.Contacts.Add(new Contact {
					FirstName = person.FirstName,
					LastName = person.LastName,
					Email = emails.Length > 0 ? emails[0] : null,
				});
			}

			return response;
		}
	}
}

Which once you start the AppHost’s HttpListener lets you view your data using REST-ful  HTTP requests like so:

Some of you might be thinking WTF dude why the hell would you want to do this to an iPhone?? Actually I did for a while too! However in a recent thread on the mailing list Miguel De Icaza actually identified some useful use cases where this might be a good idea.

For one reason you can sprinkle a little JavaScript in your HTML page to display the list of Contacts below:

Which granted doesn’t look like much however this task is infinitely less tedious with JavaScript.

Having thought about for a little more I can think of a few more potential use-cases:

  • Giving you more flexibility to access and export your iPhone’s data without needing to use iTunes
  • Develop PhoneGap-like iPhone apps without PhoneGap :-)
  • Use a full-featured desktop browser to view your iPhone data rather than it’s constrained mobile interface
  • Access your iPhone from over the Internet (allowing async callback duplex requests)
  • Provide easy 2-way communication between iPhone Apps

Other potential use-cases heard on the tweet vine:

  • Mobile device management (Landesk like) and Software testing (@itdnext)

Developer Notes

How the Web Server works?

Basically any url with a Web Service prefix is interpreted as a Web Service and delegated to Service Stack to process.

http://localhost:8080/Xml/
http://localhost:8080/Json/
http://localhost:8080/Jsv/

All other urls are treated like a standard HTTP GET request where it looks for a matching file in the Projects www/ resource directory and simply copies it to the Response Output Stream. Requests that ends with a ‘/’ (i.e. a directory path)  are treated like ‘/default.html’

Note: In order to have your static files packaged and deployed with your application you need to set the ‘Build Action’ to ‘Content’ for each file.
Also if you don’t see any contacts you need to use the Contact App in the iPhone simulator and add some in yourself.

MonoTouch Quirks

Since I found the JsonDataContractSerializer in Mono to be unreliable I’ve had to write and included my own Json Serializer whose heavily reliance on generics requires some extra attention when running in an No JIT environment like MonoTouch. Basically we have to tell the MonoTouch compiler what concrete generic classes to generate – which we do by Registering all DTO’s like so:

private void RegisterDtoTypes_RequiredWhenTheresNoJit()
{
	Register.Type<Hello>();
	Register.Type<HelloResponse>();
	Register.Type<Contacts>();
	Register.Type<ContactsResponse>();
	Register.Type<Contact>();
}

Download the Example project

For those interested, the above sample project and all the Embedded ServiceStack libraries required to build your own iPhone HTTP+Webservices solution is available at:

http://servicestack.googlecode.com/files/MonoTouch-EmbeddedServiceStack.zip

Since I only have the trial version of MonoTouch I have only been able to verify that this works in the iPhone Simulator. So if anyone with the full version of MonoTouch gets this running on an iOS device – can you let me know. Feel free to file any issues you run into at the projects website: http://code.google.com/p/servicestack/issues/list

Happy Hacking!

Further Reading

A tutorial showing you how to create and call web services from MonoTouch is available here:
http://www.servicestack.net/monotouch/remote-info/

Advertisement

Leave a Reply