Learning Objective-C on Windows with GNUstep and Eclipse

Writing iOS or Cocoa apps does require a Mac with XCode, but you can learn Objective-C (and work on libraries and command-line apps) on Microsoft Windows.

GCC includes an Objective-C compiler. You can install GCC on Windows via Cygwin or MinGW.

You can also get the GNUStep implementation of the OpenStep libraries which includes the same core libraries as Cocoa — including Foundation which contains NSString, etc.

GNUstep includes a graphical environment GWorkspace which is a clone of the NeXT workspace manager. I haven’t gotten GWorkspace (or Backbone and alternative) to work on Windows or any other graphical apps, but you can use graphical GNUstep apps on Linux.

What this means is that the core libraries and command line apps can work on Windows — which is good for learning basic Objective-C concepts.

In order to use GNUstep on Windows install the GNUstep MSYS System — which gives you the core unix-like tools you know and love.

Next install GNUStep Core. You should be able to open a Shell window and execute commands.

Then install GNUStep Devel which will give you GCC with Objective-C and the GNUStep libraries which allow development.

Gorm is an interface builder for GNUStep which allows you to create (admittedly ugly) GNUstep user interfaces via drag and drop — but I couldn’t get it to work on Windows.

Once you have MSYS, GNUStep Core, and GNUStep Devel, launch the shell from your Windows Start menu.

gnustep start menu

Using a text editor, write a hello world app:

#import <Foundation/Foundation.h>

int main(int argc, const char *argv[]) 
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	NSLog (@"Objective-C with GNUstep on Windows");
	return 0;
}

Voila, you’re coding in Objective-C on Windows with GCC!

You can see that your managing memory the old fashioned way. You don’t have ARC, but you can get modern features using clang which is the compiler used by XCode.

Directions for installing clang on Windows are available here:

http://solarianprogrammer.com/2012/03/21/clang-objective-c-windows/

Basically:

1. Checkout LLVM
2. Checkout clang into the llvm/tools folder
3. Edit llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp

Look for // FIXME: temporary hack: hard-coded paths. (on line 223 currently)


// FIXME: temporary hack: hard-coded paths.
AddPath("C:\\GNUstep\\include", System, true, false, false);
AddPath("C:\\GNUstep\\msys\\1.0\include", System, true, false, false);
AddPath("C:\\GNUstep\\lib\\gcc\\mingw32\\4.6.1\\include", System, true, false, false);
AddPath("C:\\GNUstep\\lib\\gcc\\mingw32\\4.6.1\\include\\c++", System, true, false, false);
AddPath("C:\\GNUstep\\GNUstep\\System\\Library\\Headers", System, true, false, false);
//AddPath("/usr/local/include", System, true, false, false);
break;

4. Compile

cd llvm && mkdir build && cd build
../configure --enable-optimized --enable-targets=host-only
make && make install

An error is expected and not a problem groff: command not found

Now you can use ARC in your Objective-C on GNUstep compiled with clang:

// test.m

#include <Foundation/Foundation.h>

int main(){
    @autoreleasepool{
        NSLog( @"Objective-C with ARC on Windows");
    }
    return 0;
}

Here’s a sample GNUmakefile:

include $(GNUSTEP_MAKEFILES)/common.make

TOOL_NAME = test
test_OBJC_FILES = test.m

include $(GNUSTEP_MAKEFILES)/tool.make

Now run:

make CC=clang

Now, using a plain text editor (even Sublime Text) for writing code isn’t always fun..But you can use Eclipse.

Install the Eclipse CDT (C/C++ Development tools) and follow the directions here to set up Eclipse for using Objective-C:

http://wirecode.blogspot.com/2007/11/objective-c-and-eclipse.html

I haven’t yet gotten Objective-C to compile with Eclipse CD% yet but I’ll post more when I’ve got it working.

Advertisements

Objective-C object syntax and semantics

Objective-C syntax looks like line noise mixed with Klingon. But it’s concepts are not that far from standard programming practices, though some of the names of the concepts are unfamiliar because they were chosen before modern practices (like OOP) became common (and thus well understood with a shared syntax.) Some of it’s mechanisms are odd because it was designed to run as a preprocessor on top of C.

To start off, Objective-C is object oriented (sortof… in the same way “objective” is related to “object”).

A “class” in Obj-C has an interface (defined in a .h “header” file) and an implementation (defined in a .m “messages” file.)

Let’s take a look at an example. It’s time to get started on our adventure game, so (for now) create a console application and add a new class.

File -> New -> File -> OS X -> Cocoa -> Objective-C Class

Screen Shot 2013-01-16 at 2.33.05 PM

Give your class a name and notice by default that it is a subclass of NSObject. NS, again stands for “NextStep” and the reason you have it is because Objective-C doesn’t have namespaces. So you’ll see a lot of capitalized prefix abbreviations.

Screen Shot 2013-01-16 at 2.33.24 PM

You can see that two files were created. Jedi.h and Jedi.m. Click on Jedi.m and open the assistant editor to see Jedi.h alongside it. This is a handy feature in Xcode (when it works.)

Jedi interface and implementation

@interface and @implementation are compiler directives. Each are followed by an @end directive. You can see that Jedi extends NSObject with the colon syntax similar to C#.

Jedi : NSObject

Let’s start by adding a property. Every Jedi is a person, and every person has a name. Create a Person class and change Jedi to extend person. Add an instance variable “name” to person.

//Person.h
#import <Foundation/Foundation.h>

@interface Person : NSObject {
    NSString * _name;
}

@property (readwrite) NSString *name;

@end
//  Person.m
#import "Person.h"

@implementation Person

@synthesize name;

@end
//  Jedi.h
#import <Foundation/Foundation.h>
#import "Person.h"

@interface Jedi : Person

@end

This is our first real departure from familiar syntax. The compiler directives aren’t too scary and you can think of them like annotations for now.

The block after the class definition in Person.h defines instance variables. In our case, an NSString called name. All objects are pointers (yikes!) and NSString is no exception. NSString is an object that has all sorts of capabilities that a char * does not. Modern languages like Java and C# have String classes and Objective-C or rather it’s core library in Foundation.h from Cocoa (OpenStep) has NSString.

Don’t worry too much about pointers. Thanks to ARC, memory management is easy (ish) and the real hard part is understand the evolving memory management methods in Obj-C — including a lot of very good but recently outdated information on the internet. And code you are likely to see that was written as little as 1 year ago.

Moving on, a @property directive creates accessors for that instance variable. Kinda like attr_accessor in Ruby. But not quite. In the implementation, you also need to @synthesize the property in your implementation. This creates the getters and setters. With XCode 4.4+ you no longer need to add the @synthesize line. If a property is declared “readwrite” it will create both a getter and setter. If it is “readonly” it will only create a getter.

Let’s create a Jedi and welcome him to the adventure.

//  main.m
#import <Foundation/Foundation.h>
#import "Jedi.h"

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Jedi *jedi = [[Jedi alloc] init];
        jedi.name = @"Luke";
        
        NSLog(@"May the force be with you!, %@", jedi.name);
    }
    
    return 0;
}

To instantiate our class we have to first allocate memory and the initialize our object. Thats what this line is doing:

Jedi *jedi = [[Jedi alloc] init]

Objective-C doesn’t have constructors. But you can nest calls. The square brackets [ ] are an indication that you’re dealing with objects. Here, you’re calling two methods that are built into NSObject — alloc, which wraps the C function malloc() and init which by convention initializes the object. This, if you will, is the standard constructor call — the equivalent to new in other languages like Java. And remember, every object is really a pointer.

Next we assign a name to our object. The dot notation syntax is familiar to us, but what it’s really doing is providing a little syntactic sugar for this message call.

[jedi setName: @"Skywalker"]

Now I’d better slow down a bit and explain what I mean by a message call. See, classes (and objects — instances of classes) don’t have methods in Objective-C, they have messages. For all practical purposes you can think of them as the same thing, and many people use the terms interchangeably. But it helps to remember what your doing inside the brackets is object oriented, and if you’ve used signals and slots in Qt you won’t be too blown away by the idea. There are a lot of ramifications for this, the main one being that you can dynamically send messages to objects (whether the message is supported or not — which could then trigger an exception) which allows for metaprogramming.

So you’re really sending a message to an instance of a class, not calling a method on an object. But for most purposes it amounts to the same thing. Even the latest Apple docs use the term “method”.

Dot notation is a node to those of us who are familiar with it from other languages, but it’s not universally popular with Objective-c purists.

But I’m getting ahead of myself in the example. Let’s get back to our code.

Every person has a name, and every Jedi is a person (assuming aliens are people too.) But what differentiates a Jedi from an ordinary person is the ability to use the force. Let’s add that capability by creating a method declaration in Jedi.h and an implementation in Jedi.m (very similar to what you’d expect in C) but with a slightly different syntax.

//  Jedi.h
#import <Foundation/Foundation.h>
#import "Person.h"

@interface Jedi : Person

- (void)useTheForce;

@end

The minus (-) symbol designates it as an instance method. If it were replaced with a plus (+) then it would be a class method — similar to using the “static” keyword in Java.

// Jedi.m

#import "Jedi.h"

@implementation Jedi

- (void)useTheForce {
    NSLog(@"The Force is what gives a Jedi his power");
}
@end

void is the return type. (Just pretend those parentheses weren’t there.) The semicolon is just like a function definition in a C header or declaration in a Java interface. (Note what we call interfaces are called protocols in Objective-C. The class declaration in a .h header file is called an “interface” in Objective-C. It’s easy to conflate the two if you’re not thinking about it.

And now let’s have our young Jedi try it out.

[jedi useTheForce]

Does the same thing as

jedi.useTheForce

but the latter gives us a warning “Property access result unused — getters should not be used for side effects.” Because the dot notation is syntactic sugar that expects it to be calling a property, not invoking a method (or calling a message)– which has side effects.

Taking a step back to learn Objective C

Objective C is the language used by Apple to create IOS apps, so if you want to create native apps, you will need to learn it.

You can go a long way in IOS development (and not just using Interface Builder) without having to learn much of Objective C. You can parse through the line noise, and with a little experimentation, find out how to modify strings and perform arithmetic, iterate through loops, etc. until you’ve got a working program. But that’s not fun and it leads to unnecessary errors and frustration.

So let’s take a step back and learn Objective C.

In my opinion, Objective-C is the worst language esthetically (and conceptually) I have ever seen. It has more punctuation than Perl and less consistency than PHP. It’s object oriented system is half baked but to be fair it was created when OOP was a fairly new concept and apart from a handful Smalltalk afficionados, not well understood by anyone. So much of the language constructs were named when OO terminology was not yet settled. But many of it maps near enough to familier concepts, so we can go from there.

Let’s get started.

I promised an adventure game based on Star Wars, but let’s start with something simpler. Forget about IOS and GUIs for a moment and create a console app.

Screen Shot 2013-01-16 at 9.52.13 AM

Here’s hello world in Objective C:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{
    NSLog(@"Hello, World!");
    return 0;
}

Objective C is (very) loosely descended from C, and *theoretically* valid C is valid Obj-c. In this example, at least it holds true.

main is still the entry point to an application. You still have argc and argv, the only change being const which comes from C++ and is easy enough to understand.

#import is like #include but guarantees something is included only once. You can still use “#include” (because it’s valid C) but don’t.

NSLog comes from Foundation. Foundation is the Objective C core library. NS stands for “NextStep” the old NeXT workstation that Objective C was developed for. It is a bit more than printf or cout. More like System.out.println() in Java or System.Console.WriteLine() in C#. NSLog takes a format string and variable number of arguments.

In order to “cast” a string literal — an array of chars — to an NSString, use an @ symbol in front of the string. @"like this".

And of course return your error code of zero from main.

Technically, there is a memory leak here. We never released the memory allocated for the NSString created implicitly when we sent the constant character string @”Hello, World!” to NSLog().

In practice, this memory will be freed when the program exits so it’s not a big deal in a hello world app that ends immediately, but your IOS apps (hopefully) will not.

So let’s rewrite this program to use ARC – the automatic reference counter.

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        NSLog(@"Hello, World!");
    }
    return 0;
}

The @autoreleasepool block puts all the references created within it under ARC – which means the compiler takes care of it.

If you are familiar with Objective C garbage collection (why are you reading this?) then you should be aware that using ARC means that you do not call retain, release, autorelease, or dealloc. See the IOS 5 release notes on ARC for more details.

IOS development late start

Apple stock is falling on the news that iPhone 5 sales are expected to be down 40% below projections. Without Steve Jobs at the helm, it was only a matter of time before this sort of thing happened.

Screen Shot 2013-01-15 at 3.52.47 PM

It seems like a great time for me to finally get started learning IOS development. One part of the impetus comes from my work at Ancestry.com where I’m working to development better software testing practices — which happens to include for IOS. And the other part comes from my own project (currently on hold) to develop a mobile app.

Screen Shot 2013-01-15 at 3.59.59 PM

I started Budgeteer last year while I was in Ecuador using Sencha Touch for the UI which takes Javascript and HTML5 and compiles it to a native app. (I also happened to be consulting for Sencha at the time.) Since I’m working in IOS now, I thought I’d take up the project again as a native app. I’m also interested in Xamarin (by the guys who gave you Mono) to build cross platform apps in C#, but that’ll have to wait. I was burned before with Titanium.

I feel like I’m getting a late start in IOS development, but that’s OK. There have been some good developments lately that make it much easier including storyboards, automatic memory management, and UIAutomation. Which are great, but there is still a lot of code out there that doesn’t take advantage of it all, and much of the information you’ll find online is out of date.

I’ll try to address this and would appreciate any comments that can correct me.

First off, you’ll need a Macintosh computer. Apple has decreed that you need to use their tools (and while there are ways around it — like the aforementioned Sencha Touch, Titanium Appcelerator, Xamarin, etc. — they’re still not as mature and are all proprietary.)

And then you’ll need XCode. That’s the Apple IDE. It’s kindof ok. Not a great productivity booster, but at least it’s free now. Download it from the app store (iTunes). That’s right, Apple thinks a software development platform is an MP3.

I’m going to start with a simple Hello world to get you up and running in IOS. And then I’m going to build an adventure game based on a popular movie franchise.

I’m using XCode 4.5 (which is quite different from XCode 4-4.2 which is a total change from XCode 3) so screenshots and UI directions might get quickly out of date.

Once you’ve installed XCode, create a new project, and since we’re doing this for iPhone app-love let’s create an IOS application.

From the toolbar click “File -> New -> Project”. Choose an application template. IOS -> Application -> Single View Application (we’re not too ambitious.)

Screen Shot 2013-01-15 at 4.26.09 PM

Enter your project information and click next.

Screen Shot 2013-01-15 at 4.28.01 PM

Take a look at your project in XCode and notice the files on the left hand side

Screen Shot 2013-01-15 at 4.32.50 PM

You have the the folling files:

SWAppDelegate.h
SWAppDelegate.m
MainStoryboard_iPhone.storyboard
MainStoryboard_iPad.storyboard
SWViewController.h
SWViewController.m

The .h files are interface files (think “like C headers” but not too hard.)
The .m files are implementation files (think “like .c files” but not really.)
The .storyboard is your user interface.

Click on MainStroyboard_iPhone.storyboard and it brings up the Interface Builder. Which shows a picture of an iPhone screen.

Screen Shot 2013-01-15 at 4.38.59 PM

Look in the lower right corder. You see “Objects” with “View Controller” highlighed. Remember selecting “Single View” in the template. This is what you get. Another common View Controller is the “Table View Controller” and I’ll let you guess what that does. A basic ViewController is what we have SWViewController is it.

You can see it the source code by clicking on SWViewController.m and if you click on the toolbar: View -> Assistant Editor -> Show Assistant Editor or click on the theater mask (shirt with bowtie?) in the upper right corner of your screen you’ll see SWViewController.h right alongside it.

Screen Shot 2013-01-15 at 4.42.20 PM

Let’s just ignore the details of Objective-C for now. I don’t get it, and I’m going to explain it a in a little more detail in my next post. As far as I’m concerned Objective-C is esthetically the most objectionable programming language I’ve ever seen. And that includes a nightmare hybrid of Perl and BASIC.

But we want to see this thing do something, and compile, and run. So go back to your storyboard and where it says “Objects” in the lower right corner, click the dropdown and change it to “Controls”

Screen Shot 2013-01-15 at 4.48.37 PM

Then click and drag a label onto the storyboard.

Screen Shot 2013-01-15 at 4.51.38 PM

Change your label to say something interesting (not by doubleclicking) by clicking on the label, then clicking on the 4th icon in the top right (a seatbelt?) and editing the field under Text: Plain where it says “Label” to say something more interesting:

Screen Shot 2013-01-15 at 4.53.53 PM

Expand the label by dragging, and tweak the font size and color to your heart’s content. Come back when you’re done playing and then select “IPhone 6.0 Simulator” under “IOS Device” in the top left corner of XCode and click Run. After a couple minutes you’ll see first cool new iPhone app.

force

Congratulations. You’ve taken your first step into a larger world.

2012 in review

The WordPress.com stats helper monkeys prepared a 2012 annual report for this blog.

Here’s an excerpt:

19,000 people fit into the new Barclays Center to see Jay-Z perform. This blog was viewed about 58,000 times in 2012. If it were a concert at the Barclays Center, it would take about 3 sold-out performances for that many people to see it.

Click here to see the complete report.