Friday, April 17, 2009
NSConference: the aftermath
It seems that my presentation and my Xcode top tip[*] went down really well, so thanks to all the attendees for being a great audience, asking thoughtful and challenging questions and being really supportive. It's been a couple of years since I've spoken to a sizable conference crowd, and I felt like everyone was on my side and wanted the talk - and indeed the whole conference - to be a success.
So yes, thanks to Scotty and Tim, Dave and Ben, and to all the speakers and attendees for such a fantastic conference. I'm already looking forward to next year's conference, and slightly saddened by having to come back to the real world over the weekend. I'll annotate my Keynote presentation and upload it when I can.
[*] Xcode "Run Shell Script" build phases get stored on one line in the project.pbxproj file, with all the line breaks replaced by \n. That sucks for version control because any changes by two devs result in a conflict over the whole script. So, have your build phase call an external .sh file where you really keep the shell script. Environment variables will still be available, and now you can work with SCM too :-).
Friday, April 03, 2009
Controlling opportunity
The Rational Unified Process goes for the slightly more neutral term Change Request Management, but the documentation seems to imply the same opinion, that it is the ability to make change requests which must be limited. The issue is that many requests for change in software projects are beneficial, and accepting the change request is not symptomatic of project failure. The most straightforward example is a bug report - this is a change request (please fix this defect) which converts broken software into working software. Similarly, larger changes such as new requirements could convert a broken business case into a working business case; ultimately turning a failed project into a revenue-generator.
In my opinion the various agile methodologies don't address this issue, either assuming that with the customer involved throughout, no large change would ever be necessary, or that the iterations are short enough for changes to be automatically catered for. I'm not convinced; perhaps after the sixth sprint of your content publishing app the customer decides to open a pet store instead.
I humbly suggest that project managers replace the word "control" in their change documentation with "opportunity" - let's accept that we're looking for ways to make better products, not that we need excuses never to edit existing Word files. OMG baseline be damned!
Wednesday, March 04, 2009
On noodles
Steph, who is a very good musician and knows what she's talking about, wrote that there are two ways to play a harp, a "get the music right" recitation style and a "get the rhythm right and everything else follows" style more suited to improvisation, noodling or folk playing.
That's not only true of the harp, it seems to hold for many instruments. For instance, in a moment of crazed, um, craziness this weekend I bought what's commonly referred to as a lute. In fact, a lute with much in common with this lute. Now I've been playing it for all of about two hours in total since Saturday, and can barely remember what note each course plays, and do a poor rendition of about four different tunes from a book of trivially simple lute tunes. But today marked an interesting transition, as it was the first day that I could make music up on the instrument without either knowing or concentrating on what I was doing. Only a couple of things (the song "Wooden Heart" made famous by Elvis Presley, and that banging dance-floor filler "Parson's Farewell") but this represented the point where I could make music on the lute - a different skill than remembering where and when to stick fingers on some bits of nylon, steel and wood.
And I think that's where the root of Steph's distinction of playing techniques really comes from; the unprepared style relies on having some music that needs to occur, and the ability for your hands (or nose or whatever your instrument is played with) to move around in some way which causes that music to exist. Whereas the prepared style relies on having some performance in mind that must be repeated, and requires that you think about moving $appendage in such-and-such way to recreate that performance. I find the distinction in conscious application to be an important one when playing the fiddle, an instrument I'm marginally better at than the lute. If I'm reading some music, playing solo or otherwise engaged in trying to play music, then I can only play whatever notes the music contained and in a fairly uninteresting manner. It's only if I'm able to relax and not think about the music that I can harmonise, ornament and otherwise play more interesting things than what was written on the page - even if not necessarily particularly well :-).
Monday, February 23, 2009
Cocoa: Model, View, Chuvmey
Chuvmey is a Klingon word meaning "leftovers" - it was the only way I could think of to keep the MVC abbreviation while impressing upon you, my gentle reader, the idea that what is often considered the Controller layer actually becomes a "Stuff" layer. Before explaining this idea, I'll point out that my thought processes were set in motion by listening to the latest Mac Developer Roundtable (iTunes link) podcast on code re-use.
My thesis is that the View layer contains Controller-ey stuff, and so does the Model layer, so the bit in between becomes full of multiple things; the traditional OpenStep-style "glue" or "shuttle" code which is what the NeXT documentation meant by Controller, dynamic aspects of the model which could be part of the Model layer, view customisation which could really be part of the View layer, and anything which either doesn't or we don't notice could fit elsewhere. Let me explain.
The traditional source for the MVC paradigm is Smalltalk, and indeed How to use Model-View-Controller is a somewhat legendary paper in the use of MVC in the Smalltalk environment. What we notice here is that the Controller is defined as:
The controller interprets the mouse and keyboard inputs from the user, commanding the model and/or the view to change as appropriate.
We can throw this view out straight away when talking about Cocoa, as keyboard and mouse events are handled by NSResponder, which is the superclass of NSView. That's right, the Smalltalk Controller and View are really wrapped together in the AppKit, both being part of the View. Many NSView subclasses handle events in some reasonable manner, allowing delegates to decorate this at key points in the interaction; some of the handlers are fairly complex like NSText. Often those decorators are written as Controller code (though not always; the Core Animation -animator proxies are really controller decorators, but all of the custom animations are implemented in NSView subclasses). Then there's the target-action mechanism for triggering events; those events typically exist in the Controller. But should they?
Going back to that Smalltalk paper, let's look at the Model:
The model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller).
If the behaviour - i.e. the use cases - are implemented in the Model, well where does that leave the Controller? Incidentally, I agree with and try to use this behavior-and-data definition of the Model, unlike paradigms such as Presentation-Abstraction-Control where the Abstraction layer really only deals with entities, with the dynamic behaviour being in services encapsulated in the Control layer. All of the user interaction is in the View, and all of the user workflow is in the Model. So what's left?
There are basically two things left for our application to do, but they're both implementations of the same pattern - Adaptor. On the one hand, there's preparing the Model objects to be suitable for presentation by the View. In Cocoa Bindings, Apple even use the class names - NSObjectController and so on - as a hint as to which layer this belongs in. I include in this "presentation adaptor" part of the Controller all those traditional data preparation schemes such as UITableView data sources. The other is adapting the actions etc. of the View onto the Model - i.e. isolating the Model from the AppKit, UIKit, WebObjects or whatever environment it happens to be running in. Even if you're only writing Mac applications, that can be a useful isolation; let's say I'm writing a Recipe application (for whatever reason - I'm not, BTW, for any managers who read this drivel). Views such as NSButton or NSTextField are suitable for any old Cocoa application, and Models such as GLRecipe are suitable for any old Recipe application. But as soon as they need to know about each other, the classes are restricted to the intersection of that set - Cocoa Recipe applications. The question of whether I write a WebObjects Recipes app in the future depends on business drivers, so I could presumably come up with some likelihood that I'm going to need to cross that bridge (actually, the bridge has been deprecated, chortle). But other environments for the Model to exist in don't need to be new products - the unit test framework counts. And isn't AppleScript really a View which drives the Model through some form of Adaptor? What about Automator…?
So let me finish by re-capping on what I think the Controller layer is. It's definitely an adaptor between Views and Models. But depending on who you ask and what software you're looking at, it could also be a decorator for some custom view behaviour, and maybe a service for managing the dynamic state of some model entities. To what extent that matters depends on whether it gets in the way of effectively writing the software you need to write.
Monday, February 09, 2009
When techs collide
Such a combination I found today, when I mixed a little bit of Distributed Objects with a soupçon of Cocoa Bindings to create, um, Distributed Bindings (calling it Cocoa Objects would just be rude).
It's actually just as simple as you think it will be, so there's no point in any sample code. You can basically use the answer to the FAQ question on DO. Once you've got the proxy object in the client, use it as the observable controller in -bind:toObject:withKeyPath:options:. And that's it!
Well, not quite it. You'll notice that things are a wee bit crashy, which is why this is somewhat like crossing the streams. Both Bindings and DO use the Proxy pattern to achieve their magic, but because the two systems have no special knowledge of each other the proxy connections are not kept in sync. If your server object mutates after the DO connection disappears, then it tries to send a KVO notification to an object that's no longer there…boom. Having a client-server system where the client can crash the server is of, well, dubious utility. There are some things that you could do to mitigate this, for instance looking for NSConnectionDidDieNotification (in the server) or opening a heartbeat RPC for the client to "check in" with the server. These fixes will work perfectly, if the vended object is updated predictably enough that you can reliably take care of broken connections between KVO notifications. Without that you're SoL, as the server won't reliably get a DO exception - more often than not it'll segfault. But while this may be unstable, it still is damned cool.
Monday, February 02, 2009
A lack of CocoaHeads
Saturday, January 24, 2009
Most favouritest and least favourite Macs
Obviously my Mac use comes as a result of Mac OS X, so neither of my choices are particularly old machines. My favourite is a definite thing, and it's the first Mac I ever bought myself - a PowerMac G4 Sawtooth. I didn't own it from new; I bought it from a contractor who was writing a WebObjects app for us when I worked at the University. It was a "G4 Server" according to the sticker, which really just meant that it came with a SCSI adaptor fitted standard, and the pièce de resistance: Mac OS X Server 1.2 installed :-). The 1.x series of MOSES (Mac OS Enterprise Server) was a release of Rhapsody, a straight port of OPENSTEP to the PowerPC with a couple of changes. Most noticable were the configuration of startup items, the platinum UI and some changes to the Workspace to make it a little more similar to the Mac OS Finder. The 450MHz G4 I had was blazingly fast in this OS, and none too shabby when it came to more modern OS X too. When I finally sold it on it was running 10.4.
My least favourite is less clear-cut, I have a choice of two. But I think I'm going to give it to the Beige G3 Power Mac I borrowed long-term, I think from the University, when I was a student. This was really a slightly updated Power Mac 8600 with a faster CPU in, but the CPU's capabilities were significantly limited by the architecture (50MHz bus, 5MBPS SCSI) which really belonged to the older 603-alike processors. I seem to remember it having some weird amount of memory, like 208MB, because I'd scrounged different chips from different places, but even with that much RAM it couldn't do more than crawl in OS X 10.0-10.2. As with the G4 I installed Server 1.2, but many of the Java components really were staggeringly slow on this system.
Saturday, January 03, 2009
Quote of the year (so far)
"Best practices" is the most impressive way to spell "mediocrity" I've ever seen.
I couldn't agree more. Oh, wait, I could. *thud* There it goes.
Friday, January 02, 2009
Tautology of the year (so far)
A recent wave of fatwas issued by radical Islamic religious leaders in that region authorizing these groups to use cyberattacks to defend Islam has opened the door for these groups to wage cyberattacks, according to iDefense.
In other news, water has been found to be wet. (seriously considering a "my beloved language, you've killed it!" tag)
Thursday, January 01, 2009
Quick antispam observation
Now, some of these sites - and I've been notifying the owners as I go - give you a different failure message if you get your password wrong or your e-mail address. This is, to quote the twitterverse, made of fail. It means these websites can be used to automatically generate lists of the members' e-mail addresses; useful to spammers, phishers (remember that the list is based on being a member of a particular site, so it's easy to target the phish at that site) and even for later trying to compromise accounts on that site. I'd really avoid being a member of any site whose login page worked like that, and try to get them to change their error messages.
What's new in 2009
It looks to me like the most popular pieces on this blog are the opinions and how-tos regarding Cocoa development, particularly my thoughts on properties and Cocoa memory management round-up. Don't worry, there's definitely more of this coming. As well as preparing for this Mac Developer Network conference talk I've been discussing recently, I've got another exciting - and unfortunately secret - project on the go now which should see plenty of collateral blog posting in the first half of the next year, all about Cocoa development. There'll also be a bit more of an iPhone mix-in; obviously for much of last year the SDK either didn't exist or was under non-disclosure, but now I've got more reasons to be using Cocoa Touch it will also be mentioned on here. I shall also be delving a bit deeper into Darwin and xnu than I have in previous times.
One example of Cocoa-related information is meetup announcements; I'm still involved in the local CocoaHeads chapter and I'll endeavour to post an advance warning for each meeting here. I know many of my readers are in the States but a few of you are local so please do come along! In fact, if you're not local (or "bissen't from rond theez partz", as we say here) then consider going to your nearest CocoaHeads or starting a new one. It's a great way to find out who's working on Mac or iPhone development in your area, share tips and stories and build up that professional contacts network.
Previously I've been concerned that readers here at iamleeg don't seem interesting in commenting on my posts, but these days I'm no longer worried. I can tell how many people are reading, and of those how many are regulars, and I have to say that the blog is doing pretty damn well. Of course, if you do feel inclined to join in the discussion (particularly if I've got something wrong, or missed an important point from a post) then you should feel perfectly at liberty to leave a comment.
Finally, have a happy new year!
Monday, December 22, 2008
Cocoa Memory Management
In fact, I've already answered this question myself, as How does reference counting work? As mentioned in the FAQ, I actually answered the question "how do I manage object lifecycles in (Cocoa|GNUstep|Cocotron)"? It's actually a very violently distilled discussion, so it's definitely worth checking out the references (sorry) below.
Apple have a very good, and complete, Memory Management Programming Guide for Cocoa. They also provide a Garbage Collection Programming Guide; remember that Objective-C garbage collection is opt-in on 10.5 and above (and unavailable on iPhone OS or earlier versions of Mac OS X). GNUsteppers reading along should remember that the garbage collector available with the GNU objc runtime is entirely unlike the collector documented in Apple's guide. GNUstep documentation contains a similar guide to memory management, as well as going into more depth about memory allocation and zones. Apple will also tell you how objects in NIBs are managed.
The article which gave me my personal eureka moment was Hold Me, Use Me, Free Me by Don Yacktman. Stepwise has another article, very simple rules for memory management in Cocoa by mmalc, which is a good introduction though with one caveat. While the table of memory management methods at the top of the article are indeed accurate, they might give you the impression that keeping track of the retain count is what you're supposed to be doing. It's not :). What you're supposed to be doing is balancing your own use of the methods for any given object, as described in rules 1 and 2 of "Retention Count rules" just below that table.
James Duncan Davidson's book "Learning Cocoa with Objective-C" has not been updated in donkey's years, but its section on memory management is quite good, especially the diagrams and the "rules of thumb" summary. Luckily, that section on memory management is the free sample on O'Reilly's website.
If reading the theoretical stuff is all a bit too dry, the Mac Developer Network have a rather comprehensive memory management training video which is $9.99 for non-MDN members and free for paid-up members.
Finally, Chris Hanson has written a good article on interactions between Cocoa memory management and objc-exceptions; if you're using exceptions this is a good discussion of the caveats you might meet.
Wikipedia == fail
This is from the Susie Dent entry discussion page:
IMDb relies on the contributions of the public, so isn't an overly reliable source.
Sunday, December 21, 2008
better security, not always more security
Specifically, I wondered whether I should add discussion of the authentication capabilities in PDO to the FAQ entry. Not that it's frequently asked - indeed, it's a NAQ - but because getting mentions of security into a Usenet FAQ is likely to cause newbies to be thinking about security, which is possibly a good thing (for the world, not so much my uniquely employable attributes). But I decided no, though the subject is interesting, it's not because of the technicality, but the philosophy.
Distributed Objects works by sending NSPortMessage messages over NSConnection connections. The connections and message-passing bumph are peer-to-peer, but DO adds some client-server distinction by having servers register their vended connections with name servers and clients look up the interesting vendors in said name servers. By default, anything goes; all connections are honoured and all clients serviced. There are two security features (both implemented as delegate methods) baked into DO, though. The most interesting of the two is the authentication.
The reason that the authentication feature is interesting is that it's implemented in such a way as to make non-security-conscious developers question the security. The end sending the NSPortMessage includes some data based on the constituent parts of the message, and the end receiving the message decides whether to accept it based on knowledge of the constituents and of the data. On the face of it, this looks like shared-secret encryption, with the shared secret being the algorithm used to hash the port message. It also appears to have added no security at all, because the message is still sent in plain text. In fact, what this gives us is more subtle.
All that we know is that given the source information and the sender's authentication data, the receiver gets to decide whether to accept the sender's message. We don't necessarily know the way that the receiver gets to that decision. Perhaps it hashes the information using the same algorithm as the sender. Perhaps it always returns YES. Perhaps it always expects the authentication data to be 42. On the other hand, perhaps it knows the public key of the sender, and the authentication data is a signature derived from the content and the sender's private key. Or perhaps the "authentication data" isn't used at all, but the source material gives the server a chance to filter malicious requests.
Now all of that is very interesting. We've gone from a system which looked to be based on a shared secret, to one which appears to be based on whichever authentication approach we decide is appropriate for the task at hand. Given a presumed-safe inter-process link, we don't need to be as heavyweight about security as to require PKI; whereas if the authentication were provided by a secure tunnel such as DO-over-SSL, we'd have no choice but to accept the cost of the PKI infrastructure. Given the expectation of a safe server talking to hostile clients, the server (or, with some amount of custom codery, a DO proxy server) can even sanitise or reject malicious messages. Or it could both filter requests based on authentication and on content. The DO authentication mechanism has baked in absolutely zero policy about how authentication should proceed, by letting us answer the simple question: should this message be processed? Yes or no? Choose an approach to answering this question based not on what you currently believe could never be circumvented, but on what you currently believe is sufficient for the environment in which your DO processes will live. If a shared secret is sufficient and adds little overhead, then do that, rather than 4096-bit asymmetric encryption.
By the way, the second security feature in DO is the ability to drop a connection when it's requested. This allows a DO server to survive a DoS, even from a concerted multitude of otherwise permissible clients.
Thursday, December 11, 2008
Whither the codesign interface?
Well, actually, it's not so much about how I can use code signatures, but how the subset of Clapham Omnibus riders who own Macs (a very small subset, as the combination of overheating batteries in the old G4 PowerBooks and combustible bendy-busses means they don't stay around very long) can use code signatures. Unfortunately, the answer seems to currently be "not by much", with little impression of that changing. The code signing process and capability is actually pretty damned cool, and a nice security feature which I'll be talking about at MacDev 09. It's used to good effect in the iPhone, where it and FairPlay DRM are part of that platform's locked-down execution environment.
The only problem is, there's not much a user can do with it. It's pretty hard to find out who signed a particular app, in fact the only thing you can easily do is discover that the same entity signed two versions of the same app. And that's by lack of interface, not by any form of dialogue or confirmation. That means that when faced with the "Foobar app has changed. Are you sure you still want to allow it to [whatever]" prompt, many users will be unaware of the implications of the question. Those who are and (sensibly) want to find out why the change has occurred will quickly become frustrated. Therefore everyone's going to click "allow", which rather reduces the utility of the feature :-(.
Is that a problem yet? Well, I believe it is, even though there are few components yet using the code signature information in the operating system. And it's precisely that allow-happy training which I think is the issue. By the time the user interfaces and access control capabilities of the OS have developed to the point where code signing is a more useful feature (and believe me, I think it's quite a useful one right now), users will be in the habit of clicking 'allow'. You are coming to a sad realisation; allow or deny?
Monday, December 01, 2008
You keep using that word. I do not think it means what you think it means.
Security has a much wider scope than keeping bad people out. A system (any system, assume I'm talking software but I could equally be discussing a business process or a building or something) also needs to ensure that the "good" people can use it, and it might need to respond predictably, or to demonstrate or prove that the data are unchanged aside from the known actions of the users. These are all aspects of security that don't fit the usual forbiddance definition.
You may have noticed that these aspects can come into conflict, too. Imagine that with a new version of OS X, your iMac no longer merely takes a username and password to log a user in, but instead requires that an Apple-approved security guard - who, BTW, you're paying for - verifies your identity in an hour-long process before permitting you use of the computer. In the first, "hacker-proof" sense of security, this is a better system, right? We've now set a much higher bar for the bad guys to leap before they can use the computer, so it's More Secure™. Although, actually, it's likely that for most users this behaviour would just get on one's wick really quickly as they discover that checking Twitter becomes a slow, boring and expensive process. So in fact by over-investing in one aspect of security (the access control, also sometimes known as identification and authorisation) my solution reduces the availability of the computer, and therefore the security is actually counter-productive. Whether it's worse than nothing at all is debatable, but it's certainly a suboptimal solution.
And I haven't even begun to consider the extra vulnerabilities that are inherent in this new, ludicrous access control mechanism. It certainly looks to be more rigorous on the face of things, but exactly how does that guard identify the users? Can I impersonate the guard? Can I bribe her? If she's asleep or I attack her, can I use the system anyway? Come to that, if she's asleep then can the user gain access? Can I subvert the approval process at Apple to get my own agent employed as one of the guards? What looked to be a fairly simple case of a straw-man overzealous security solution actually turns out to be a nightmare of potential vulnerabilities and reduced effectiveness.
Now I've clearly shown that having a heavyweight identification and authorisation process with a manned guard post is useless overkill as far as security goes. This would seem like a convincing argument for removing the passport control booths at airports and replacing them with a simple and cheap username-and-password entry system, wouldn't it? Wouldn't it?
What I hope that short discussion shows is that there is no such thing as a "most secure" applications; there are applications which are "secure enough" for the context in which they are used, and there are those which are not. But the same solution presented in different environments or for different uses will push the various trade-offs in desirable or undesirable directions, so that a system or process which is considered "secure" in one context could be entirely ineffective or unusable in another.
Free apps with macdev ticket
Sunday, November 23, 2008
Some bloody genius
Tuesday, November 04, 2008
More on MacDev
I'm already getting excited about the conference, not only because it'll be great to talk to so many fellow Mac developers but due to the wealth of other sessions which are going to be given. All of them look really interesting though I'm particularly looking forward to Bill Dudney's Core Animation talk and Drew McCormack's session on performance techniques. I'm also going to see if I can get the time to come early to the user interface pre-conference workshop run by Mike Lee; talking to everyone else at that workshop and learning from Mike should both be great ways to catch up on the latest thoughts on UI design.
By the way, if you're planning on going to the conference (and you may have guessed that I recommend doing so), register early because the tickets are currently a ton cheaper. Can't argue with that :-).