Simple way to embed a http server into your iPhone app

Posted by face on June 15, 2009

Announcing MongooseDaemon, an objective-c wrapper for the wonderful mongoose http server.

It can be indispensable to be able to explore your iPhone apps directory structure when developing and debugging iPhone applications. You may also want to serve up content from your iPhone application via http.

Erica Sadun’s cookbook has an example of a hand rolled http server. However, it is only an example and is incomplete. I recently needed a http server in an iPhone app and after playing with Erica’s example I quickly realized I didn’t want to be in the business of creating a complete http server.

So I started looking for an existing http server I could embed in my app. I quickly found moongoose.

With just a few minutes of coding, I was able to get mongoose working in my iPhone application. To make it even easier for the next developer, I extracted my wrapper into the MongooseDaemon class and am offering it under a BSD license.

Here is some example code taken directly from one of my apps I am debugging:

Add the following to one of your projects classes .h (MyAppDelegate.h for this example):
1
2
3
4
5
6
7
8
9
  #import "MongooseDaemon.h"
  ....
  @class MongooseDaemon

  @interface MyAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
    ...
    MongooseDaemon    *mongooseDaemon;
    ...
  }
And add the following to the class ( MyAppDelegate.m for this example):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  ...
  @implementation LightyAppDelegate
  ...
  - (void)applicationDidFinishLaunching:(UIApplication *)application {
  mongooseDaemon = [[MongooseDaemon alloc] init];
  [mongooseDaemon startMongooseDaemon:@"8080"];

  ...
  - (void)dealloc {
  ...
    [mongooseDaemon stopMongooseDaemon];
    [mongooseDaemon release];
  ...
  }

Now you can surf to your application. For example, if your iPhones IP on wifi is 192.168.1.100 (sorry a helper method for determining your iPhones IP will be coming soon), then you could surf to http://192.168.1.100:8080/

Serve files in good health!


Digg! Delicious! Technorati Blinklist Furl Reddit

Announcing ratos: A shell to Decode iPhone Stack Traces

Posted by face on February 06, 2009

I’m pleased to give you ratos, a shell to speed iPhone development by decoding an entire stack trace at once using atos. Of course as it relies on atos, so it only works on a Mac with Xcode installed.


 [301] tako:~>  ratos

App Name:TheSnapper
App Path:/Users/face/proj/TheSnapper

Paste xcode stack trace to stdin, then type 'sim' or 'arm' on a line by itself.
  Type 'exit' or '^D' to quit and 'app' to print the current app.

ratos>2009-02-05 10:21:31.107 TheSnapper[751:20b] Stack: (
    808221155,
    806100816,
    808224973,
    807957033,
    807851552,
    25785,
    22599,
    22855,
    807923363,

arm

-[BackViewController doubleSnapAction:] (in TheSnapper) (BackViewController.m:192)
-[BackViewController resetAllSiders] (in TheSnapper) (BackViewController.m:126)
-[BackViewController resetSnap:] (in TheSnapper) (BackViewController.m:138)


When I first learned iPhone development it took me a while to find atos. Exception handling comes natural but Xcode spits out addresses in their stack traces. After much googling I finally found atos. I then immediately found Apple’s docs to integrate atos into an exception handler. Cool….NOT!

Turns out Apple’s Xcode integration relies on /usr/bin/atos at runtime….not possible on my iPhone.

So, I immediately wrote a quick and dirty shell in Ruby that takes a stack trace in from xcode, and prints out any lines that have symbols. Gobbledygook in, nice human readable stack trace out!

After enjoying ratos for the past few months I finally had a chance today to clean it up a little and publish it on github.

To use it, first install it on your path.:
git clone git://github.com/face/ratos.git
sudo cp ratos/bin/ratos /usr/local/bin/.
There are a couple environment variables that can be used to configure ratos. Also, if ratos happens to be installed in a project under the directory bin it will self configure. If your application name and directory name are the same and ratos is installed in a shared location like /usr/local/bin, you only need to set RATOS_APP_PATH:
# csh
setenv RATOS_APP_PATH ~/proj/TheSnapper

# or bash
export RATOS_APP_PATH=~/proj/TheSnapper
If your application name is different than the directory name, you can also set RATOS_APP_NAME. Here are some real world examples of how I start up the ratos shell:
 [303] tako:~>  echo $RATOS_APP_PATH
/Users/face/proj/TheSnapper
 [304] tako:~>  ratos

App Name:TheSnapper
App Path:/Users/face/proj/TheSnapper

Paste xcode stack trace to stdin, then type 'sim' or 'arm' on a line by itself.
  Type 'exit' or '^D' to quit and 'app' to print the current app.

ratos>exit
 [305] tako:~>  env RATOS_APP_PATH=~/proj/IttyBooks ratos

App Name:TheSnapper
App Path:~/proj/IttyBooks

Paste xcode stack trace to stdin, then type 'sim' or 'arm' on a line by itself.
  Type 'exit' or '^D' to quit and 'app' to print the current app.

ratos>exit
 [306] tako:~>  env RATOS_APP_PATH=~/proj/IttyBooksFree RATOS_APP_NAME=IttyBooks ratos

App Name:IttyBooks
App Path:~/proj/IttyBooksFree

Paste xcode stack trace to stdin, then type 'sim' or 'arm' on a line by itself.
  Type 'exit' or '^D' to quit and 'app' to print the current app.

ratos>exit
And finally, here is an example interaction:
 [307] tako:~>  ratos

App Name:TheSnapper
App Path:/Users/face/proj/TheSnapper

Paste xcode stack trace to stdin, then type 'sim' or 'arm' on a line by itself.
  Type 'exit' or '^D' to quit and 'app' to print the current app.

ratos>2009-02-05 10:21:31.107 TheSnapper[751:20b] Stack: (
    808221155,
    806100816,
    808224973,
    807957033,
    807851552,
    25785,
    22599,
    22855,
    807923363,
    816119156,
    816119004,
    816157144,
    8381,
    8244
)
terminate called after throwing an instance of 'NSException'

arm

-[BackViewController doubleSnapAction:] (in TheSnapper) (BackViewController.m:192)
-[BackViewController resetAllSiders] (in TheSnapper) (BackViewController.m:126)
-[BackViewController resetSnap:] (in TheSnapper) (BackViewController.m:138)
main (in TheSnapper) (main.m:14)
start (in TheSnapper) + 52

ratos>exit

Enjoy!


Digg! Delicious! Technorati Blinklist Furl Reddit

I've pushed some enhancements to objective-c activerecord

Posted by face on February 06, 2009

OpenID logo


I used objective-c activerecord in IttyBooks as my ORM layer.

I fixed some bugs and made some API changes. Most of the API changes where for performance or memory reasons. While activerecord is not as feature complete as its Ruby cousin, it was nice to contribute. Sure beats mixing SQL in objective-c as well.

Anyway, you can view all of my changes on my fork at github. And they should end up merged back in aptiva’s master tree as well.

Gota love github!


Digg! Delicious! Technorati Blinklist Furl Reddit

Some iPhone apps I have written

Posted by face on February 06, 2009

Been busy writing iPhone apps full time these days. Here are a couple of the apps I’ve recently written.

Please check them out!


Digg! Delicious! Technorati Blinklist Furl Reddit

Finally got NetShare to work on my iphone 3G

Posted by face on August 01, 2008

Screen shot of NetShare

I was so excited, Apple and AT&T approved tethering for my iPhone…but it was gone, no wait, gizmodo say’s it’s back! (click on picture to the left which is the “App Store” link in the gizmodo article to install NetShare right now via iTunes). Update:The link is broken now, NetShare is not available in the US app store. For us lucky few who purchased it….it still works…

However, after installing NetShare via iTunes onto my iphone I could not get it to work. I followed the instructions only to get:

Safari can’t open the page. Safari can’t open the page “http://www.apple.com/”. The error was: “unknown error” (NSURLErrorDomain:-1) Please choose Report Bugs to Apple from the Safari menu, note the error number, and describe what you did before you saw this message.

After fiddling with it for a few minutes I found a solution. The iphone appeard to be still trying to using the WiFi connection and not 3G.

So, right before the final step of launching NetShare on the iphone (i.e. after setting up the adHoc network on the iphone to your PC), launch Safari on the iPhone and surf to a page. This will cause the little WiFi icon to change to 3G at the top of your phone. Now lanuch NetShare that you have the 3G icon back and everything will work like a dream.

I can even use the ssh client on my OSX laptop to connect to remote servers using connect.c to proxy ssh through the iphone. To get this to work was something like:


wget http://www.taiyo.co.jp/~gotoh/ssh/connect.c
gcc connect.c -o connect -lresolv
sudo cp connect /usr/local/bin/.
ssh -o 'ProxyCommand /usr/local/bin/connect -5 -S 10.10.10.1:1080 %h %p' 206.71.190.75
# Of course the ProxyCommand can go in your ~/.ssh/config

Have iPhone, Have Laptop, will travel!


Digg! Delicious! Technorati Blinklist Furl Reddit