A Collection of interesting iOS Open Source projects

I just finished a large project so I decided to take a moment to sort through the multitude of open source iOS projects (new and old) and pick out a couple of the most interesting and useful. I have collated my results below; a sort of whose who of iOS open source projects. I have tried hard to keep the descriptions brief so I don’t bore you. There are many hidden gems in each project that will save you hours of time so have good look at each.

CocoaPods

First off, if you haven’t already checked out CocoaPods, do it now! It is an awesome dependency manager for your iOS and Mac projects, which has saved me countless hours of pain and headaches.

CocoaPods creates a workspace for your Xcode project and adds a Pods project to that workspace. The Pods project encapsulates all of your third party libraries and all related compilation settings. It will automagically setup each library within your Pods project, so you don’t have to worry about -fno-objc-arc compiler flags for non-ARC source or adding SystemConfiguration.framework for some project you didn’t realise needed it, basically the kind of obvious misstep that might result in a wasted afternoon googling. Each time you build, it will compile the Pods project into an easily digestible static library for your Xcode project to link against and make all the necessary header files available to you.

Also, check out the CocoaPods Podspec repo; it hosts a stellar collection of iOS/Mac open source projects. Coincidentally, all of the projects listed below are currently available through the CocoaPods repository.

Currently Using

AFNetworking
AFNetworking was created by two talented guys (Mattt Thompson and Scott Raymond) from the now defunct, Gowalla (don’t worry AFNetworking will live on without Gowalla). It is an incredibly useful networking library, which is built on top of NSURLConnection and NSOperation. It uses Block based callbacks which gets a big tick from me and provides you with AFHTTPClient which “captures the common patterns of communicating with an web application over HTTP”. This handy class encapsulates all the information needed for communicating with one web service.

Magical Record
Magical Record was inspired by the ease of Ruby on Rails’ Active Record fetching and aims to reduce your CoreData code by reducing the amount of boilerplate code and condensinf CoreData’s very verbose and long winded fetch syntax.

Will Use

A2DynamicDelegate
I am a huge fan of Blocks and A2DynamicDelegate aims to allow you to convert any delegate, datasource or arbitrary protocol into a block based delegation. It uses some serious Objective-C runtime hoodoo to allow you to dynamically implement methods in a protocol using blocks.

FormatterKit
FormatterKit is a collection of NSFormatter subclasses which allows you to format an impressive range of data types. It can format arrays (e.g. “Russell, Spinoza & Rawls”), hours of operation (e.g. “Mon-Wed: 8:00AM – 7:00PM”), ordinal numbers (eg. “1st, 2nd, 3rd” / “1ère, 2ème, 3ème”) and time intervals (e.g. “3 minutes ago” / “yesterday”) to name a couple.

DCIntrospect
Introspect is a handy set of tools for any iOS developer who doesn’t use Interface Builder and creates his/her view layouts at runtime. It has a couple of really cool tricks up its sleeve like automatically rendering view frames, displaying view insets and a set of really useful key bindings, which allows you to access helpful view debugging information while your app is running.

ConciseKit
A set of Objective-C additions and macros that will make your code more concise. The ConciseKit GitHub page gives you a nice rundown of handy Macros and shorthands it implements. Some of it will be made redundant by the new Objective-C literals you can with the upcoming Apple LLVM 4.4, but there is a tonne of other handy stuff in there like simple method swizzling, shorthand paths and a large number of concise NSArray additions.

JRSwizzle
JRSwizzle makes method swizzling a breeze and uses the most robust method depending on the version of Objective-C runtime.

BlocksKit
BlocksKit adds a tonne of Block based methods to your favourite Foundation and UIKit classes.

Honourable Mentions

NYXImagesKit
LRTableModel

If you know of any other interesting projects, drop me a tweet, @jinthagerman.

How to detect non-jailbroken pirates

Please Note: The following is an approach I have put together to help other developers stop this kind of highly immoral piracy. I have not tested this myself as I am not currently maintaining any paid apps. Please report back with your results if you do try this.

Background

This section is rather long-winded, so if you’re impatient and/or an iOS ninja/expert, skip down to the “Rough Solution” section.

Most iOS developers know that jailbroken iPhone/iPad users can quite easily download and install cracked versions of their apps. This egregious violation of copyright has understandably angered devs which have poured their hearts and souls (not to mention countless hours and Benjamins) into these apps. Through this anger, methods have been developed to detect and track these illegitimate users.

But what some developers don’t realise is, there is another method for installing cracked apps on your iPhone without jailbreaking. It is not quite as easy as the jailbroken route, but I found a couple of programs which simplify the process. Google turned up a couple of results, Crappstore (a Xcode project), iReSign (automated tool) and IPA God. Part of the complexity lies in the fact that you need access to a iOS developer account as the method requires a valid Development provisioning profile. This should be a impassable barrier for most users, but there are services selling provisioning profiles to users which include their UDIDs.

The programs mentioned above are all based on the same method, which has been around for awhile now, but a dev on Twitter proposed a simple question which caught my attention. At runtime, can I detect whether an app has been installed illegally using this method?

So first, lets take a look at how this method works. It takes advantage of the fact that Apple has given developers a fair amount of leniency with regards to what code they can execute on their devices. The process is outlined below.

  1. Obtain the App Store IPA or download decrypted IPA (skip to Step 3)
  2. Decrypt using an appropriate tool usually on a jailbroken device
  3. Re-code sign using one of the tools mentioned above with a valid Development provisioning profile (you can obtain these for a fee for a few different sources)
  4. Install provisioning profile and freshly codesigned IPA onto your device
  5. Enjoy your cracked app (or more correctly, try to enjoy your app while the guilt eats away at your soul)

So how can we tell at runtime whether this app is legitimate or not? Well, the core of this method is resigning the decrypted app using a Development provisioning profile. So what we really need to do is determine the code signing identity at runtime.

The embedded.mobileprovision file holds information related to how the app was signed and the devices it is allowed to be installed on. My first thought was this would be our silver bullet, but after some research, I realised this was not the case.

Stack Overflow offered me this piece of information.

A provisioning profile is DER-encoded “pkcs7-signedData”, consisting of an XML blob (the data), a certificate chain (Apple Root Certificate Authority → Apple iPhone Certification Authority → Apple iPhone OS Provisioning Profile Signing), and the signature

So this tells me that the structure of it isn’t human readable without a ASN.1 parser, but all the pertinent information we need should be here. Luckily, most of what we need is in the “XML blob” which is actually a plist. This part is human readable in a text editor so I took a look around and I found these main differences between Development and Distribution embedded.mobileprovision files.

Development Distribution
Contains UDIDs Yes No
get-task-allow true false
Certification Authority Apple Certification Authority Apple Worldwide Developer Relations Certification Authority

However, it seems Apple strips the embedded.mobileprovision file out of your IPA at some point in the black box that is the App Store submission process. Moreover, the embedded.mobileprovison file doesn’t even need to be bundled with the app (IPAs created by iReSign didn’t contain any) as long as it exists on the device. codesign embeds the code signature (which refers to the appropriate provisioning profile) into the binary (to take a look, “codesign -dvvv AppBinary” in Terminal). Seeing as there is no app without a binary, this seems like a decent place to check the signature.

I opened the binary of an app in a text editor and found a similar structure embedded at the end of the file as we saw in the embedded.mobileprovision files. However, UDIDs are not present in both cases and get-task-allow by itself is not enough information to be determine the legitimacy of the app, so we are left with the Certification Authority.

Rough Solution

The solution I present here is the result of a couple of hours of digging and experimentation. I haven’t extensively tested it with the various method I mentioned earlier and I haven’t tested it in the wild as I don’t maintain any applicable paid apps. Please use at your own risk and only if you understand the underlying logic and possible implications. With more time and motivation, I’m sure a more elegant method would be discovered, but I believe this method is robust enough to at least use to collect some data on the use of these techniques. If someone implements this, get in contact because I’d be happy to help test this if you would like.

My proposed technique is brutally simple. Look for the “Apple Worldwide Developer Relations Certification Authority” string in the executable.

This could be done much more efficiently (using NSFileHandle), but this version is more readable and explains the technique well. If anyone is interested in seeing the extended version, I might be persuaded to do a follow-up post on that.

I would recommend you put this between some #ifdefs and define a preprocessor macro in your Distribution Build configuration. This will keep this snippet from interfering with your development testing. If this means nothing to you, you probably shouldn’t be doing this anyway.

Discussion

There are a couple of possible pitfalls that I can think of off the top of my head.

  • I tested this method using a project I am working on, which compiles to a 6.3mb binary and it takes roughly 0.9s to complete this check. There are, however, several simple optimisations I can think of that should speed this up and reduce the memory footprin.
  • There is potential for various false positives here that I haven’t thought of
  • This method is vulnerable to changes in the way that Apple signs apps
  • There could possibly be issues when Apple reviews the app depending on how they test it

Update: Thanks to Steve Troughton-Smith for pointing out a silly mistake I made in the code snippet. By including an exact copy of the Certification Authority string in my code, I was (recursively?) validating the test which would produce false positives in almost all cases. For the sake of simplicity and readability, I have fixed this simply by splitting the string and concatenating it. There are definitely more elegant ways of hiding this string, but I will save this for a future post.