Under The BridgeUnder The Bridge

Musings
All About Errors

Here’s one to bookmark for reference: The veritably _definitive_ guide to

Error Handling in Swift

Regardless of your skill, handling errors is a common task for any developer. As developers we have complete control of the code we write and features we include, but despite our best efforts, we don’t control everything. We don’t control the values our users enter or whether our applications have access to the resources they need. In this post we’re going to look at how we can handle these situations by looking at error handling in Swift…

Pretty certain you’ll find something new here no matter what your skill level:

Up to now we didn’t even realize catch could take a where clause, huh. That’s what a couple decades of C++ will do to you, reflexively cringe in triggered terror at the mere thought of “exception”. But we’ll get through it — that bit about propagating back asynchronously looks particularly interesting!

The Nib-lunged Saga

We’ve historically been big fans of Interface Builder for slapping stuff out there in a hurry mostly by ourselves, but these days working on a pretty big app (200+ nib files) that’s expeditiously transitioning to modernity under the tender care of a rapidly expanding team (join now!) the downsides of visual tools for maintainability, code review, and merge conflicts become … substantial. Soooo, we’re considering that as it comes up to refactor in The Great Swiftening, we drop the whole nib/storyboard concept and go code only. If that situation is on your radar as well, take a look at the roundup here from last fall:

Working Without a Nib

My goal is to make all my projects nibless. Nib and xib files have caused me no end of problems. Even files that haven’t been edited in years spontaneously stop working when Xcode is updated and its xib compiler changes. (Most of the problems manifested on previous OS versions, where it was harder to detect them and to test fixes.) And that’s to say nothing of the advantages that doing interfaces with code offers. I’m convinced that with current technology (e.g. Auto Layout, Swift), using Interface Builder is a poor time investment for non-temporary projects…

Particularly like this addenda:

I use xib’s for everything in Keyboard Maestro. And have special Lint code to detect inconsistencies. Coming to the conclusion I’m an idiot.

Heh. For a deep dive into the code only alternative, check out

IB Free: Living Without Interface Builder and Loving It

However, once my projects increased in complexity, I found myself becoming more and more frustrated: when designs evolved, I would often just have to start the layout over by clearing all constraints. I often couldn’t get complex layouts to work in IB and I did not understand UIKit well enough to implement anything that IB didn’t allow out of the box. This frustration was compounded immensely when I began to work on projects with multiple team members and source control: I couldn’t understand what other team members had done by looking at a diff of xibs or Storyboards, let alone untangle a merge conflict…

Nodding along there, are you? Yeah, us too.

In this blog post, I’m going to describe the benefits of being IB-free, and will show you how to build a project and control a view’s layout using Anchorage.

That last library, that’s what tipped us all the way. Check it out:

Anchorage: “A collection of operators and utilities that simplify iOS layout code.”

A lightweight collection of intuitive operators and utilities that simplify iOS layout code. Anchorage is built directly on top of the NSLayoutAnchor API, so fully supports UILayoutGuide. Each expression acts on one or more NSLayoutAnchors, and returns active NSLayoutConstraints.

Seriously, they’re not kidding about the “lightweight”. iOS 9 layout API is already pretty darn good, and Anchorage makes it look downright fluent. Definitely going to give that a shot at our current Swiftification and see how it works out!

Hailing Frequencies Open

OK, now that was unexpected in a point release:

Managing App Store Ratings and Reviews

iOS 10.3 introduces a new way to ask customers to provide App Store ratings and reviews for your app. Using the SKStoreReviewController API, you can ask users to rate or review your app while they’re using it, without sending them to the App Store. You determine the points in the user experience at which it makes sense to call the API and the system takes care of the rest.

When iOS 10.3 ships to customers, you will be able to respond to customer reviews on the App Store in a way that is available for all customers to see. (This feature will also be available on the Mac App Store.)

Well, that sounds promising, doesn’t it now? Although when you actually look at the new API, there’s some interesting restrictions:

requestReview(): Tells StoreKit to ask the user to rate or review your app, if appropriate.

Although you should call this method when it makes sense in the user experience flow of your app, the actual display of a rating/review request view is governed by App Store policy. Because this method may or may not present an alert, it’s not appropriate to call it in response to a button tap or other user action…

When you call this method in your shipping app and a rating/review request view is displayed, the system handles the entire process for you. In addition, you can continue to include a persistent link in the settings or configuration screens of your app that deep-links to your App Store product page. To automatically open a page on which users can write a review in the App Store, append the query parameter action=write-review to your product URL.

If your first reaction is that you want to control the presentation, go ahead and dupe this Radar

Allow user-initiated App Store rating/review request alert

although we’re going to go out on a limb here and assume that the lack of that ability is a quite deliberate decision, kinda hard to imagine them just forgetting about doncha think? so it’s not likely to happen. But we shall see.

Some more details have trickled out as well:

Apple explains the new App Reviews API for developers

Apple is also limiting the amount of times developers can ask customers for reviews. Developers will only be able to bring up the review dialog three times a year. If a customer has rated the app, they will not be prompted again. If a customer has dismissed the review prompt three times, they will not be asked to review the app for another year. Customers will also have a master switch that will turn off the notifications for app reviews from all developers, if they wish to do that. On iOS you can now use 3D Touch to label a review as “Helpful”, a feature that wasn’t available before for iOS users…

Additional Details on the New App Store Review Features

The replies that developers will be able to leave on App Store reviews will be attached to the user review to which they’re replying. It’s not a thread, per se, because users can only leave one review, and developers can only leave one response to each review, but they will be connected visually. Users can then edit their review, and developers can then edit their reply…

The new APIs will be eventually be the only sanctioned way for an iOS app to prompt for an App Store review, but Apple has no timeline for when they’ll start enforcing it. Existing apps won’t have to change their behavior or adopt these APIs right from the start…

So there you go, start planning your New Improved Review Begging UX now!

UPDATES:

How & when to ask for app reviews and ratings including iOS 10.3

Notifications Are Better Than Alerts

Fabric, R.I.P.

Catch the news yesterday? That was a mild surprise:

Fabric is Joining Google

Welcoming Fabric to Google

Although only mild, we grant you, because, well…

Indeed. Clearly this is great if you’ve already bought into the Firebase platform, but if you haven’t there’s a bit of thinking to do now, especially for those of us in businesses that Google actively competes with so have a smidgen of trepidation about handing over our collective user profiles and activity. Paranoid, yes yes, but hey paranoids have enemies too.

Not much out there in the way of comprehensive alternatives for your development deployments left though: for cross-platform development this Visual Studio Mobile Center thing that HockeyApp is growing up into might be interesting, but that looks like pretty much it, really.

‘Course, you could always just go all in on Testflight and let other platforms fend for themselves; it’s the easiest by far, that it’s iOS 8 or later should be no longer a problem in 2017 — if that still is a problem for you, our most sincere condolences — plus we gather that frontloading the binary approval process into the beta distribution is supposed to make the final review go noticeably quicker. That would be a quite acceptable tradeoff indeed for having to get your betas approved; does anyone have any firm statements and/or evidence that using TestFlight does actually expedite final review, or is this urban legend?

And as always, if we’ve missed the beta distribution method of your choice here, please educate us!

Padding it Out

So you thinking the rumours swirling about the A10X and the iPad Pro Mini sound … compelling? Yeah, us too. If those turn out anywhere close to reality, looks like 2017’s going to be the year we go all in on iOS, at least to the extent of travelling (which we do a good bit of, now that we’re based out of Bangkok and all). Last year, that was just about practical:

A Computer for Everything: One Year of iPad Pro

… I use my iPad Pro for everything. It’s my writing machine and favorite research tool, but I also rely on it to organize my finances, play games, read books and watch movies, program in Python and Workflow, and manage two successful businesses. While I’ve been advocating for such multi-purpose use of the iPad platform for a while, the iPad Pro elevated the threshold of possibilities, reaching an inflection point that has pushed others to switch to an iPad as their primary computer as well…

“What, how on earth can you work on apps off an iPad?”, you ask? Well, there’s number of options there already if you’re a web developer

14 great programming apps for your iPad 2016

Apparently Pythonista 3 is generally well regarded. Which would be great, if, y’know, we’d written any Python since 2013. Oh, wait. Well, for our use case of Xcode-based building process, we’ll give this a shot:

Dringend: A fully-fledged iOS & Mac development environment on iPhone and iPad

Build & run your apps on the go

Dringend lets you build and run your application wherever you are in the world, be it on a beach or whilst relaxing at a cafe. View errors and warnings just like in Xcode and best of all you can run your project on the iPhone or iPad itself. (Mac to act as build server & Dropbox account required)…

Sounds … well, like pretty much exactly what we want, really. We’ll see how that works out in practice and let you know!

Then, since we keep our private stuff on Bitbucket, looks like this is worth a shot too:

Git2Go: The Git client for iPhone and iPad you always wanted

Git2Go is the first app for iOS which unleashes your full development productivity from everywhere. Clone all your GitHub and Bitbucket repositories with just one tap, manage branches and easily commit changes after you’ve edited code on-the-fly – All from your iPhone and iPad!

Yup, looks like that could work too.

Working Copy: a powerful Git client for iOS that clones, edits, commits, pushes & more…

Or that!

Any of you Dear Readers attempted to develop, or at least make an emergency patch release with, an iOS app with any of these? Or know of any others we should be putting on the trial list?

UPDATES:

Matt Gemmell’s thoughts on Designing for iPad Power Users

Linea looks pretty cool: A New Way to Work

Swiftier Swift, Swiftly

Everybody wants their Swift programs to run swiftier, right? In case you haven’t stumbled across it so far, The Canonical List Of Recommended Ways To Do That is found right in the Swift github repo:

Writing High-Performance Swift Code

So you should go read that at the first opportunity and keep an eye on edits too!

Follow that up with this excellently accessible talk:

Real World Swift Performance

Lots of things can make your application slow. In this talk we’re going to explore application performance from the bottom. Looking at the real world performance impact of Swift features (Protocols, Generics, Structs, and Classes) in the context of data parsing, mapping, and persistence, we will identify the key bottlenecks as well as the performance gains that Swift gives us…

Here’s a couple more illuminating posts on instruction level speediness:

Unowned or Weak? Lifetime and Performance

os_unfair_lock is the new synchronization hotness!

Mind you, it’s quite likely that for many of you the most compelling thing that springs to mind on reading the headline there is not swiftier execution, but swiftier compilation, amirite? Here’s some backgrounders and tips on that:

Profiling your Swift compilation times

Guarding Against Long Compiles

Speeding Up Slow Swift Build Times

Regarding Swift build time optimizations

After I read @nickoneill’s excellent post Speeding Up Slow Swift Build Times last week, it’s hard not to look at Swift code in a slightly different light. A single line of what could be considered clean code now raises a new question — should it be refactored to 9 lines to please the compiler? (see the nil coalescing operator example further down) What is more important? Concise code or compiler friendly code? Well, it depends on project size and developer frustration.

Before getting to some examples, let me first mention that going through log files manually is very time consuming. Someone came up with a terminal command to make it easier but I took it a step further and threw together an Xcode plugin

Also check out Swift build time optimizations — Part 2 for followup.

And you’re probably vaguely aware that XCTest does performance these days but haven’t adopted it wholeheartedly yet, right? Check out

measure(): How to optimize our slow code and adjust the baseline

XCTest makes performance testing extraordinarily easy: you give it a closure to run, and it will execute that code 10 times in a row. You’ll then get a report back of how long the call took on average, what the standard deviation was (how much variance there was between runs), and even how fast each of those 10 runs performed if you want the details…

Kinda handy to be able to get hard numbers for your refactoring efforts that easily, indeed.

Any other compilation or execution tips, tricks, and tradeoffs to share, Dear Readers?

Paleo App Dieting

No doubt you’re aware that bigger is not better for downloads on the App Store, especially if you hit the dreaded 100 MB cellular download limit, but were you aware that even if you haven’t there’s a marked disadvantage to download size increasing? Well, here it’s quantified by way of Actual Real Life Experiment:

We bought a successful app, loaded it with extras and watched it fail

… we estimate a linear change in install conversion rate below the 100MB cutoff of -0.45 percent install rate per MB. Above the 100MB cutoff, we estimate a linear change in install rate of -0.32 percent per MB. To our best estimate, the gap between the two lines is covered by a 10 percent instantaneous install rate drop across the cellular download limit.

Although Apple says the cellular download limit is 100MB, we found in practice that a 101MB IPA did not trigger the cellular download block. The actual limit was somewhere between 101MB and 123MB, and it varied depending on the exact build.

Increasing the size of our app from 3MB to 99MB reduced installs by 43 percent, and the increase to 150MB reduced installs by 66 percent in total…

They’ve put together a handy App Readiness Guide with an especially handy App Size Calculator to let you check out your favourite apps.

Sooo, how do we get our size down? If you’re shipping to iOS 9 and later, there’s great options:

App Thinning (iOS, tvOS, watchOS)

  • Slicing is the process of creating and delivering variants of the app bundle for different target devices
  • Bitcode is an intermediate representation of a compiled program. Apps you upload to iTunes Connect that contain bitcode will be compiled and linked on the store…
  • On-demand resources are resources—such as images and sounds—that you can tag with keywords and request in groups, by tag. The store hosts the resources on Apple servers and manages the downloads for you…

Those are generally pretty straightforward to adopt, although you may have occasion to refer to

But if you’re still shipping for iOS 8, none of those help your iOS 8 users at all. Ah well.

First thing is to make sure you’re stripping debugging symbols and dead code with Xcode build settings. Also, make sure that Xcode isn’t bloating your asset catalog behind your back. The setting for that is “Optimization” aka ASSETCATALOG_COMPILER_OPTIMIZATION — and if you haven’t set anything, apparently it defaults to “time” which undoes all your compression and bloats up wildly besides. So set it to “space” instead.

If you need to dig deeper than that, here’s some useful tools for messing with your binary and asset catalog to figure out just what’s going on:

Bloaty McBloatface: a size profiler for binaries

Crunch: “Extract resources from iOS apps. Make iOS icons.”

cartool: “Export images from OS X / iOS .car CoreUI archives.”

AssetCatalogTinkerer: “An app that lets you open .car files and browse/extract their images.”

iOS-Asset-Extractor: “A tool to extract image assets from the iOS SDK.”

And if you need to go still deeper into smallerizing those graphics, well then you’ll have to go to some work. Possibly useful approaches include:

PaintCode is your goto tool for converting vectors into code — and it now supports Swift 3, Android, and JavaScript!

Or you could use SVG files as resourcesMacaw is a new library that looks particularly good for that.

TexturePacker is your goto tool for creating sprite sheets, if that suits your resource usage profile.

ImageAlpha + ImageOptim is an effective strategy for reducing PNG sizes.

JPEGmini is particularly good at making JPEGs smaller.

Or, you could go with the generally well regarded WebP image format, supported by iOS-WebP for instance.

Any more tips? Share and enjoy!

Consistently Immutable

Here’s a good read for when you’re planning a data caching strategy for your Next Great Project:

Managing Consistency of Immutable Models

Immutable models have many advantages, but managing consistency can be difficult. At LinkedIn, we’ve open sourced two Swift libraries to help manage consistency and persistence of immutable models. Unlike Core Data, the API is non-blocking, exception-free, and scales well with large numbers of models and view controllers…

The natural reflex of course is Core Data, and these were their issues:

  • The first problem we ran into was stability…
  • The other issue we ran into was performance…
  • Another issue is there are no eviction strategies…
  • Another point was that migrations are necessary…
  • The final thing for us was scalability…
  • Even if we were to solve all of these problems, we didn’t like the programming model that Core Data provided. One of the things we didn’t like is that all the models were mutable, and they’re not thread-safe, so when you pass it to a different thread, you need to reread from the database…

We could nitpick over how serious these problems actually are if you know what you’re doing, but yeah that last one is kinda a deal. So what would a modern architecture look like, you ask?

What we really wanted to try was to use immutable models for all the data in our application. Immutable models have long been a cornerstone of functional programming languages, and with the introduction of Swift to iOS, I think that they’ve been pushing this idea of immutability. Swift has a bunch of “immutable by default” features, and personally, I’ve been learning a lot about immutability because of Swift. I’m going to list a few of the examples of why immutable models are beneficial:

We’ll assume you know those benefits already, but if not TL;DR they’re easier.

  • We wanted immutable, thread safe models for the reasons which I just went over.
  • We wanted consistency, so a change in one place would automatically be reflected elsewhere in the application.
  • We wanted non-blocking access on all reads and writes. There wouldn’t be any disk access on the main thread.
  • We wanted a simple eviction strategy. Looking at some of our peers, we saw that a lot of apps were using 200, 300, 400 megabytes of disk space, and ideally, for us, we wanted to limit it below 50 megabytes.
  • We want it to scale well. Again, as I said, we have hundreds of models and view controllers, and we wanted easy migrations. Actually, we wanted to write no migration code at all, ever.

To accomplish all these things we wrote RocketData.

RocketData is a caching and consistency solution for immutable models. It’s intended to replace Core Data or at least fulfill that role in an application. It’s written 100% in Swift, and we really like it…

Definitely read it all, but here’s the secret sauce:

The Consistency Manager, as I said, is truly the engine which drives everything. It’s an entirely separate open-source library that RocketData depends on. It’s written completely in Swift, and you can use it independently.

and here’s the executive summary:

Core Data Comparison

There is no tool which will solve every problem. For many use cases, we believe Rocket Data is a better option to Core Data because of the speed and stability guarantees as well as working with immutable instead of mutable models. However, Core Data is useful for other use cases, and it’s important to consider the differences before you make a decision for your app…

Always good to have options … and this looks like a pretty sweet one!

UPDATES:

Speaking of options: Core Data or Realm

Make Collections Great Again

Pretty good chance you use UICollectionView pretty widely in your apps, right? And pretty much exactly the same chance you’d like some extra performance and enhanced reusability, no doubt? Ch-ch-check out

Open Sourcing IGListKit

Today, we are excited to announce that we’re open sourcing one of Instagram’s core frameworks: IGListKit. This framework powers how we take data from the server and turn it into fast and flexible lists.

To do this, we combined a familiar data-driven UICollectionView architecture with a state-of-the-art diffing algorithm. With this setup, we created a tool that lets engineers with varying levels of experience work quickly and safely on Instagram. Outside of Instagram, IGListKit can help anyone who is building lists to skip tedious and error-prone setup, and utilize one of the fastest diffing algorithms available for iOS…

Better Architectures

IGListKit reduces the chance of having “massive view controllers” by dividing responsibilities into multiple layers: the view controller, list adapter, section controller, and the cell.

This design has a positive side effect of building your lists with independent components, meaning you end up with reusable section controllers and cells. The result is a one-way data flow, where each component has no knowledge of its parent…

Diffing

In Instagram, our data can change a lot. For example, new data arrives from the server each time you like a photo or you receive a direct message in real-time.

UICollectionView can handle all types of updates (deletes, reloads, moves, and inserts), but performing those updates without crashing can be a little tricky.

We built a lightning-fast diffing algorithm based on a paper published back in 1978 by Paul Heckel. This algorithm finds all of the possible updates that UICollectionView needs in linear time (that’s O(n))…

That’s a pretty serious level of win … especially if you’ve got some experience with that “little tricky” task of managing updates elegantly, in the same way that liquid nitrogen is a “little chilly”. So if you’ve got a big collection of data to manage, we wholeheartedly recommend you check that out!

ADDENDA:

And while you’re looking at libraries to make your UI nicer, check out this most excellent list:

39 Open Source Swift UI Libraries For iOS App Development

and of course there’s always

Awesome iOS: A curated list of awesome iOS libraries, including Objective-C and Swift Projects

UPDATES:

The Case for Deprecating UITableView

IGListKit Reference

IGListKit Tutorial: Better UICollectionViews

IGListKit — Migrating an UITableView to IGListCollectionView

Rollout The Red Carpet

So you might have heard of Rollout.io before:

Update Live Mobile Apps

Instantly Fix Bugs|

Deploy code-level changes to native iOS apps, without waiting on the App Store.

Which works by remotely swizzling your methods up to and including completely replacing with JavaScriptCore-executed code, which is 100% legit as a delivery method, no really it is, here check the latest rules:

3.3.2 … an Application may not download or install executable code. Interpreted code may only be used in an Application if all scripts, code and interpreters are packaged in the Application and not downloaded. The only exceptions to the foregoing are scripts and code downloaded and run by Apple’s built-in WebKit framework or JavascriptCore, provided that such scripts and code do not change the primary purpose of the Application by providing features or functionality that are inconsistent with the intended and advertised purpose of the Application as submitted to the App Store.

All well and good then … except that swizzling only works in Objective-C and it’s $CURRENT_YEAR, who still writes Objective-C? Cha, we’d spend our ever so valuable blogging space on that right after an in-depth article on the state of 3270 emulation, amirite? (With all due respect to the author of that no doubt invaluable if you need it fine bit of work, mind you, just that most of the world has moved on a bit!) Well, look at what the boffins over Rollout way have come up with now:

Hi Everyone,

I’m delighted to announce that Rollout now supports Swift apps!

After months of development, testing and tweaking we’ve just released our official Swift support.

If you’ve been waiting for Swift support in order to try out Rollout, either create a new app and install the SDK or upgrade your existing app with the latest SDK version…

Uh … yeah? And just how exactly did you get that to work?

The heart of Rollout’s Swift patching magic lies in a technique we call Pre-SIL instrumentation.

SIL stands for Swift Intermediate Language, it is generated from the Abstract Syntax Tree. This intermediate form is used by the Swift optimizer to perform Swift language specific optimizations prior to generating the LLVM IR.

Rollout instrumentation needs to happen before the optimization phase so it will work even if the method was inlined, the dispatching was de-virtualized and more (I’ll write more about optimizations in Swift in the near future).

To add this code instrumentation Rollout runs the following flow:

  1. Replace the swiftc compiler with a proxy script
  2. When swiftc compiles a file, intercept the file and instrument it
  3. Identify all methods in file
  4. Instrument all methods with the patching mechanism

All of the above needs to happen without a cost in compile time, runtime and most importantly maintaining a consistent debugging experience (as if Rollout didn’t touch your code)…

Well, brush our teeth and call us pearly. If that does indeed work as advertised, that is quite the leap forward for application maintenance, isn’t it? Looks like the free tier doesn’t support Swift so it’s not a completely trivial cost to adopt, but hey, it’s pretty cheap compared to the damage a broken app could do you!