Category Archives: Objective C

Cocoa Development Objective C OS X Personal Travel

See you at WWDC!

Apple kept everyone on tenterhooks this year by announcing WWDC 2012 very late – the second latest announcement ever in fact.

Like many other people (11,000 of them I hear, which is alarming given that there are only 5,000 tickets to the event) I signed up to WWDC Alerts,  which sent me an SMS message while I was having lunch, only a few minutes after the tickets went on sale. That I was lucky enough to bag myself a ticket has a lot to do with that – about 90 minutes later, they were all gone – so big thanks to fellow Brits Anthony Herron and Aaron Wardle for running that, completely free of charge too. Legends.

Apple picked a surprising time to announce the tickets, being as it was about 2am Pacific Time. Perfect for people like me in Europe – I’d expected to get the call late at night – but I imagine there are a lot of people on the west coast who are seething about this choice of timing.

I’ve never been to WWDC before, but this year was a perfect time to go, with the continued growth of SourceTree and the fact that I’m attending Atlassian Summit, which is held a couple of weeks before in San Francisco. So I’ll be heading over for Summit, hanging out in the Atlassian SF Office for a week, then heading down to WWDC. A pretty efficient trip :)

So, if you’re going to WWDC, Summit or are in the SF area generally around that time and want to say hi, look me up!

I’m also thinking about getting a short-term pre-paid SIM (preferably with data) for the 3 weeks I’m out there, if you have any suggestions on that front I’d love to hear them.

 

Cocoa Development Objective C OS X

Follow-up: OS X privilege escalation without using deprecated methods

I posted a few months ago about the problems I’d encountered with performing privileged actions from a Mac OS X app – in my case, installing a command line utility in /usr/local/bin – and that all the examples of this that I’d come across used an approach which was now deprecated. You can find my original post here:
Escalating privileges on Mac OS X securely, and without using deprecated methods.

I had failed to produce a shrink-wrapped working example to go with the discussion, primarily because extracting it into a standalone example would take a while and I made the post a couple of days before I went on holiday. I also didn’t know whether anyone else actually cared about the subject enough for it to be worth me doing it!

Well, perhaps I should have known better, because I’ve had quite a few requests for such an example since then :) I finally got around to doing this at the weekend – and actually when I came to do it I understood why people had pestered me for it, because it took me a while to get things configured just right in a fresh project! Mostly, it’s that there are quite a few things that can go wrong outside the code, both in the project settings and the plists because of the code signing requirements.

So anyway, here’s the project: PrivilegedHelperExample on Bitbucket. Please make sure to check the ReadMe.txt – despite being shrink-wrapped, you will need to add your own code signing identity before you can compile the code, and you will need to reflect the name of your certificate in a few places, which I’ve listed. I’ve also tried to point you at the relevant pain points you may encounter when replicating the result in a different project.

The majority of this code is just the Apple example code from BetterAuthorizationSample and SMJobBless, grafted together, de-duplicated and tweaked. All the changes I made can be considered public domain.

Enjoy!

Cocoa Development Objective C OS X

Escalating privileges on Mac OS X securely, and without using deprecated methods

This week I implemented a much-requested feature in SourceTree for the upcoming 1.3 release (beta 1 went out on Monday, this will make it into beta 2) – a command-line tool so you can quickly pull up SourceTree for the repository you’re in from a terminal. Writing the command-line tool was trivial, but when I came to implement the menu item which would install it in /usr/local/bin, which inherently needs privilege escalation, it turned out to be a lot more complicated than I expected.

How so? Surely lots of people have done this sort of thing before? Well, that’s true, they have – but the problem is that just about all of the existing examples of this use the Authorization Services API call AuthorizationExecuteWithPrivileges – and this method is deprecated in OS X 10.7 (Lion). Now, of course that doesn’t stop you using it (yet), provided you’re willing to turn off the warning that building against the 10.7 SDK gives you, but any programmer worth his salt should take deprecation as a hint that they should be looking for another way.

There are basically 3 ways to escalate privileges on OS X, and only one of them is now recommended:

  1. Use a helper tool which has its setuid bit set so that it runs as root. Risky if that tool gets compromised, and the setuid bit can be lost, needing reinstatement by another privileged task.
  2. Execute a command as root via AuthorizationExecuteWithPrivileges. As mentioned above, this is now deprecated, and again if a hacker compromises either the app or the tool being launched, bad things can happen.
  3. Ask Launch Services to install a privileged helper tool via SMJobBless. This helper is subsequently run by launchd as root when invoked via a Unix socket, and can perform privileged tasks. Importantly, code signing is verified at both ends by Launch Services at install time to prevent tampering with either binary.

Clearly option 3 was the way to go – the only ‘downside’ about it is that is does require that you have the ability to sign your application and helper tool. I already have valid code signing certificates because I deploy on the App Store, so this isn’t an issue (even though this functionality won’t actually be in the App Store version of SourceTree because Apple disallow installer behaviour there, I still sign with the same certs). In fact, the fact that I know my app and helper tool can’t be interfered with without the code signatures becoming invalid is very reassuring. Given that it only costs $99 per year to be on the Mac Developer Programme which allows you to get certificates (even if you don’t deploy on the App Store), it’s something serious developers should consider strongly.

SMJobBless is ideally suited to installing daemons, but it’s perfectly acceptable to install tools which run simple one-off tasks too. When setting up the plist for the helper, you specify that it is ‘OnDemand’, with no ‘KeepAlive’ which means it’s not started by Launch Services at startup, only when a Unix socket is opened, and shuts down very quickly if there’s no activity. Unfortunately the SMJobBless example doesn’t do anything except to show you how to install a tool, it doesn’t tell you how to implement that tool to do anything useful, or how to call it from your main application.

To see how to do that, you need to refer to BetterAuthorizationSample , which includes a re-usable library for this. Ironically though, this example uses AuthorizationExecuteWithPrivileges to install its helper (this example pre-dated its deprecation in favour of SMJobBless). So you have to remove all the code associated with installation; you won’t need it anyway since SMJobBless does that function better. You keep the rest which gives you a framework for implementing and calling the helper. So here’s what I did:

  1. Implement the installation of a privileged helper, based directly on the SMJobBless example. I needed to change the bundle IDs and the certificate CN’s to match my setup of course.
  2. Extend the plist files from SMJobBless to register the helper with a socket. This was basically a case of copying the settings from the BetterAuthorizationSample plists, which already does this.
  3. Bring in BetterAuthorizationSampleLib.c/.h to assist with implementation of the helper, and the code for calling it in the app, but remove everything in the ‘Installation’ section. This eliminates all the references to AuthorizationExecuteWithPrivileges – we’re doing the install with SMJobBless so don’t need that.
  4. Follow the BetterAuthorizationSample for the implementation of the helper, and the bit in the application where you call the helper to perform privileged operations.

So in my case, the following happens when you click ‘Install Command Line Tool’ in SourceTree:

  1. A privileged helper is installed in Launch Services using SMJobBless. OS X checks the code signatures on both ends to ensure that the helper and the application asking to install it are valid (must be signed with my cert, and that cert must be issued by Apple).
  2. A connection is opened to the privileged helper over a socket which causes launchd to start it up
  3. I ask the helper via the BetterAuthorizationSampleLib to install the command-line tool in /usr/local/bin. As an additional check, the helper validates via ‘codesign -v  -R=”conditions”‘ that this tool is code signed with my cert (again, must be issued by Apple) – this is to prevent anyone else sniffing out this socket and trying to use it to install other things. If that passes, it installs the command.

This is quite a long-winded process compared to just calling a ‘cp’ command via AuthorizationExecuteWithPrivileges, but it’s also a lot more secure, since a malicious person can’t alter any of the moving parts without invalidating the code signatures. You’re also insulated from future changes when inevitably AuthorizationExecuteWithPrivileges is removed entirely.

I apologise for the lack of a pre-packaged example here – I haven’t had time to extract one from my own implementation yet. However, as described above if you start with the SMJobBless sample and add-in the BetterAuthorizationSample, removing from the latter everything associated with installation, you’re basically there. If I get chance later I’ll post a shrink-wrapped example.

I hope that helps someone – I found there to be little information on this subject that was up-to-date, and lots of older information that was misleading so maybe this will save someone some time. Ideally, I hope Apple will combine the SMJobBless and BetterAuthorizationSample some time to produce a 10.7-compliant official example.

Cocoa Development Objective C Open Source OS X

SSSelectableToolbar

A common requirement in any Cocoa application is a preference pane style window where each toolbar item switches to a different view in the main window, resizing as necessary. I’ve used BWToolkit to do this in the past, which provides BWSelectableToolbar. However, there are a few issues with using BWToolkit:

  1. If you want to deploy on the Mac App Store, You have to customise it to remove all uses of private methods, since those are banned on the App Store.
  2. It sometimes crashes Interface Builder – usually not fatally but it can get awkward
  3. Sometimes it gets the window height slightly too tall when switching panes – I’ve patched it to try to cope with this but it still happens sometimes
  4. It relies on using IB plugins. XCode 4 does not support IB plugins anymore – although you can still build the code, you can’t edit the nibs anymore

I’ve just been coping with 1, 2 & 3 so far, but 4 was the killer which made me come up with my own alternative: SSSelectableToolbar.

With SSSelectableToolbar, you can still do the preference pane setup entirely within Interface Builder, but it doesn’t require any plugins. There are a couple of extra steps required because of this, but they’re not onerous and still better than setting it all up in code.

The license is permissive MIT, usage is in the README, and there’s an example demo to show how it works. I hope it’s useful to someone else too.

Business Cocoa Development Objective C OS X Personal

SourceTree, your Mac Git & Mercurial GUI, is 40% off this week

Since I’m trying to spread this news as far and wide as I can, I might as well say it here too :)

Since the approval light just went green on the Mac App Store, I’m happy to announce the launch of SourceTree 1.2! In celebration, I’m having a crazy-bonkers 40% off sale just for one week, so get it while it’s hot!

There’s loads of things that are new or improved in this release, but here are the headlines:

  • Support for GitHub, Bitbucket and Kiln APIs, so you can see your hosted projects inside SourceTree, clone from them, link them as remotes, and even create new projects if you want.
  • Streamlined and polished user interface – I specifically dedicated a lot of extra time in this release on making SourceTree easier on the eyes, and to streamline the layout and workflows better.
  • Performance - I thought SourceTree was already pretty fast, but I managed to find quite a few more places to trim the fat, and also parallelised more activities to make things feel more responsive. Everything feels snappier, and complex repositories benefit especially.
  • New Sidebar - I had previously resisted the need to emulate iTunes here, but once I had implemented it, I had to admit that I was wrong, and in fact this worked great. Provides lots of shortcuts to navigating and operating on branches, tags and remotes.
  • Stashing and Shelving - oft requested, now delivered :)
  • Customise Git and Mercurial – you can now use your system Git / Mercurial instead of SourceTree’s standard versions (which have been updated), and enable additional Mercurial extensions (at your own risk).
  • French and Japanese translations – local versions for our friends in far away (and not so far away) places, likely to be more to come in future. Big thanks to tuan_kuranes and mzch for their help with these two!
  • And the rest – just lots of little refinements too numerous to list. Examples: copying text from the diff panel, ‘git commit –amend’ support, close branches in Mercurial, switch tracking branches in Git

It’s quite a big update – one user remarked to me that they’d normally expect developers to charge an upgrade fee for something like this, but like all other SourceTree updates this is free to existing customers. I have no plans for any paid upgrades for some time yet, I just want to keep making SourceTree better, and hope that more people come onboard. Maybe it’s my open source background, but I like to keep iterating and continually improving things, based on what I want to do (I’m a daily SourceTree user myself), and on what people tell me they’d like to see. SourceTree 1.2 certainly won’t be the last update by far :)

When I look back 6 months at SourceTree 1.0, it’s incredible how much better it is as a product now, both visually and functionally. I’ve learned a ton of things while I’ve been developing it, and I continue to learn more all the time, and I can’t think of anything I’d rather be doing right now. Also, my wife Marie re-designed many of the icons for 1.2 (and I think you’ll agree they’re a lot nicer) – that was fun to do as a joint project, even if I am a picky ‘customer’ ;)

I hope you enjoy the new release!

Cocoa Development Objective C Web

Automatically get latest download link from Sparkle in PHP

This is just a quick post to help someone out on Twitter, and the blog seemed the best place to post it.

If you make Mac apps, you probably use Sparkle to manage your auto-update process, outside the Mac App Store anyway. And so you should, it’s awesome, and makes keeping software up to date much easier. But what about the download link on your website for new users? Wouldn’t it be nice not to have to manually update that every time?

For SourceTree, I use a PHP script which just parses my Sparkle appcast and reads the latest release from there, generating a download link automatically. So whenever I update the Sparkle appcast (and I have scripts to do this from XCode, which I may share in a subsequent post if there’s interest), the download link for new users is always up to date immediately.

The full code is after the jump if you want it. As usual, feel free to use this for whatever you want, but there are no warranties for anything whatsoever; don’t blame me if it doesn’t work, or dissolves your website into a pool of steaming alien slime.

read more »

Business Cocoa Development Objective C Personal Tech

Introducing: SourceTree

I’m pleased to announce that I’m finally ready to make my first fully-fledged commercial Mac OS X application available to the world!

SourceTree is a user-friendly Mac OS X front-end for Mercurial and Git, the two most popular distributed version control systems used today. The goal was to create a single tool which could deal with both systems efficiently, and to give a developer quick and intuitive access to the things (s)he needs to just get on with building software.

I thought I’d answer a few background questions on this that I get asked on occasion:

Why Mercurial AND Git?

Other apps tend to concentrate on just one version control system, so why am I supporting two? Well, as a developer I’m regularly coming across projects from both sides of the fence, and in practice I find I need to use both fairly regularly. I personally chose Mercurial for my own projects (and discussed why here), but I still use Git when dealing with other projects, and spend a fair amount of time hopping between the two. It struck me that even though they have their differences, they are both based on the same distributed principles, so having to use two separate tools was just unnecessary. I wanted a single tool which provided a common interface where that made sense, while still exposing the things they do differently where that was useful too. SourceTree 1.0 is my first attempt at that.

Why only Mac OS X?

There were actually multiple reasons for this choice:

  1. I wanted to learn Objective-C and Cocoa on a real project
  2. I know from experience that designing for multiple platforms can be a distraction, with more time spent on compatibility issues, and less on functionality – and that’s before you even consider the compromises  you have to make, particularly on UI conventions which are far from uniform across platforms. I’ve been a multi-platform developer for more than 10 years, and for a change I just wanted to focus on the end user results and nothing else. I’m aware that schedules slip very easily when you overcomplicate, and I’m already supporting multiple DVCS systems (something I consider to be an important feature point), so I deliberately chose to keep this element simple.
  3. Mac OS X has become my own platform of choice for most things now. The combination of stability, user-friendliness, Unix underpinnings and well designed hardware match my current needs perfectly. I’m done with the ‘some assembly required’ PCs that I loved tinkering with over the past 15 years

What about Subversion?

A few people have asked me if I plan to add Subversion support too. I actually did intend to originally, until I realised how much time it was going to take to just do a decent job on Mercurial and Git. Within the time constraints, I focussed on the subject areas that I felt I could contribute most to – there are already quite a few Subversion tools out there for Mac OS X, but Mercurial and Git are much less well served, so that’s where I focussed my efforts.

I still have Subversion support tentatively on my work plan, but it’s not top of the list. I think it’s better to do your most important features well before diversifying. Plus, there are problems with Subversion – it’s very, very slow compared to Mercurial and Git, so to match the performance in SourceTree of things like the interactive searches and dynamic refreshing / log population I’d probably have to do a ton of extra caching just so the user wasn’t sat tapping their fingers.

Edit: I made my decision on this: I don’t plan to support local Subversion, but to support operating with Subversion servers with Mercurial and Git locally via hgsvn and git-svn.

Why didn’t you make it open source?

Sorry folks, while I love contributing to open source (I’ve done a bit on SourceTree too, sending a patch back to BWToolkit), making it work as a business is very hard indeed. I half-killed myself trying to combine being an open source project leader and doing other commercial activities at the same time, so now I’m trying a more traditional approach. One thing I learned in the last few years is that there are some sectors & application types where being an open source maintainer is very compatible with also running a business based on that project, and there are others where you can really only do one or the other simultaneously without flaming out. Sucks, but there it is ;)

What’s Next?

I have a public, official roadmap for SourceTree and encourage users to suggest things they think should be on there, via the support system. I learned from running an open source project for 10 years that being open about your plans can be a big benefit – users like to know where things are likely to be going, and often have better ideas than the developer on what could do with a bit more spit and polish. They can also tell you what’s important to them, which is crucial for prioritising – as developers we tend to get carried away with things we want to work on, but in the end, it’s scratching the customer’s itch that matters most.

And while I’m really quite proud of SourceTree 1.0, there are plenty of features I’d like to continue to add, and definitely more room for some totally unnecessary beautification which I didn’t have time for in the first release. Hey, this is OS X ;)

SourceTree is available now on a 21-day trial license. Go get it already :)

Cocoa Development Objective C

Cocoa tip: using custom outline view cells designed in IB

I only started learning Objective-C and Cocoa in mid-May, and for the first time I think I actually have a tip to contribute to the wider community. It’s about using custom cells in NSOutlineView, but those which you want to design inside Interface Builder rather than drawing manually.

If you’re an iOS developer, you’ll be wondering why this deserves a blog post – it’s easy to do in Cocoa Touch! Well, yes it is easy on iOS, because Apple have specifically allowed you to design table view cells in Interface Builder. When targetting Mac OS X though, it’s actually pretty awkward, and here’s why: in Cocoa Touch, the class which draws the cells in a table is UITableViewCell, which is a subclass of UIView – meaning you can drag one onto the canvas in Interface Builder and lay stuff out right there. In Cocoa, in contrast, the cell is simply represented by NSCell, which is not an NSView subclass. This means Interface Builder will not let you play with them, you draw them by implementing drawWithFrame:inView: instead. I think Apple realised the problem with this design in time for Cocoa Touch but obviously felt they couldn’t break the existing Cocoa interfaces. There are also many differences between the instantiation of NSCell versus UITableViewCell – there’s only one NSCell for all rows in a table / outline view, compared to a type-indexed pool in Cocoa Touch.

The problem boiled down to this: if the contents of your table / outline cell is non-trivial, or if you just don’t want to write a bunch of layout code, it’s a PITA to implement a custom look in NSOutlineView, such as the one in the picture, especially if you want custom controls embedded in it. For my current Cocoa app, I really wanted to design my cells (and I have 2 different styles for group levels and detail levels) in Interface Builder to save me hassle, including using Cocoa Bindings to hook up some dynamic fields within. Many internet searches later, and mostly the answer I found was that it couldn’t be done. Luckily, I’m too stubborn to take no for an answer, and eventually I figured out a way to do it. Details are after the jump, with an example project to show it in action.

read more »