ObjFW, Frameworks, the App Store and Swift



This week, I finally got scrypt-pwgen into the App Store (except France, because they have insane crypto regulations). This was actually quite a fun exercise, as this (to the best of my knowledge) is the first app to make it into the App Store that uses ObjFW. Initially, I was using ObjFW built as a .framework for this and it worked fine on my local device, but it confused the App Store a lot, and while the build would upload, it would then fail the processing on Apple's side. The immediate remedy was to just use ObjFW as a static library, which worked and pretty much let me get the app into the App Store immediately (except the first version being rejected, because it crashed as a category wasn't loaded due to the switch from a .framework to static linking). However, I really wanted this working with a .framework . Since copying the Xcode-built .framework s over was annoying, I tried adding a subproject with ObjFW itself, but that was also annoying. I ended up adding support for building .framework s to buildsys.mk and a script that builds a universal ObjFW.framework and ObjFW_Bridge.framework for all architectures + all simulator architectures, so that I can easily switch between device and simulator. This now works beautifully, and I can successfully upload it to the App Store, with just one caveat: Before uploading it to the App Store, I need to use lipo to strip the simulator architectures, as Apple does not like you uploading a .framework that contains support for unsupported architectures :).

All this looking into .framework s gave me the idea to look into how well ObjFW.framework and ObjFW_Bridge.framework work with Swift. And after minor fixes, it worked exceptionally (pun intended!) well, except for one thing: Exceptions! But there was an easy solution, as Swift supports Blocks, and now there's a category on OFException in the bridge that allows you to do this:

import ObjFW import ObjFW_Bridge OFException.try({ OFOutOfMemoryException(requestedSize: 1234).throw() }, catch: { (e: OFException) in print("Caught \(e.class())") }, finally: { print("Finally") })