An iOS Developer’s (Mostly) Open Source Toolchest

One benefit of a big platform like iOS is that developers can choose from many tools and technologies. Below are our selections for my current project. Most of them are available via [CocoaPods][cocoapods].

##Objective-C

We’re using Objective-C for two main reasons:

* Existing expertise within Atomic.
* A mature and robust ecosystem. (At the time of writing, StackOverflow has ~210k Objective-c [questions][stackoverflow_objective_c]!)

*Alternatives: [Swift][swift_link]; other languages via platform abstraction layers like [Xamarin][xamarin_link], [RubyMotion][rubymotion_link], [Phonegap][phonegap_link], etc.*

##ReactiveCocoa
[ReactiveCocoa][reactivecocoa] brings [Functional Reactive Programming][link_frp] to Objective-C, and is a favorite around AO. It’s very well suited for asynchronous work like UI and network interaction, helping us keep the majority of our code [lazy][link_lazy] and [functional][link_functional]. A good introduction can be found at [NSHipster][nshipster_rac].

##Objection
[Objection][objection] is a dependency injection framework created by our own [Justin DeWind][justice]. It enables us to write classes that don’t need to know how to instantiate each other. Paraphrasing from a 2009 I/O

This slideshow could not be started. Try refreshing the page or viewing it in another browser.

[io_presentation], a dependency injection framework is an *everything-factory* that you don’t have to write or maintain.

##OCMockito
We create [mock objects][wiki_mock], stub properties on them, and verify expected behavior with [OCMockito][ocmockito]. I like its permissive behavior, wherein it records function calls as they occur for later verification at the end of the test. This frees us from over-specifying the behavior under test, resulting in unit tests that are less brittle.

*Alternative: [OCMock][OCMock]*

##Specta/Expecta
[Specta][specta] is a test runner compatible with XCTest; [Expecta][expecta] is a matcher framework from the same authors. Read more about their merits [here][specta_expecta_ocmockito_external_blog].

*Alternative runners: [Kiwi][kiwi], [Cedar][Cedar], [XCTest][XCTest], [Quick][Quick], [Sleipnir (Swift)][Sleipnir]*
*Alternative matcher: [OCHamcrest][OCHamcrest]*

##KIF

[KIF][kif] is an integration testing framework that allows us to programmatically interact with an app’s UI. It hooks into iOS’ [accessibility features][ios_accessibility], allowing you to e.g. `waitForViewWithAccessibilityLabel:@”Welcome!”` and then `tapViewWithAccessibilityLabel:@”Next”`.

*Alternatives: [Instruments][instruments], [Zucchini][zucchini]*

##Underscore.m

[Underscore.m][underscore_m] is “a functional toolbelt for Objective-C” inspired by [underscore.js][underscore_js]. If you find yourself pining for features from functional languages, this is for you.

##Mantle

[Mantle][mantle] provides a number of features that make working with data-holder objects more convenient. Notably, it provides default implementations of `-isEqual:` and the methods for the [`NSCopying`][NSCopying] and [`NSCoding`][NSCoding] protocols.

##Masonry
We build user interfaces with [Masonry][masonry], which wraps [Auto Layout][auto_layout] with a [sweeter][syntactic_sugar] DSL.

##CocoaLumberjack
[CocoaLumberjack][cocoalumberjack] is a logging framework (see what they did there?). It provides a number of features over the ubiquitous NSLog, notably including the ability to capture the output.

##HockeyApp
[Hockeyapp][hockeyapp] provides an easy way to get beta builds out to our customer every week. Hopefully we won’t need it, but the crash reporting looks fantastic.

##Conclusion

[Open source][atomic_open_source] allows a small team to build great things by [standing on the shoulders of giants][giants_shoulders].

At a consultancy like AO, every new project presents an opportunity to use new tools. What did you choose for your current project?

[stackoverflow_swift]: http://stackoverflow.com/questions/tagged/swift
[stackoverflow_objective_c]: http://stackoverflow.com/questions/tagged/objective-c

[swift_link]: https://developer.apple.com/swift/
[xamarin_link]: http://xamarin.com/
[phonegap_link]: http://phonegap.com/
[rubymotion_link]: http://www.rubymotion.com/
[reactivecocoa]: https://github.com/ReactiveCocoa/ReactiveCocoa
[objection]: http://objection-framework.org/
[specta]: https://github.com/specta/specta
[expecta]: https://github.com/specta/expecta
[ocmockito]: https://github.com/jonreid/OCMockito
[kif]: https://github.com/kif-framework/KIF
[underscore_m]: http://underscorem.org/
[mantle]: https://github.com/Mantle/Mantle
[masonry]: https://github.com/Masonry/Masonry
[libextobjc]: https://github.com/jspahrsummers/libextobjc
[hockeyapp]: http://hockeyapp.net/
[cocoalumberjack]: https://github.com/CocoaLumberjack/CocoaLumberjack
[cocoapods]: http://cocoapods.org/
[giants_shoulders]: http://en.wikipedia.org/wiki/Standing_on_the_shoulders_of_giants

[link_frp]: http://en.wikipedia.org/wiki/Functional_reactive_programming
[link_lazy]: http://en.wikipedia.org/wiki/Lazy_evaluation
[link_functional]: http://en.wikipedia.org/wiki/Functional_programming
[kiwi]: https://github.com/kiwi-bdd/Kiwi
[atomic_open_source]: https://atomicobject.com/resources/open-source/
[justice]: https://spin.atomicobject.com/author/dewind/
[OCHamcrest]: https://github.com/hamcrest/OCHamcrest
[XCTest]: http://www.objc.io/issue-15/xctest.html
[OCMock]: http://ocmock.org/
[Cedar]: https://github.com/pivotal/cedar
[wiki_mock]: http://en.wikipedia.org/wiki/Mock_object

[specta_expecta_ocmockito_external_blog]: http://www.annema.me/why-i-prefer-testing-with-specta-expecta-and-ocmockito
[Quick]: https://github.com/Quick/Quick
[Sleipnir]: https://github.com/railsware/Sleipnir
[nshipster_rac]: http://nshipster.com/reactivecocoa/

[ios_accessibility]: http://nshipster.com/uiaccessibility/
[NSCopying]:https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSCopying_Protocol/index.html
[NSCoding]:https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSCoding_Protocol/index.html
[auto_layout]: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/index.html
[syntactic_sugar]: http://en.wikipedia.org/wiki/Syntactic_sugar

[instruments]: https://developer.apple.com/library/prerelease/ios/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/
[zucchini]: https://github.com/zucchini-src/zucchini
[io_presentation]: https://www.youtube.com/watch?v=hBVJbzAagfs
[guice]: https://github.com/google/guice
[underscore_js]: http://underscorejs.org/