Tuesday, July 29, 2008

Cocoa#, Mono and Me

My great application:


Currency Converter.net


Yeah, OK, not so great. But this Inverse Hoffman is the result of a couple of hours hacking in Mono, with Cocoa#. My app's largely based on the Stupid Word Counter tutorial, though it's a from-scratch implementation of the famous Apple/NeXT sample application in C#.


Firstly, a little history. My first encounter with .NET was back in about 2003 at a Microsoft Developer Roadshow in the car park (and later lecture theatre) in Oxford's comlab. I was particularly interested in their discussions of cross-platform capability, Project Rotor (I kept in touch with one of the Rotor developers) and so on, but really didn't see much exciting in .NET. Nonetheless, being a fair man, I took my beta CDs of Windows 2003 and Visual Studio .NET and gave them a whirl. Unfortunately, still not much interesting. Largely due to buggy betas and a lack of beta documentation.


Now accessing Cocoa from non-ObjC languages is nothing new, we've been doing it from Perl, Python, Ruby and Java for ages and partcularly old farts might even remember Objective-Tcl. Why should I care about Cocoa#? Well for a start, there are likely to be a lot Windows developers out there with some (language that boils down to MS IL eventually) skills who are wanting to produce Mac applications, and it'd be interesting to see what we'll end up with when they do. And it's always fun to learn a new language, anyway ;-)


Good points


  • Real NIB files. No really, that interface is genuinely an IB 3.x NIB based on the Cocoa Application template. The objects inside it are Objective-C objects, and there are good old outlets and actions (I haven't yet investigated whether Cocoa Bindings would work).

  • macpack. A command-line tool which takes your IL executable and wraps it up in a Cocoa application bundle, ready for drag-deployment.

  • Good inline bridging information. Unlike, say, PyObjC the language bridge isn't completely dynamic, but unlike the Java bridge or JIGS you don't have to keep a separate manual mapping of real classes onto ObjC shams. For instance, here's the controller from Currency Converter.net, complete with class, ivar and method exports:

namespace info.thaesofereode.CurrencyConverter
{
[Cocoa.Register("CurrencyConverterController")]
public partial class CurrencyConverterController : Cocoa.Object
{
public CurrencyConverterController(System.IntPtr native_object) : base(native_object) {}

//Cocoa IBOutlets
[Cocoa.Connect]
private Cocoa.TextField inputCurrency;
[Cocoa.Connect]
private Cocoa.TextField outputCurrency;
[Cocoa.Connect]
private Cocoa.TextField conversionRate;

//Cocoa IBAction
[Cocoa.Export("calculate:")]
public void calculate(Cocoa.Object sender)
{
//get the rate from the view
System.String rate = conversionRate.Value;
CurrencyConverterModel.Rate = System.Convert.ToDouble(rate);
//get the currency
System.String input = inputCurrency.Value;
System.Double output = CurrencyConverterModel.convert(System.Convert.ToDouble(input));
//update the UI
outputCurrency.Value = System.Convert.ToString(output);
}
}
}

Bad points


  • Not very Cocoa-like wrapper classes. I think this is deliberate; they've gone for making the Cocoa shim look like a .NET interface because after all, we're programming from .NET. This is a bit disappointing as I'm more familiar with PyObjC and the Perl-ObjC-Bridge where the APIs are left pointedly alone, but given the target audience of Cocoa# it's unsurprising.

  • MonoDevelop. Luckily, using it isn't mandated.

So, overall, one more good point than bad (and a tentative two, if you overlook MonoDevelop); a pretty good initial evaluation and I might give this a deeper scrape.

Tuesday, July 22, 2008

Microblogging

For a long time, I deliberately avoided microblogs like twitter. I thought that they were simply an acknowledgement that people want to be published more than they want to have something to say. However, it would be rude of me to completely disavow the medium without actually giving it a go.

To that end, I may indeed be iamleeg on twitter, as soon as twitter actually finishes processing the signup form.

I'd like to point out that one problem I'm going to have is brevity - I have spent 650 characters telling you what my username is. Constraining myself to SMS-sized wibblings will indeed be tricksy.

Monday, July 21, 2008

Common sense writ large

Looking at the bottom of Apple's Q3 results, as indeed with any similar publication from a US publicly-traded company, we see the following text.

This press release contains forward-looking statements including without limitation those about the Company’s estimated revenue and earnings per share. These statements involve risks and uncertainties, and actual results may differ. Risks and uncertainties include without limitation potential litigation from the matters investigated by the special committee of the board of directors and the restatement of the Company’s consolidated financial statements; unfavorable results of other legal proceedings; the effect of competitive and economic factors, and the Company’s reaction to those factors, on consumer and business buying decisions with respect to the Company’s products; war, terrorism, public health issues, and other circumstances that could disrupt supply, delivery, or demand of products; continued competitive pressures in the marketplace; the Company’s reliance on sole service providers for iPhone in certain countries; the continued availability on acceptable terms of certain components and services essential to the Company’s business currently obtained by the Company from sole or limited sources; the ability of the Company to deliver to the marketplace and stimulate customer demand for new programs, products, and technological innovations on a timely basis; the effect that product transitions, changes in product pricing or mix, and/or increases in component costs could have on the Company’s gross margin; the effect that product quality problems could have on the Company’s sales and operating profits; the inventory risk associated with the Company’s need to order or commit to order product components in advance of customer orders; the effect that the Company’s dependency on manufacturing and logistics services provided by third parties may have on the quality, quantity or cost of products manufactured or services rendered; the Company’s dependency on the performance of distributors and other resellers of the Company’s products; the Company’s reliance on the availability of third-party digital content; and the potential impact of a finding that the Company has infringed on the intellectual property rights of others. More information on potential factors that could affect the Company’s financial results is included from time to time in the Company’s public reports filed with the SEC, including the Company’s Form 10-K for the fiscal year ended September 29, 2007; its Forms 10-Q for the quarters ended December 29, 2007 and March 29, 2008; and its Form 10-Q for the quarter ended June 28, 2008, to be filed with the SEC. The Company assumes no obligation to update any forward-looking statements or information, which speak as of their respective dates.

Erm, like, duh. Stuff which we say might happen in the future, might not actually happen. Really? You've got to get out of the financial industry, there's a lucrative career ahead of you in construction.

Friday, July 18, 2008

Designing a secure Cocoa application

That's the title of next month's CocoaHeads Swindon, and I'll be leading the presentation/discussion. So if you want to learn a little about how to ensuring your Cocoa app doesn't give away the keys to the kingdom, or have some experiences to share with the rest of the group, come along! We'll be at the Glue Pot, which is nice and near the train station as well as reasonably close to a car park. We'll be congregating at 7:00 but will wait for everyone to be settled with a beer in their hand before starting ;-).

Monday, July 14, 2008

Ah, the sweet sound of my own voice

The title is a linky to the press release regarding the edition of Sophos Podcasts I recorded with Carole, and which has now (clearly) gone live. In it we mainly talk about the data theft and Macs technical paper I've already posted about. This is the first podcast I've ever been involved in, so any feedback you have (apart from telling me that I sound drunk in my first sentence, I'm not sure what that's all about) will be most welcome!

Tuesday, July 08, 2008

CocoaHeads Swindon

Just got back from the first meeting of Swindon CocoaHeads, featuring a bunch of people who live nowhere near Swindon, some good beer and the occasional discussion of Cocoa. Special mention to Scott who came all the way from sunny Warsaw to be with us!

Tonight's event was an informal, "what do we want from Swindon CocoaHeads?" event, but it looks like being successful enough that we'll be doing it again. The format will be a presentation or directed conversation, followed by general chit-chat about all things Cocoa. In fact, um, I may have volunteered to give the first presentation at the next meeting. The subject is: well, that would be telling, wouldn't it… ;-). You'll have to find out by coming along to the Glue Pot in Swindon at 8pm on Monday, August 4th. Look out for further announcements and a mailing list over at Scotty's place in the forthcoming month!

Tuesday, June 24, 2008

Objective-C NAQs

Never-Asked Questions :-)

In Code Complete 2 §6.5, Steve McConnell presents a list of class-related design issues that "vary significantly depending on the language". So why don't we look at them for Objective-C? Especially as I can't find anyone else who's done so based on a couple of Google searches… N.B. as ever, I'm really considering Cocoa + Objective-C here, as the language itself doesn't provide enough policy for many of the issues to have an answer (only method resolution and the existence of isa are defined by the runtime and the compiler - ignoring details like static string instances, @protocol and so on).

Behaviour of overridden constructors and destructors in an inheritance tree. Constructors are simple. If you can initialise an object, return it. If you can't, return nil. The -[NSObject init] method is documented as simply returning self.

For destructors, we have to split the discussion into twain; half for garbage collection and half for not. In the world of the Apple GC, destruction is best done automatically, but if you need to do any explicit cleanup then your object implements -finalize. The two rules are that you don't know whether other objects have already been finalized or not, and that you must not resurrect your object. In the world of non-GC, an object is sent -dealloc when it has been released enough times not to stick around. The object should then free any memory claimed during its lifetime, and finally call [super dealloc]. Note that this means objects which use the voodoo cohesion of "OK, I'll clean up all my resources in -dealloc" probably aren't going to work too well if the garbage collection switch is flipped.

Behaviour of constructors and destructors under exception-handling conditions. Exceptions are a rarity in Cocoa code (we didn't have language-level exceptions for the first decade, and then there was a feeling that they're too expensive; C++ programmers like the Leopard 64-bit runtime because ObjC exceptions and C++ exceptions are compatible but that's not the case in the NeXT runtime) but obviously a constructor is an atomic operation. You can either initialise an object or you can't; there's no half-object. Therefore if an -init… method catches, the thing to do is unwind the initialisation and return nil. The only thing I can think to say for having exceptions around destruction time is "don't", but maybe a commenter will have better ideas.

Importance of default constructors. All classes implement -init, except those that don't ;-). Usually if there's a parameterised initialiser (-initWithFoo:) then that will be the designated initialiser, and -init will just return [self initWithFoo: someReasonableDefaultValueForFoo];. If there's no reasonable default, then there's no -init. And sometimes you just shouldn't use -init, for instance NSNull or NSWorkspace.

Time at which a destructor or finalizer is called. See How does reference counting work? for a discussion of when objects get dealloced. In the garbage-collected world, an object will be finalized at some time after it is no longer reachable in the object graph. When that is exactly really depends on the implementation of the collector and shouldn't be relied on. Temporal cohesion ("B happens after A, therefore A has been done before B") is usually bad.

Wisdom of overriding the language's built-in operators, including assignment and equality. This is such a brain-damaged idea that the language doesn't even let you do it.

How memory is handled as objects are created and destroyed or as they are declared and go out of scope. How does reference counting work? How do I start using the garbage collector?

Tuesday, June 17, 2008

WWDC day crosspost

WWDC summary on SophosLabs blog, written by yours truly. I wonder how many Sophos readers (I should probably avoid the term sophist, shouldn't I?) have an interest in Mac and iPhone stuff (and subequently how many comment via the e-mail address on the Labs blog).

Monday, June 16, 2008

Local KDC on Leopard

via Nigel Kersten, a great description of the operation of Leopard's built-in local KDC. I think the most exciting thing about the local KDC is the Bonjour support; could we see simple cross-system trust in the near future? Could there be someone in the world who can actually make Kerberos simple?

Friday, June 13, 2008

WWDC day 00000000000000000000000000000101

Technically day five isn't over yet, but with just one session and a taxi ride remaining I doubt I'm going to get anything prematurely wrong here. In fact, I'm no longer entirely sure that I'll remain awake through the rest of the day so even if something entirely different does happen (still haven't heard anything about IXKit this millennium) I expect I'd miss it.

Planning an east-bound flight is always difficult, because an 11-hour flight through eight time zones "takes" 19 hours. So if I sleep on the plane I'll wake up in the middle of the afternoon UK time, and going back to sleep at newly-local night-time might be complicated. Conversely if I don't sleep on the plane then I won't be going to sleep until at least 9am currently-local time, for a total of about 28 hours uptime. I was just talking to someone who recommended fasting, I'm not sure whether it's worth going through that hardship for an unverified theory (stuff all of that "in the name of science" crap). The other option would be to go into work 3pm-11pm for the beginning of the week, I'm not sure everyone else will appreciate having their meetings moved to the middle of the night and I don't think the canteen's open that late either ;-).

Still, of the three WWDCs I've been to this is definitely in the top ten list of interesting and exciting WWDCs. There definitely still are fellow NeXT fans in the woodwork (actually, *tap* *tap* I think it's gypsum board) who worm their way out during these events, I guess that most have no motivation not to be working on Cocoa. Actually, I don't recall having seen Andrew Stone this week, and I know of a couple of other guys who aren't here, but have definitely managed to gain some traction for the phrase "NeXTSTEP Mobile ;-)

WWDC day four

Not so many sessions attended today - partly because I've reached the limit of what the human physiology can achieve on a diet of coffee and doughnuts. But also due to ducking out of sessions to meet with ex-NeXT guys, ex-Lighthouse guys and ex-colleagues for most of the afternoon. Of course, this was followed by the beer bash, no longer the campus bash which we all know and fondly remember (or at least we all fondly remember queueing for a couple of hours at each end for the coach) but still a good event. Speaking of ex-Lighthouse guys, Wylie and I spent a bit of time putting Sun's world to rights (essentially, if they were to stop diluting the Java brand, stop pulling themselves in every which way and try to make some money, they might do OK).

So tomorrow is the NeXT meetup at the beginning of lunch, I have a lab appointment at exactly 12 which is a little annoying but I'll try to make it over. If the G4 cube is the right shape, wrong CPU and Real Men's Objects use the NX prefix, then come over to the front of the Moscone West after the second session.

Thursday, June 12, 2008

WWDC: afp548 Venn competition

I, with some help from Ken and the guys, did a better job.

WWDC day three

Today was not quite a full day, so I managed to spend about an hour or so milling around Yerba Buena park, doing a little gift shopping and generally existing outside of the Mascarpone centre. Also put in another update to the c.l.o-c FAQ (though I didn't update the date! oops…) to better discuss retain/release memory management. There are still situations (GNUstep, Cocotron, and some particular OS X environments) where garbage collection is either unavailable or unsuitable, and it turns out that a lot of questions on either the group or cocoa-dev recently have been about the memory management system.

In the evening, after dinner at Chevy's with the u.c.s.m guys (and yet more discussion of the Sophos feature set), checked in to the Apple Design Awards for the first 30 mins or so. All of the winners (and runners-up) I saw were worthy applications, although it was interesting to note that while most of the "productivity" app winners were from small shops, both of the games (runner-up was Command and Conquer 3, winner was Guitar Hero 3) were from large studios, ports of Windows/console games and in existing long-running series. They're both great games, too, of course. Ian was, of course, rooting for Delicious Library 2, and sadly disappointed ;-).

This was all followed by the AFP548 beer bash over at Thirsty Bear. Yet more "oh, you're from Sophos? Yeah, let me say this one thing…", which I really enjoy because if something's either good or bad enough to be the subject of a beer-fuelled rant in a party, I should probably hear about it. Also submitted a couple of entries to Peter's "Leopard bug Venn diagram" contest; I'm not sure I could do a better job of describing the situation than that but for those who were there, I came up with: \Omega = "Closed/Duplicate" and \Omega = "NeXTSTEP 7.0".

Wednesday, June 11, 2008

WWDC aside

None of Perl, Cocoa or some weird XML toolkit came up with the "simple things simple, complex things possible" quote.

WWDC day 2

Tuesday is typically associated with "starting to learn stuff" at WWDC, and today was definitely spent learning stuff. Learning, for instance, that doughnuts are considered adequate breakfast material, or that if you are prepared to pay the tiny wi-fi fee at Starbucks you can get faster INTARWEBS than all the people on the steps outside the Mascarpone. It was also a day of nice food; I've just got back from dinner with Alex at the Chevy's, having had lunch with Michael at the Ozuma sushi restaurant. More discussing Sophos-for-Mac with customers and potential customers ensued (apparently we've saved some people from the "hell that is Norton", and I point out for legal purposes that that's a direct quote and not my own opinion or words), and I got some pretty good photos of the Bay Bridge and treasure island which I'll upload as soon as I locate the USB cable.

Tuesday, June 10, 2008

ObjC FAQ update

Added a question about the ObjC 2.0 garbage collector. Sorry it's been so long in coming! I'll try and add a few more ObjC 2.0 questions over the coming days.

WWDC - day one

The WWDC keynote is always an odd event to attend. It's put on for the benefit of the investors and the media, with the developers being invited purely to act as braying masses expressing their adulation for His Steveness. It's rare for any technical content to make it into the session, except in unavoidable cases such as the 2005 keynote. The focus of that was the Intel transition, so by necessity there had to be some technical justification of the switch.

With this in mind, it's not hard to see that the keynote can be a somewhat dull affair. Obviously as both an Apple customer and member of the "economic ecosystem" of the Mac, it's always good to be as informed as possible of the company's position and direction. That said, yesterday's keynote (no wi-fi in this hotel, so a late post) contained less of interest to me than usual.

As I mentioned I'm financially dependent on Apple (in an indirect sense of course; I'm paid to write Mac software for Sophos, therefore no Mac = no job at Sophos), though as I'm not an indie dev I have a bit more of a comfort buffer than many people. The enterprise iPhone video Steve showed was basically a backslap in front of the shareholders; look, there are people who really do use this stuff! Then the laundry list of every developer who's downloaded the SDK and managed to get something to compile; interesting to see the wealth of different domains into which the iPhone is entering, but seriously. Two demos, three tops. Not all four thousand of the known apps. Good to see TEH CHEAP being applied to the 3G iPhone, though; I may have to
have a discussion with Orange about a PAC when that's available.

Which left Mobile Me. This is actually a pretty cool reboot of iTools^W.Mac, OK it looks like there might be no more iCards but on the other hand the Mobile Me syncing is really beneficial. I can see that becoming more of a cash cow for Apple, though mainly because they opened it up to the PC; people who have an iPod and Windoze could buy MM to synchronise their contacts, mail and so on, as well as getting webmail access (and webmail access which doesn't suck balls as much as
Exchange's OWA, may I add). That then might make them more amenable to the Halo Effect and the purchase of a Mac down the line.

The rest of the day was interesting but obviously undisclosable, except for the evening I spent in a couple of bars down the financial district (the Golden%Braeburn event at 111 Minna, where I went with Steffi from BNR and a couple of Cocotron committers; then Dave's bar where I met Nigel and most of Apple UK). Conversation ranged from Sophos feature requests to the drinkability of American IPAs; all good stuff!

Monday, June 09, 2008

WWDC part 0

well, here it is, the pre-WWDC "I'm jetlagged so you have to put up with my wittering" post. I'm just waiting for a softwareupdate to finish so that I can go out with my camera, taking some early-morning pictures before heading off to stand in line for the Stevenote. I was out for beers with Ian and Neil last night, we'd all heard rumours of a 5 a.m. start to the queue. On the two previous occasions that I've been, 9 a.m. has been sufficient; but with the sellout nature of the event it's likely that the room will fill up rather quickly so we've compromised on a 7 a.m. start. Actually, forget the 5 a.m. nonsense, there's a line of overnight campers - I can't decide whether they're deliberately trying to re-enact a Joy of Tech cartoon, or actually have nothing to do with their lives.

Friday, June 06, 2008

This means business

This is the design of the business card I'll be taking to WWDC. Let's look at some notable features.



  • Photo in top left. I don't know about you, but I find it much easier to remember what someone looks like than who they are - this card is available so that people can combine the two.

  • Plenty of blank space. The back is also entirely empty and can be written on. When people exchange business cards there'll usually be some context, it can help you remember what that is if you write it down. For instance, I've got cards from previous WWDCs with handwritten notes like "webobjects employer", "bindings", "parallels openstep" and "huge hat" (bonus points for identifying all four).

  • Questionable source code snippit. This is a deliberate ploy to annoy fellow-developers with our compulsive attention to detail, thus helping to cement the meeting in their mind as well as providing an inoffensive conversation starter.

  • Minimal contextual detail. I'm pretty sure I won't get through all 250 cards in one sitting, so they ought to remain relevant for as long as possible.

Wednesday, June 04, 2008

Little hack to help with testing

Want the ability to switch in different test drivers, mock objects, or other test-specific behaviour? Here's a pattern I came up with (about a year ago) to do that in a GNUstep test tool, which can readily be used in Cocoa:


NSString *driverClassName = [[NSUserDefaults standardUserDefaults] stringForKey: @"Class"];
Class driverClass = NSClassFromString(driverClassName);
id myDriver = [[driverClass alloc] init];

With a healthy dose of no, seriously, don't do this in production code, you now have the ability to specify your test driver on the command-line like this:


$ ./myTestingTool -Class GLTestDriver

This uses the oft-neglected behaviour of NSUserDefaults, in which it parses the executable's command-line arguments to create a defaults domain, higher in priority than even the user's preferences file. You can use that behaviour in a graphical app too, where it comes in handy when working in Xcode. It then uses a combination of the runtime's duck typing and introspection capabilities to create an instance of the appropriate class.