My talk at NSConf was about cross-platform Objective-C. Those people who I talked to after the session will know that my goal is clear. There are plenty of people out there who have learned Objective-C to get onto the iOS or Mac app stores. Those people need some server-side smarts in their apps, and want to benefit from the skills they’ve already acquired. In other words: they want Objective-C on the server.
I’m now in a position to offer that :). I took a look at the GNUstepWeb project, a reimplementation of WebObjects 4.5. It was in a fairly parlous state, and wouldn’t even build on my Mac. I’ve fixed that. It’s still a bit of a faff, but we’re in a position to start playing with server-side ObjC and see whether there’s any value in having a better product.
Building GSW on the Mac
GNUstep-make
First, you need to grab GNUstep from SVN. Now you need to compile GNUstep-make, the build system. On Mac OS X you do the following:
cd modules/core/make ./configure --with-library-combo=apple-apple-apple make make install
The weird configure invocation tells GNUstep you’re going to use the Apple Objective-C runtime, and the Foundation (and AppKit) libraries instead of GNU replacements.
GNUstep-make includes a shell script that defines the locations of various folders. You should import that into your shell environment:
. /Library/GNUstep/Makefiles/GNUstep.sh
Consider adding that line to your .bash_profile.
GNUstep-base
Then you build the GNUstep-base extensions, some additional classes and macros for working with Foundation code.
cd modules/core/base ./configure make make install
GDL2
GDL2 is the GNUstep Database Library; an EOF-like framework for interacting with databases. If you’re going to use a DBMS like MySQL for your web apps, you should install that and its developer headers before doing:
cd modules/dev-libs/gdl2 ./configure --disable-gorm-palette make make install
(Aside: GORM is the GNUstep version of Interface Builder. You don’t need the plugin for working with entities in GORM, and you can’t build it on Mac OS X so that’s why it’s disabled in the configure invocation.)
GNUstepWeb
Now here’s the good stuff. Build and install GSW. At time of writing, there’s an open bug that stops it building on Mac OS X, so you’ll need to grab the patch from this bug report. Apply that patch, then:
cd modules/dev-libs/gsweb ./configure make make install
A sample app
You probably want to see a sample GSW app, so it’s a good job I wrote one :-). Clone the HelloGSW project on GitHub. I’ll show you how to build and run that before we get into how it works.
Building HelloGSW
cd HelloGSW make
Running HelloGSW
HelloGSW.gswa/Contents/MacOS/HelloGSW
this will spit a load of output to the console, including a URL that looks like http://localhost:9001/WebObjects/HelloGSW.woa/0/. Open that URL in your browser. You should see this:
HelloGSW code walkthrough
The interesting code is in the Main class, which is a subclass of GSWComponent (and conventionally the default component to show for a new visitor). Each “page” in a GSW app is a component, though of course you could arrange to return XML, JSON or any other format rather than HTML. HTML is the default and the easiest to work with, and indeed we’ll start by looking at a section of the HTML file, Main.wo/Main.html.
<p>The time is <webobject name=now_string></webobject>.</p>
This is clearly the paragraph that puts the date onto the screen, but you can see that there’s this weird <webobject> tag in there. That’s going to be substituted with our date object at runtime, but how? To answer this question, look at the Main.wo/Main.wod file.
now_string:WOString {value = now}
This file contains bindings, which if you’re familiar with Cocoa work pretty similar to Cocoa Bindings. This tells us that there’s a web object called now_string, that it’s an instance of WOString, and that its value binding is bound to something called now.
That now binding is actually a key on the component object. We might expect to see a method called -(NSString *)now defined on Main to fill in the value of this string. Indeed, if we look at Main.m:
- (NSString *)now { NSDate *theDate = [NSDate date]; return [theDate description]; }
Where to go from here?
The start is to build more GSW apps, and of more complexity. However there are things that need to be done along the way: all of the rest of the code and files in this project are meaningless boilerplate. This stuff needs to be hidden, automated or removed. Then we can also automate the process: compare how much of a faff setting up this app was with running a Rails app in Heroku (and I haven’t even set up an adaptor to a real web server!). It’d be really useful to simplify common tasks in modern web applications, such as exposing REST interfaces and non-HTML document formats.
Conclusions
Objective-C is not just a client app language. It’s got a long heritage as a server technology, but unfortunately the tools for doing that are quite out of date. They’re still useful though, so people who have come into the Objective-C fold recently can expand the use of their newly-found skills. Hopefully people will adopt—and contribute to—GNUstepWeb and help everyone to make it a useful modern server technology.
Great idea!
And thanks for making this happen :)
Already thought of some kind of database integration?
CoreData on the server side would be awesome!
You’ve got GDL2 as part of GNUstepWeb, which is conceptually very similar to Core Data but is designed to be used with RDBMS like MySQL/Postgres/Oracle. GNUstep also has a CoreData library which is, unsurprisingly, like Core Data: I don’t know what state their port is in. If you’re running your server process on Mac OS X you can use Apple’s Core Data anyway.
Have you heard of Bombax? It was a commercial product from Brombaxtic that is now open sourced that did put Objective-C on the server.
ObjC isn’t designed for a large-scale development.
It wouldn’t surprise me if at some point apple extend iCloud to make it a back-end cloud service that developers can host their apps on. If that happened I could see them releasing a fully updated Objective-C set of frameworks for this purpose.
Nice article! I would love to see this as a Heroku Buildpack (http://devcenter.heroku.com/articles/buildpacks). Have you looked into building one for GNUstep?
Anna, I don’t agree. UIKit isn’t designed for anything more complicated than a mobile app, but as someone who’s worked on many Objective-C server platforms I’m pretty confident that Objective-C scales.
Mattt, that’s a long way off yet. I want to approach it in stages, but my goal is to do something Heroku-like.
Awesome project – I think it would benefit a lot of objective-c programmers. Definitely bookmarking and interested in seeing where this goes.
Thank you for your interest in GSWeb and for bug reports. While I am ok with GNUstep libraries have I tried to understand the WebObjects concept. I understand the Component part of it (I suspect that the Smalltalk Seaside framework is modelled after it), but server state is still a bit of a mystery, as is the bindings (the wod,woo etc).
Is the framework “modern” or rather possible to modernize enough to compare to other frameworks? I.e. making async requests possible like a javascript-webobjects bridge?
This spurred me into decide to write the frontend to my servertools (built upon GNUstep/Cocoa) using GSW – it is going to be fun.
Tim, Good luck with your server tools project! I hope you keep the world informed as to how it’s going :-).
Addressing your question about whether GSW is “modern”: the answer is no. It itself doesn’t make it easy to do things like AJAX, REST APIs or anything else you’d likely see in a modern web app. But the good news is it’s not too hard to build those things on top of what it _does_ provide, which is basically the request/response cycle. The Java WebObjects community have various extensions as part of Project Wonder (http://wiki.wocommunity.org/display/WO/Project+WONDER-Overview) that do make it easier to do modern web apps on WO. Those could be a good inspiration for doing the same things over in Objective-C on GSW.
I would like to help with a project wonder type framework. Do u gave a timeline/goals , any other collaboration ideas to get this started. I like locomotivecms(ruby) as an inspiration towards acheiving a modern look, functionality goal for this modern objective-c framework. Also, check out https://github.com/tdmartin102/ajrdatabase
Hi, I don’t have any particular projects in mind with regard to extending GNUstep web, though I do think it needs to be a lot easier to build and deploy a GSW application so automation is one thing I’m investigating (and, of course, incorporating some form of unit tests invoked from GNUstep-make). What I’m doing is building an application, and looking for things the framework doesn’t provide that need adding. Something that springs to mind if you want a quick idea to get started is a REST component along the lines of ERRest from WOnder.
I will look into the ERrest and see what’s needed on the gnustepweb side, and get started. What about Xcode 4.3 and gnustepweb ? How to build with Xcode post!
Consider that added to the backlog…
i followed the direction when i type make inside the test application folder, i get the following error on LION, with Xcode 4.3.3, command line tools installed:
GNUmakefile:1: /common.make: No such file or directory
GNUmakefile:2: /Auxiliary/gsweb_wo.make: No such file or directory
GNUmakefile:21: /gswapp.make: No such file or directory
make: *** No rule to make target `/gswapp.make’. Stop.
Forget the previous post, the new problem is GNUStep – BASE ERRORS
Your gnustep-make is configured to use native objc exceptions, but
the objc runtime does not appear to support setting an uncaught
exception handler. This means that any uncaught exception will
cause a program to abort immediately.
Consider reconfiguring gnustep-make or updating libobjc to fix this.
checking ffi.h usability… no
checking ffi.h presence… no
checking for ffi.h… no
checking for forwarding callback in runtime… no
checking FFI library usage… none
You do not have an up-to-date libobjc library installed
GNUstep requires libffi (or ffcall) and proper libobjc hooks to do
invocations and DO.
(This does not apply on apple-apple-apple systems where DO is
not compatible with other GNUstep systems.)
configure: WARNING: Incomplete support for ffi funtionality.
checking iconv support… yes, -liconv
checking for xml2-config… /usr/bin/xml2-config
checking for libxml – version >= 2.3.0… yes
checking libxml/SAX2.h usability… yes
checking libxml/SAX2.h presence… yes
checking for libxml/SAX2.h… yes
checking for xsltApplyStylesheet in -lxslt… yes
checking libxslt/xslt.h usability… yes
checking libxslt/xslt.h presence… yes
checking for libxslt/xslt.h… yes
checking for libgnutls-config… no
checking for libgnutls – version >= 1.4.0… no
*** The libgnutls-config script installed by libgnutls could not be found
*** If libtgnuls was installed in PREFIX, make sure PREFIX/bin is in
*** your path.
no
You do not appear to have usable libgnutls headers/library.
Building without them will disable SSL/TLS/HTTPS in NSStream
and NSURLConnection.
If you really want to build gnustep-base without TLS support,
add –disable-tls to the configure arguments.
configure: error: Missing support for TLS functionality.
Your make error is because you didn’t set up your environment, by sourcing
/Library/GNUstep/Makefiles/GNUstep.sh
after installing gnustep-make. Your build error is, as the error message makes explicit, the result of not having GNUTLS installed. You can get GNUTLS from homebrew, macports and the usual suspects.i have have the GNUTLS installed. but i sent u and email about libObjc error, ffi?
Please don’t mix up email and public comment threads, no-one but us two can see the emails. Your configure error this time was that you don’t have libffi installed. Before going any further, please: