Where does the application delegate come from?

Posted on October 10, 2008

When I first starting looking at how XCode and Interface Builder worked together, it wasn’t obvious how the application delegate was created. So, here’s my sequence of what happens.

  • The application loads its default nib file. That’s normally MainWindow.nib, but you’ll want to look at Info.plist in your project, under “Main nib base project:” screenshot

  • The “File’s Owner” for the default nib file is the UIApplication. For other nib files, you’ll specify the file owner in the call that loads the nib.

  • The nib file has an object for your application delegate (in this case, called “Tst2 App Delegate”). It’s a top-level object so it’s instantiated when the nib file is loaded. It’s connected to the ‘delegate’ field of the File’s Owner: Interface Builder

  • When the nib file is loaded, top-level objects are instantiated for you. In this example, “Tst2 App Delegate” and “Tst2 View Controller” will be created automatically.

  • Tst2 App Delegate is connected to the delegate outlet of the File’s Owner - in this case, the UIApplication object for your app.

  • Tst2 View Controller is connected to the Tst2 App Delegate’s viewController outlet: Interface Builder

= Documentation

You’ll want to read or at least skim these documents, found here on the developer website or in the XCode doc.

Resource Programming Guide - much more detail on how resource files (including nibs) are used.

Baby’s First iPhone Application - See Dick and Jane write an iPhone app. Surprisingly useful quick tour through creating an app. (And the real title is Your First iPhone Application, in case you were wondering.)

No java.lang.management in Android

Posted on October 07, 2008

More Android/jruby experiments.

I’m getting a VerifyError thrown when Android’s classloader tries to pull in org.jruby.manager.BeanManager - the exception is thrown at line 209 of Ruby.java (from trunk):

this.beanManager        = new BeanManager(this, config.isManagementEnabled());

And this from the android log:

VFY: unable to resolve static method 1349: Ljava/lang/management/ManagementFactory;.getPlatformMBeanServer()Ljavax/management/MBeanServer;

Using trunk jruby - 1.1.4 doesn’t load in Android.

Android and JRuby - 1.1.4 no go, but trunk may be working

Posted on October 06, 2008

I’m experimenting with JRuby on Android. With the jruby 1.1.4 jar, I get this error:

[2008-10-06 17:49:52 - AndroidTst] warning: Ignoring InnerClasses attribute for an anonymous inner class that doesn't come with an associated EnclosingMethod attribute. (This class was probably produced by a broken compiler.)
[2008-10-06 17:50:06 - AndroidTst] 
UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dx.cf.code.SimException: at stack depth 0, expected type org.jruby.runtime.builtin.IRubyObject but found org.jruby.runtime.builtin.IRubyObject[]
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.cf.code.BaseMachine.popArgs(BaseMachine.java:143)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.cf.code.Simulator$SimVisitor.visitConstant(Simulator.java:585)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.cf.code.BytecodeArray.parseInstruction(BytecodeArray.java:750)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.cf.code.Simulator.simulate(Simulator.java:96)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.cf.code.Ropper.processBlock(Ropper.java:681)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.cf.code.Ropper.doit(Ropper.java:636)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.cf.code.Ropper.convert(Ropper.java:253)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.dex.cf.CfTranslator.processMethods(CfTranslator.java:252)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.dex.cf.CfTranslator.translate0(CfTranslator.java:131)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.dex.cf.CfTranslator.translate(CfTranslator.java:85)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.command.dexer.Main.processClass(Main.java:297)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.command.dexer.Main.processFileBytes(Main.java:276)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.command.dexer.Main.access$100(Main.java:56)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:228)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:245)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:130)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:108)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.command.dexer.Main.processOne(Main.java:245)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.command.dexer.Main.processAllFiles(Main.java:183)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.dx.command.dexer.Main.run(Main.java:139)
[2008-10-06 17:50:06 - AndroidTst]   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[2008-10-06 17:50:06 - AndroidTst]   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
[2008-10-06 17:50:06 - AndroidTst]   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[2008-10-06 17:50:06 - AndroidTst]   at java.lang.reflect.Method.invoke(Method.java:597)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.ide.eclipse.adt.build.DexWrapper.run(Unknown Source)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.ide.eclipse.adt.build.ApkBuilder.executeDx(Unknown Source)
[2008-10-06 17:50:06 - AndroidTst]   at com.android.ide.eclipse.adt.build.ApkBuilder.build(Unknown Source)
[2008-10-06 17:50:06 - AndroidTst]   at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:633)
[2008-10-06 17:50:06 - AndroidTst]   at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
[2008-10-06 17:50:06 - AndroidTst]   at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:170)
[2008-10-06 17:50:06 - AndroidTst]   at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:201)
[2008-10-06 17:50:06 - AndroidTst]   at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:253)
[2008-10-06 17:50:06 - AndroidTst]   at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
[2008-10-06 17:50:06 - AndroidTst]   at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:256)
[2008-10-06 17:50:06 - AndroidTst]   at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:309)
[2008-10-06 17:50:06 - AndroidTst]   at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:341)
[2008-10-06 17:50:06 - AndroidTst]   at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:140)
[2008-10-06 17:50:06 - AndroidTst]   at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:238)
[2008-10-06 17:50:06 - AndroidTst]   at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
...at bytecode offset 00000028
locals[0000]: Lorg/jruby/ext/ffi/AbstractMemory$i_method_multi$RUBYINVOKER$get_string;
locals[0001]: Lorg/jruby/runtime/ThreadContext;
locals[0002]: Lorg/jruby/runtime/builtin/IRubyObject;
locals[0003]: Lorg/jruby/RubyModule;
locals[0004]: Ljava/lang/String;
locals[0005]: [Lorg/jruby/runtime/builtin/IRubyObject;
...while working on block 0025
...while working on method call:(Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;Lorg/jruby/RubyModule;Ljava/lang/String;[Lorg/jruby/runtime/builtin/IRubyObject;)Lorg/jruby/runtime/builtin/IRubyObject;
...while processing call (Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;Lorg/jruby/RubyModule;Ljava/lang/String;[Lorg/jruby/runtime/builtin/IRubyObject;)Lorg/jruby/runtime/builtin/IRubyObject;
...while processing org/jruby/ext/ffi/AbstractMemory$i_method_multi$RUBYINVOKER$get_string.class

[2008-10-06 17:50:06 - AndroidTst] 1 error; aborting
[2008-10-06 17:50:06 - AndroidTst] Conversion to Dalvik format failed with error 1

I’m not seeing the same problem with jruby trunk though.