Fun with Distributed Objects

Here’s how you can use Distributed Objects to remotely evaluate code on your simulated iPhone. This is obviously not for shipping applications, but I think you’re going to want to know how to do this when you’re debugging your app.

I’m assuming that you’re building your iPhone app with Nu. That’s a stretch, since I haven’t released a version of Nu for the iPhone other than the demo that I put out Thursday night. But start with that one for now.

Add this to your main.nu:

(class Server is NSObject
     (- (void) print:(id) message is
        (puts (+ "master says: " message)))
     (- (id) eval:(id) command is
        (eval (parse command))))

Then put this near the end of your applicationDidFinishLaunching::

(set receivePort ((NSSocketPort alloc) initWithTCPPort:8080))
(set $connection 
   (NSConnection connectionWithReceivePort:receivePort sendPort:nil))
(set $server ((Server alloc) init))
($connection setRootObject:$server)
(puts (NSString stringWithShellCommand:"ifconfig"))
Now run your iPhone app. Open the console in Xcode (use the Run – Console menu item). You should see something like this at the end of your log:
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
    inet 127.0.0.1 netmask 0xff000000 
    inet6 ::1 prefixlen 128 
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    inet6 fe80::219:e3ff:fe66:8ca6%en0 prefixlen 64 scopeid 0x4 
    inet 192.168.0.104 netmask 0xffffff00 broadcast 192.168.0.255
    ether 00:19:e3:66:8c:a6 
    media: autoselect (100baseTX <full-duplex,flow-control>) status: active
    supported media: autoselect 10baseT/UTP <half-duplex> 10baseT/UTP <full-duplex> 10baseT/UTP <full-duplex,hw-loopback> 10baseT/UTP <full-duplex,flow-control> 100baseTX <half-duplex> 100baseTX <full-duplex> 100baseTX <full-duplex,hw-loopback> 100baseTX <full-duplex,flow-control> 1000baseT <full-duplex> 1000baseT <full-duplex,hw-loopback> 1000baseT <full-duplex,flow-control>
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    ether 00:19:e3:66:8c:a7 
    media: autoselect status: inactive
    supported media: autoselect 10baseT/UTP <half-duplex> 10baseT/UTP <full-duplex> 10baseT/UTP <full-duplex,hw-loopback> 10baseT/UTP <full-duplex,flow-control> 100baseTX <half-duplex> 100baseTX <full-duplex> 100baseTX <full-duplex,hw-loopback> 100baseTX <full-duplex,flow-control> 1000baseT <full-duplex> 1000baseT <full-duplex,hw-loopback> 1000baseT <full-duplex,flow-control>
fw0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 2030
    lladdr 00:19:e3:ff:fe:80:5f:8e 
    media: autoselect <full-duplex> status: inactive
    supported media: autoselect <full-duplex>
vmnet8: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    inet 172.16.53.1 netmask 0xffffff00 broadcast 172.16.53.255
    ether 00:50:56:c0:00:08 
vmnet1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    inet 172.16.159.1 netmask 0xffffff00 broadcast 172.16.159.255
    ether 00:50:56:c0:00:01 

Look near the end of the log. For me, “172.16.53.1” appears to be the local address of my simulated iPhone.

Now open a terminal and type “nush” (Yeah, you need Nu for this).

Type the following commands, subsituting whatever your iPhone’s address happens to be:

% (set sendPort ((NSSocketPort alloc) initRemoteWithTCPPort:8080 host:"172.16.53.1"))
<NSSocketPort:1347f0>
% (set connection (NSConnection connectionWithReceivePort:nil sendPort:sendPort))
<NSConnection:152b80>
% (set iphone (connection rootProxy))
<NSDistantObject:1430a0>

Now you have a proxy for the Server object that’s running on your iPhone. Send it a command:

% (iphone print:"hello")
()
Now go look in your console window. See it?
master says: hello

Now go back to your console window.

% (set delegate (iphone eval:"((UIApplication sharedApplication) delegate)"))
<NSDistantObject:14b600>

Now your delegate variable is a proxy for the application delegate on your iPhone. Let’s ask it a few things. Follow along:

% (delegate valueForKey:"contentView")
<NSDistantObject:168bb0>
% ((delegate valueForKey:"contentView") subviews)
<NSCFArray:140ac0>
% (((delegate valueForKey:"contentView") subviews) count)
3
% ((((delegate valueForKey:"contentView") subviews) objectAtIndex:0) description)
<UIButton: 0x1261c70>
% ((((delegate valueForKey:"contentView") subviews) objectAtIndex:1) description)
<UITextField: 0x1263700>
% ((((delegate valueForKey:"contentView") subviews) objectAtIndex:2) description)
<UILabel: 0x126fde0>
% ((((delegate valueForKey:"contentView") subviews) objectAtIndex:2) setText:"pwned")
()

Having fun?

Obviously, this is FOR DEBUGGING AND DEVELOPMENT USE ONLY (sorry to shout, I just wanted to be clear about that) and remember, Apple has final say over what gets onto its platform. Our ability to use this during development does not at all imply that we can or should build it into applications.

5 comments ↓

#1Jens Ayton on 2008-03-08 at 19:56:29 America/Los_Angeles

I suggest anyone getting excited by the apparent possibilities takes a look at section 3.3.2 of the iPhone SDK Agreement.

#2Tim Burks on 2008-03-09 at 00:14:51 America/Los_Angeles

Jens,

That’s a valid concern. Please also see my comments at the end of this post.

#3millenomi on 2008-03-21 at 20:48:50 America/Los_Angeles

A number of things:

- vmnet1 is (usually) VMWare's loopback device so you're just doing a 127.0.0.1 thing. Remember that the simulator runs on your Mac and inherits its address.
- for a real iPhone test, keep in mind that iP's register Bonjour names on wi-fi, so you can use "MyIPhoneName.local" as the hostname and it'll work.
#4Tim Burks on 2008-04-18 at 14:34:38 America/Los_Angeles

An update: this works on the simulator only. There’s currently no Distributed Objects support on the iPhone. At least not until someone writes it.

#5Pat on 2008-10-21 at 16:08:51 America/Los_Angeles

Thanks Tim, this is a great post regardless of section 3.3.2, it’s for development and testing and finding a way to work with the tools in a more efficient fashion is awesome.

Thank You

Leave a Comment (sign in with Twitter)