A Nu version of HelloWorldClassic
The first iPhone app in Apple’s sample code is a simple program called HelloWorldClassic. That’s also the first iPhone app to be rewritten in Nu, and I’m guessing that means it’s the first app written in any interpreted scripting language that runs on the new official iPhone SDK.
Want to help me test it?
The iPhone SDK was released today, and when I got my copy this afternoon, I did a quick port of Nu. Rather than building Nu as a framework, this port puts Nu in a simple static library libNu.a. That library can then be added to an iPhone SDK project in Xcode to allow Nu code to be used in an iPhone app.
This evening I rewrote the main controller class for HelloWorldClassic in Nu. That leaves just a little bit of Objective-C code in the main.m file; everything else is in this Nu source file, main.nu:
;; HelloWorldClassic in Nu
;; a sample iPhone application ported to Nu
;;
;; Copyright 2008, Tim Burks http://blog.neontology.com
;; Released under the Creative Commons Attribution-Share Alike 3.0 license
;; http://creativecommons.org/license/results-one?license_code=by-sa
;; It seems that there's no BridgeSupport for the iPhone (yet).
;; These constants are defined in the UIKit framework headers.
(global UIControlStateNormal 0)
(global UIControlContentHorizontalAlignmentCenter 0)
(global UIControlContentVerticalAlignmentCenter 0)
(global UIControlEventTouchUpInside (<< 1 6))
(global UITextFieldBorderStyleRounded 3)
(global UIKeyboardTypeAlphabet 1)
(global UITextAlignmentCenter 1)
(set TEXT_FIELD_FONT_SIZE 15.0)
(set BUTTON_FONT_SIZE 16.0)
(set TEXT_LABEL_FONT_SIZE 30.0)
(set TEXT_FIELD_HEIGHT_MULTIPLIER 2.0)
(class HelloWorldClassicAppDelegate is NSObject
(ivar (id) window (id) contentView (id) textField (id) label)
(- (void)addControlsToContentView:(id)aContentView is
(set contentFrame (aContentView frame))
;; Create a button using an image as the background.
;; Use the desired background image's size as the button's size
(set buttonBackground (UIImage imageNamed:"Button.png"))
(set buttonFrame (list 0.0 0.0
((buttonBackground size) first)
((buttonBackground size) second)))
(set button ((UIButton alloc) initWithFrame:buttonFrame))
(button setTitle:"Hello" forStates:UIControlStateNormal)
(button setFont:(UIFont boldSystemFontOfSize:BUTTON_FONT_SIZE))
;; Center the text on the button, considering the button's shadow
(button setContentHorizontalAlignment:
UIControlContentHorizontalAlignmentCenter)
(button setContentVerticalAlignment:
UIControlContentVerticalAlignmentCenter)
;; we have a problem here bridging the return type of
;; UIEdgeInsetsMake, this requires an enhancement to Nu.
;;(button setTitleEdgeInsets:(UIEdgeInsetsMake -2.0 0.0 2.0 0.0))
;; Set the background image on the button
(button setBackgroundImage:buttonBackground
forStates:UIControlStateNormal)
;; hello: is sent when the button is touched
(button addTarget:self action:"hello:"
forControlEvents:UIControlEventTouchUpInside)
;; Position the button centered horizontally in the contentView
(button setCenter: (list ((aContentView center) first)
(- ((aContentView center) second) 52)))
(aContentView addSubview:button)
;; Create a text field to type into
(set textFieldWidth (* (contentFrame third) 0.72))
;; and set the origin based on centering the view
(set textFieldOriginX (/ (- (contentFrame third) textFieldWidth) 2.0))
(set leftMargin 20.0)
(set textFieldFrame
(list textFieldOriginX leftMargin textFieldWidth
(* TEXT_FIELD_FONT_SIZE TEXT_FIELD_HEIGHT_MULTIPLIER)))
(set aTextField ((UITextField alloc) initWithFrame:textFieldFrame))
(aTextField setBorderStyle: UITextFieldBorderStyleRounded)
(aTextField setFont:(UIFont systemFontOfSize:TEXT_FIELD_FONT_SIZE))
(aTextField setContentVerticalAlignment:
UIControlContentVerticalAlignmentCenter)
(aTextField setPlaceholder:"Your name")
(aTextField setKeyboardType: UIKeyboardTypeAlphabet)
(set @textField aTextField)
(aContentView addSubview:@textField)
;; Create a label for greeting output.
;; Dimensions are based on the input field sizing
(set leftMargin 90.0)
(set labelFrame
(list textFieldOriginX leftMargin textFieldWidth
(* TEXT_LABEL_FONT_SIZE TEXT_FIELD_HEIGHT_MULTIPLIER)))
(set aLabel ((UILabel alloc) initWithFrame:labelFrame))
(aLabel setFont:(UIFont systemFontOfSize:TEXT_LABEL_FONT_SIZE))
;; Create a slightly muted green color
(aLabel setTextColor:
(UIColor colorWithRed:0.22 green:0.54 blue:0.41 alpha:1.0))
(aLabel setTextAlignment:UITextAlignmentCenter)
(set @label aLabel)
(aContentView addSubview:@label))
;; This method is invoked when the Hello button is touched
(- (void)hello:(id)sender is
(@textField resignFirstResponder)
(set nameString (@textField text))
(if (eq (nameString length) 0)
(set nameString "Nubie"))
(@label setText:(+ "Hello, " nameString "!")))
(- (void)applicationDidFinishLaunching:(id)application is
;; Set up the window and content view
(set screenRect ((UIScreen mainScreen) bounds))
(set @window ((UIWindow alloc) initWithFrame:screenRect))
;; Add the image as the background view
(set anImageView
((UIImageView alloc) initWithFrame:
((UIScreen mainScreen) applicationFrame)))
(anImageView setImage:(UIImage imageNamed:"Background.png"))
(set @contentView anImageView)
(@window addSubview:@contentView)
(self addControlsToContentView:@contentView)
;; Show the window
(@window makeKeyAndVisible)))
If you have the iPhone SDK, you can download my Xcode project and try running it yourself.
Here’s a link: NuHelloWorldClassic.tgz
(update: I fixed the bad mime type, this should be easier to download now)
Comments (6) post a reply
Yikes!
This looks very cool, I’ll have to drop it in and see how it fares. Since nabbing the SDK last night I’ve wanted to do a rewrite of the same app in PyObjC so maybe this will give me the inspiration to do just that.
Does Nu fall under the Interpreted Language restrictions in the Apple license, or is it a special case?
Jess, I can’t speak for Apple, but I can explain what makes Nu different from other scripting languages:
When Nu source code is parsed, it is converted into a tree of objects. The Nu distribution includes a tool called nubake that generates Objective-C source files that contain C functions. Those functions can be compiled and run to produce the same tree of objects that the parser would have produced. These objects are Objective-C objects like any other objects that your program constructs and uses. They are completely independent of the Nu parser, which we can easily exclude from the Nu runtime that gets linked into an iPhone app. In this way, the iPhone app can be made completely incapable of parsing and running any new source code.
So to put it bluntly, if the Nu parser is a problem, we can easily “neuter” Nu and make it safe for the iPhone.
Neutered apps wouldn’t have a parser and wouldn’t include any Nu source code. We would still get the benefits of Nu’s expressiveness and flexibility during development, but with nubake and neutering, Nu stops being a scripting language and just becomes a very smart language for automatic code generation.
Does this actually run in the Aspen simulator?
Shane,
Yes. If you’re having trouble running it yourself, please follow up on our Google group mailing list.
Tim