Top 10 Most Useful iOS Libraries in 2020

top-10-most-useful-iOS-libraries-0

Nearly five years ago, we published an article listing the top 10 libraries every iOS developer should know about.

The article provided a great starting point for developers looking to increase their productivity and avoid reinventing the wheel.

Turns out it was a highly searched topic, and the blog post remained relevant a lot longer than we expected.

With changes introduced in every new iOS release, our development needs have changed as well, resulting in rethinking which libraries we use.

Some of them listed in that article have stood the test of time and are making a comeback here, but there are also some newcomers which make our day-to-day programming lives easier.

With great libraries comes great responsibility

Before we actually start going through the list, I’d like to bring up an important disclaimer – use third-party libraries responsibly.

Be sure to check whether the libraries you’re going to use are actively maintained and supported.

Working on a project a year or two down the line could prove to be troublesome if at some point it stops compiling because of a Swift or iOS change that breaks used libraries.

Also, please, don’t import libraries in your projects just for the sake of it if you’re only going to use a very small part of that library. A great quote I heard at one recent meetup comes to mind here: ”Don’t use an excavator where a shovel would suffice.”

Now that we’ve covered the disclaimer part, I’d also like to point out that this list was compiled and ordered by looking at our recent projects and needs, and does not reflect any official download numbers or rankings that could be found online.

Your mileage may vary depending on your project’s domain, but hopefully, you’ll find something of use here as well.

Top 10 most useful iOS libraries in 2020

Alamofire is an elegant and composable way to interface with HTTP network requests. It builds on top of Apple’s URL Loading System provided by the Foundation framework. At the core of the system are URLSession and URLSessionTask subclasses.

Alamofire wraps these APIs, and many others, in an easy-to-use interface and provides a variety of functionality necessary for modern application development using HTTP networking.

	AF
    .request("https://your.api.url")
    .validate()
    .responseDecodable(of: SomeDecodableObject.self) { (response) in
        guard let object = response.value else { return }
        print(object) // Your object, decoded and ready to use.
    }

From top to bottom, you request the endpoint, validate the response by ensuring the response returned an HTTP status code in the range 200–299 and decode the response into your data model. Easy peasy.

This is a Swift version of Rx. It tries to port as many concepts from the original version as possible, but some of them were adapted for more pleasant and performant integration with iOS/macOS environment.

Like the original Rx, its intention is to enable easy composition of asynchronous operations and event/data streams. KVO observing, async operations, and streams are all unified under the abstraction of sequence. This is the reason why Rx is so simple, elegant, and powerful.

Here’s a simple example of how RxSwift can be used to create a logic for enabling a login button that checks two things – whether the username and password are both entered, and if the password is of appropriate minimum length.

	let name = nameTextField.rx.text.asDriver()
let password = passwordTextField.rx.text.asDriver()

let isEnabled = Driver
    .combineLatest(
        name,
        password
    ) { !$0.isEmpty && $1.count >= 6 }

isEnabled
    .drive(loginButton.rx.isEnabled)
    .disposed(by: disposeBag)

This is just scratching RxSwift’s/RxCocoa’s surface, but you can already see how it can make your life easier. RxSwift has a steeper learning curve than most libraries you could include in your projects, but once you get the hang of it, you’ll be thankful you did and will probably never look back.

Note – Combine will probably at some point going to slowly start sunsetting RxSwift, but since it requires iOS 13 as a minimum OS version, that is still a couple of years away, and RxSwift will prevail until then.

Kingfisher is a powerful, pure-Swift library for downloading and caching images from the web. It will download the image from url, send it to both memory cache and disk cache, and display it in an UIImageView, NSImageView, NSButton, or UIButton. When you try to retrieve an image with the same URL later, the image will be retrieved from the cache and shown immediately.

	// Basic version
let url = URL(string: "https://example.com/image.png")
imageView.kf.setImage(with: url)

// SwiftUI version
import KingfisherSwiftUI

var body: some View {
    KFImage(URL(string: "https://example.com/image.png")!)
}

It also provides many powerful additional options such showing a system indicator and a placeholder image while downloading, built-in updating transitions, extensible image processing, formatting, and much more. A must-have if you’re working with remote images!

4. Lottie

Let’s be honest, animations in an application make a huge difference. They grasp your user’s attention and steer them through your app’s flow, all the while providing a fun and memorable experience. Since creating animations by hand using UIView or CoreGraphics animations can prove to be quite challenging and time-consuming, Lottie provides us with a perfect tool to incorporate desinger creations into our applications.

Lottie loads and renders animations and vectors exported in the bodymovin JSON format. Bodymovin JSON can be created and exported from After Effects with bodymovin, Sketch with Lottie Sketch Export, and from Haiku.

	override func viewDidLoad() {
    super.viewDidLoad()

    startAnimating()
}

func startAnimating(){
    animationView.setAnimation(named: "bird_flying") // "bird_flying" is an example animation that can be found here: https://lottiefiles.com/17655-bird-flying
    animationView.play()
}

After importing Lottie into your project, this is all the code needed to add a beautiful animation to your app. Quite a timesaver.

SwiftLint is a tool used to enforce Swift style and conventions, loosely based on GitHub’s Swift Style Guide.

SwiftLint hooks into Clang and SourceKit and uses the AST representation of your source files for more accurate results.

Its rule list is quite extensive and covers pretty much everything you would want to keep track of in a well-maintained project. It also has the option to disable rules per file or even per line, but use those responsibly. Silencing a warning about a 700-line file or a too long method is maybe not the best way to go around doing things.

SnapKit is an Auto Layout library that simplifies writing auto layout in code with a minimal amount of code needed without losing readability. It is type-safe by design to help you avoid programming errors while coding your user interface.

	let box = UIView()
let container = UIView()

container.addSubview(box)

box.snp.makeConstraints { make in
    make.size.equalTo(50)
    make.center.equalTo(container)
}

It’s also very powerful when it comes to views whose constraints are updated frequently. Remaking constraints is much more pleasant than dealing with Auto Layout by hand:

	func updateBoxSize(to size: CGFloat) {
    box.snp.remakeConstraints { make in
        make.size.equalTo(size
    }
}

SwiftyBeaver is a colorful, flexible and lightweight library enabling easier logging during the development of your applications. Gone are the days of bland console outputs; using this library makes finding out what went wrong a breeze.

	let log = SwiftyBeaver.self

let console = ConsoleDestination()  // log to Xcode Console
log.addDestination(console)

// Now let’s log!
log.verbose("not so important")  // prio 1, VERBOSE in silver
log.debug("something to debug")  // prio 2, DEBUG in green
log.info("a nice information")   // prio 3, INFO in blue
log.warning("oh no, that won’t be good")  // prio 4, WARNING in yellow
log.error("ouch, an error did occur!")  // prio 5, ERROR in red

KeychainAccess is a simple Swift wrapper for Keychain that works on iOS and macOS. It makes using Keychain APIs extremely easy and much more palatable to use in Swift.

Saving data to the Keychain and retrieving it has never been easier:

	// Save to the keychain
let valueToSave = "Important data"

Keychain().set(valueToSave, key: "key")

// Get from keychain
let savedValue = try? Keychain().get("key")

9. Hero

Hero is a library for building iOS view controller transitions. It provides a declarative layer on top of the UIKit’s cumbersome transition APIs — making custom transitions an easy task for us.

It works similar to Keynote’s Magic Move. It checks the heroID property on all source and destination views. Every matched view pair is then automatically transitioned from its old state to its new state.

Hero can also construct animations for unmatched views. It is easy to define these animations via the heroModifiers property. Hero will run these animations alongside the Magic Move animations. All of these animations can be interactively controlled by user gestures.

	// First viewController - VC1
redView.hero.id = "ironMan"
blackView.hero.id = "batMan"

// Second viewController - VC2
self.hero.isEnabled = true
redView.hero.id = "ironMan"
blackView.hero.id = "batMan"
whiteView.hero.modifiers = [.translate(y: 100)]

As you can see, Hero does a lot of heavy lifting in order to provide us with a simple API to create powerful animations.

OHTTPStubs is a library designed to stub network requests by using method swizzling. It works with NSURLConnection, NSURLSession, AFNetworking, Alamofire, or any networking framework that uses Cocoa’s URL Loading System.

	stub(
    condition: { (request: URLRequest) -> Bool in
        // check whether this api call should be mocked by using the response closure
        // return false if it shouldn’t
        return true
    },
    response: { _ -> OHHTTPStubsResponse in
        let path = "...path_to_your_file.json"
        return fixture(filePath: path, status: 200)
    }
)

This library comes in handy in several situations:

  • mocking different API responses while the app is in development to check if our UI handles every case correctly,
  • easier integration testing by providing baked in responses to your testing suite,
  • implementing a demo mode inside your application that doesn’t reach the actual server, but uses baked-in responses.

I’ve written about implementing such a demo mode in one of my previous articles, so be sure to check it out if you’d like to learn more about it.

Honorable mentions

There are a few more libraries we use in most of our projects, but since these are our own open-source projects it didn’t seem fitting that they steal the spotlight of other popular third-party solutions.

However, since they could prove to be of use to you, we should also list them here as well:

  • Prince of Versions – used for easier versioning of your applications, allowing you to prompt your users to update the app to the newest version.
  • Loggie – used for capturing all HTTP/S requests the app makes and showing them in a simple table view, enabling easier API debugging.
  • Japx – lightweight JSON:API parser that flattens complex JSON:API structure and turns it into simple JSON and vice versa.
  • Locker – a lightweight library for handling sensitive data (String type) in Keychain using iOS Biometric features.

While we’re at it, you can also check out Nuts & Bolts, our repo containing a centralized collection of commonly shared and reused code throughout the Infinum iOS team.

What’s your take on our list?

Do you agree with us? Got some other libraries you find useful that you would like to share? Leave a comment or contact us on social media. We’re eager to learn about new things and interesting ways of easing common iOS pain points.