Category Archives: OS X

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!

Business Development OS X

Mac user base by country: my figures so far

As many of you probably know, almost a year ago now I decided to take the plunge and move my primary development activities to the Mac. I taught myself Objective-C, got properly to grips with Cocoa at last, and started a new Mac OS X-specific project which would eventually become SourceTree, learning a ton along the way (a process which is by no means complete!).

Happily, things have turned out very well – SourceTree continues to sell, reassuring me that there’s enough interest out there for me to keep expanding and improving it (I’m looking forward to getting the next major release in people’s hands soon), and I’ve also been getting some Mac/Ogre-based contract work which I’ve enjoyed a great deal. In short, my Macbook Pro and I are now pretty inseparable, Windows 7 is powered off 99% of the time, and I saved hundreds of pounds by not upgrading to Visual Studio 2010 ;)

Out of interest, I thought I’d share some of my SourceTree sales information, in terms of the country distribution. Mac use is typically associated primarily with the USA, and while that’s certainly reflected in my absolute numbers, there’s some quite interesting figures revealed when you take into account population size. SourceTree is aimed at developers of course, so all numbers reflect this audience alone (and of course those that chose to buy it) but in practice I suspect that the proportions of developers to non-developers is fairly uniform in most developed countries.

So, firstly the absolute distribution:

No surprises there, the USA is the single largest source, followed by Germany and the UK (who are constantly scrapping over second place!). To me though, Switzerland stuck out as the most interesting, because it’s up there in 4th place yet has a relatively small population (under 8m). So I wondered – what would the chart look like if I scaled it by the population size? Here’s the result:

And there you go – as expected Switzerland jumps right to the top, and to my surprise Luxembourg and Denmark are up there too, beating the UK which I expected to come in second. Quite a lot of European countries are punching above their weight in per-capita Mac development, if SourceTree sales are any indication. In fact, on a per-capita basis, the USA is only just sneaking into the top 10, despite it being by far my best overall customer in sheer sales volume.

I’m aware that scaling by population isn’t all that scientific, since it is sensitive to the proportion of non-developers (and even non-computer users), but as I say, I think in developed countries at least, the comparisons are reasonably valid.

So the perception that Mac development is more popular in the USA than elsewhere may be inaccurate, based on my numbers at least (which of course are not massive in the grand scheme of things, but still a statistically relevant sample I think). Sure, simply because of the sheer population size of the USA it’s bound to dominate anyone’s sales numbers, but if you asked the question ‘of 1000 randomly selected developers in a country, what percentage are using a Mac?’, the result may not be skewed in the way you might expect. It was surprising to me, anyway.

I wonder if anyone else who has been doing this for longer has had similar results?

Cocoa Development OS X

Automating Incremental Nib Localisation in Cocoa

Cocoa is already quite good at handling localisation – you have a folder per language where all your resources are loaded from, and you get tools for exporting your strings from your code (genstrings which exports NSLocalizedString macros) and from your user interface components (ibtool which can process nib files to export & import strings).

What isn’t covered very well in the docs though is how you might automate all this so that it’s efficient, incremental, and idiot-proof. And by idiot, I mean me after more than 7 days since reading the docs.

There are tools out there that purport to make this easier, such as AppleGlot and iLocalize, but to be honest I found they just made things more complicated. All I really wanted was an efficient way to batch export and import localised strings, to know what changed between versions, and to keep my previously localised strings automatically without overwriting them. Translators should need nothing more than a Unicode-capable text editor – no complex tools, no training, just their natural ability to turn English into a different language and type it into a text file.

I ended up with two Python scripts to handle this – one to handle the genstrings/NSLocalizedString route, which I wrote a while back and covered in a previous blog post. The second I wrote today to handle nibs, and also to build the individual language folders. I needed it to do this:

  1. Export strings from nibs for each language, merge with strings already translated, or
  2. Import strings for each language and create localised nibs based on the master English versions

Here’s my Python script to do this: localise_nibs.py

Usage:
  localize_nibs.py --basedir=<base> --stringsdir=<strdir> 
    [--langdir=<langdir>] export|import

  export: Reads all the xib files in <base> and generates .strings files 
        for every 2-char country code directory under <strdir>
        New strings will be added to existing files.
  import: Reads all the xib files in <base> and looks for .strings files 
        in <strdir>/<lang> with the same name. Replaces strings in xib and 
        writes the output to <langdir>/<lang>.lproj

So basically, you start with a base folder full of nib files (in English in my case), and point –stringsdir at a folder which contains (empty to begin with) subfolders corresponding to languages (like ‘fr’, ‘de’, ‘ja’ etc). When using the ‘export’ option, it will go through all your .xib files and generate strings from them using ibtool, once for each language. It will also turn these files into UTF-8 rather than UTF-16 (as ibtool exports them), so that you can put the files in hg/git without losing text diff support. You can give all these files to your translators.

The nice thing is that if you add a new control to your user interface, and you’ve already got translations in the –stringsdir folder, the script will merge the output from ibtool and the existing translation, only adding the new strings. You can then simply give the files to your translator with a ‘diff’ report (this is why you want UTF-8) to show them what they need to look at. The Apple localisation docs talk about ‘incremental’ localisation, but they totally miss this part – by ‘incremental’ they just mean taking a localised nib that you’ve manually changed and merging geometry settings, not generating a new strings file which doesn’t lose the previous translation.

The ‘import’ option does the reverse, it takes the translated strings and the base nibs, and creates localised nibs in the –langdir folder. Mostly the script just automates everything so it finds the files on its own, processes all languages, and highlights when there’s a missing translation (and uses the base version temporarily so the app still works). Note that I assume that you only manually author one nib (the base version) – personally I don’t have the resources to tweak geometry in every language so if you do, you’ll need to alter the script to cope with the ‘incremental’ localisation as Apple presents it in the docs.

Anyway, I just thought I’d post this in case it helps someone else – I experimented with a few different options and I found this one to be the best – it’s simple, uses tools you already have, and plays nice with source control. Result?

Development OS X

OS X Localisation: incremental genstrings and UTF-8 files

I came across a couple of interesting issues when I came to do the first pass of writing the text for the user-visible strings I’d been setting up for a Cocoa app I’m writing (painfully slowly as I learn the nuances of the environment), and I thought I’d share them. Full details are after the jump, since I’ve embedded a large script in the post.

The basic principle for text localisation on OS X is that, like most systems, you externalise your user-visible strings in string tables and reference them by keyed aliases in code – in this case using NSLocalizedString. Apple provide a tool called ‘genstrings’ which extracts all these into a template strings file called Localizable.strings which you can then populate per language – localised files are kept in folders called en.lproj, fr.lproj etc and helpfully they’re picked up by default like this.  So far, so good.

read more »

Development OS X Personal

Taking a bite of the Apple

Giving up the leadership of OGRE was a sad moment for me, but in hindsight it has also been rather liberating. For 10 years I’d spent most of my energy on OGRE or on projects that were related to OGRE. There was an implicit understanding both from the community and from myself that everything I embarked on would in some way tie into OGRE – and indeed my business has always been based on a constant balancing act between how I can make a living while also promoting and advancing OGRE. I’d tended to major on the latter rather than the former most of the time as it happens, because I had an emotional attachment to the project and a feeling of responsibility and custodianship that I took very seriously. So when I finally admitted to myself that my back couldn’t take the ongoing demands of being an open source leader as well as making a living, the big question was: what next?

Over the years I’ve learned a couple of things about choosing what projects to work on – follow your gut, and work on things you’d do even if there was no money in it. Yes, you need to do a business case and convince yourself that there’s a viable market for what you have in mind, but all that’s irrelevant if you don’t feel strongly about what you’re doing, because it’s passion and enthusiasm that will get you through the difficult times. So I sat down and gave some thought to what really excited me these days, what I liked using and what technical directions piqued my interest. I still find 3D and games fascinating, but they’re far from my only interests.

So, I realised that one area that I’ve been dying to get my teeth into properly for ages but had never found the time before, was coding specifically for Mac OS X. In 3 years I’ve gone from a total newcomer to the platform, to a staunch advocate of it. However until now I’d never really had time to play with developing on it, beyond porting cross-platform C++ code and providing / using intermediate libraries. One thing I learned in those 3 years as a user was how much better applications designed for OS X felt to use compared to those that were just ported via a common UI layer (like wxWidgets / Qt), and I’m convinced now that while cross-platform infrastructural code is great, user experiences are far better when designed with the specific platform in mind – increasingly that means OS and physical device now of course. Sure, cross-platform UIs save the developer time, but the result is often a watered-down experience – early on I liked OS X applications that felt like Windows, or ran the same on both platforms – now I  do not. Such carbon-copying applications were helpful while I was unfamiliar with the platform, but now it’s just glaring to me how basic their compatibility with the OS typically is, and how the UI styles clash with the expected standards.

So, I decided I wanted to learn how to target OS X specifically, and had a couple of ideas for projects I could do with it, which meant learning Objective-C. At first, I hated it and tried to escape via more familiar technologies like Objective-C++ and PyObjC. Ultimately I found shortcomings and limitations of those routes and returned to Objective-C, and the more I used it, the more my animosity toward it diminished. In the end I realised the problem was that I needed to adapt to the environment, rather than try to adapt it to my previously learned styles and behaviours. Sure, missing elements like namespaces might still nag me, but on balance the blend of static and dynamic language elements works very well for the intended use. And besides, I really didn’t want to be ‘that guy’ – the programmer that having decided one language / tech is ‘the best’, then tries to apply it everywhere, regardless of suitability; I like to think I’m a bit more flexible & multicultural than that.

I’ve also learned that Cocoa is a very, very smart system. Mad as a bison if you’re used to other systems beforehand, but persevere with it and resist the urge to hide it under some vanilla layer that you’re already familiar with, and you discover it’s really very powerful. Not to mention the Core Animation and Core Graphics frameworks are a lot of fun.

It’s funny, I’ve spent so many years concerning myself with providing compatibility across multiple OS’s, multiple GPUs, multiple render APIs, and multiple drivers, it’s a genuine joy to actually forget all that for a while, and concentrate on an end goal with a finite number of permutations for a change – and not to shy away from using platform-specific features.

While I’m still very much an advocate of open systems, I look at things slightly differently now – that data & protocols should be open, and that we should all re-use & collaborate on common, preferably open source infrastructure (like OGRE), but that the ‘last mile’ to the user is the least suitable for generalisation, because the more specific you can make that interface to what the user expects on their OS & device, the better that experience will be. And at the end of the day to the user, that experience is the application, and thus all that really matters – and I feel that Apple gets that, in a way that very few others do.

So, I’m having a great time learning to be an Apple developer so far, I’m going to see where this takes me for a while. My gut says it feels right, and I’ve learned to listen to my gut :) I love the platform, it’s a total change of pace and technology, it’s something I’ve had an interest in for a while, and the Mac has quite a thriving community of quality independent app developers that I can try to join – what’s not to like?

Games OGRE OS X

Monsieur, you are really spoiling us

Yesterday saw a triple-whammy of sugary Apple gaming goodness:

  1. Steam for Mac was released, meaning all the games you own on Steam that are ported to the Mac can also be played there, free.
  2. Torchlight was a day-1 release on the service, meaning Ogre (and therefore code written by me) was among the very first on the service.
  3. Portal became free (for Mac and PC)

Wow. A great day for Mac gaming. I noticed that World Of Goo was up on day 1 too, and since I’d bought it on Steam I could play it right away on my MBP too. Yummy.

Curiously, considering it’s based on Ogre, I don’t actually own Torchlight on Steam – I had a free Windows-only copy from Runic, I bought a physical (Windows-only) copy for my shelf, and I bought copies for both my wife and Diablo-obsessed brother in law on Steam but I never got a copy there myself, so I haven’t tried it on the Mac yet. I need to ask my wife to log in on the MBP so I can try it! :)