Under The BridgeUnder The Bridge

Notification Tokenism

So, did you catch WWDC 724 yet? It’s less than 15 minutes, check it out:

What’s New in the Apple Push Notification Service (transcript)

Starting with a review of the HTTP/2 based provider API, you will learn about an important new feature: Token Based Authentication. Learn to connect to APNs using authentication tokens for sending pushes via the HTTP/2 API, relieving you of the overhead associated with maintaining valid certificates.

Ah, yes. Longtime readers will remember various instances of untrammelled joy (where by “joy” we mean “near-homicidal frenzy”) APNs has provided over the years, so this is a very interesting indeed development. Full details were published September 20 at

Local and Remote Notification Programming Guide / Apple Push Notification Service

and announced September 22. So let’s check this out, shall we? Especially as we got the annually dreaded “This certificate will no longer be valid in 30 days.” email day before yesterday, which makes the timing entirely apropos!

Step 1: Oh look, now under certs in the Dev Portal we have this new “APNs Auth Key” option! So add one, and…

Step 2: Read the instructions:

Download, Install and Backup

Download your Authentication Key to your Mac, then double click the .key file to install in Keychain Access. Make sure to save a back up of your key in a secure place. It will not be presented again and cannot be retrieved at a later time.

Step 3: Be confused as the download gives you a .p8 file, not a .key file, and it’s not evident how you get that into the Keychain.

Step 4: Check out the discussion on the dev boards:

It’s a PEM-encoded, unencrypted PKCS#8 file. You can inspect it with `openssl pkcs8 -nocrypt -in <your_file.p8>`, but you’ll need a newer version of OpenSSL than the one that ships with El Capitan (I’m not sure which version comes with Sierra). I’m not sure how to import it into the Keychain, but I also haven’t run into a situation where having it in the Keychain would be helpful (other than just for storage).

Step 5: OK then, let’s find some service that can use this shiny new .p8 file then…

Step 6: ¯\_(ツ)_/¯ Not much out there yet!

Alright, so we’ll keep working with a cert-based process for the moment then, check for UPDATES! below once we find some. In the meantime, development tools that can work with the shiny newness? Hmmmm … looks like you’re pretty much on your own there too as we write this. Right then, if you know of any token-supporting services or tools, hit the comments section!

If you’re proactive enough to want to help move the development tools scene along, our goto for APNs tinkering for a while now has been Knuff: “The debug application for Apple Push Notification Service (APNs).” along with Knuff-Framework “just add it to your application and the phone will be visible under “Devices”” and Knuff – The APNs Debug Tool on the App Store! Pretty complete ecosystem there and we strongly encourage helping out with it if you’re interested in this space.

If you’re new to this APNs thing, or If you’d simply like a straightforward HTTP page to use for testing, check out this new site PushTry.com to, eponymously enough, try pushing:


Nicely done tutorials for both iOS and Android, clean and functional; definitely recommend you give that a pushtry. And they’re working on token support too!

Should you be looking to get this on your server side ASAP, a quick look around for projects at least using HTTP/2 APNs, that being kinda the floor for ‘actively maintained’ currently, in a variety of environments turns up these:

VaporAPNS “is a simple, yet elegant, Swift library that allows you to send Apple Push Notifications using HTTP/2 protocol in Linux & macOS. It has support for the brand-new Token Based Authentication but if you need it, the traditional certificate authentication method is ready for you to use as well. Choose whatever you like!”

swift-apns: “Swift Framework for sending Apple Push Notification over HTTP/2 API”

node-apn: “A Node.js module for interfacing with the Apple Push Notification service.”

ApnsPHP: “Apple Push Notification & Feedback Provider”

APNS/2 “is a go package designed for simple, flexible and fast Apple Push Notifications on iOS, OSX and Safari using the new HTTP/2 Push provider API.”

And again, if you have good … or bad … experiences with any particular piece of APNs server kit, let us know!

iMessage In A Bottle

So you jumped on board the iMessage train yet? It’s important enough the mothership gives it a top level website folder no less,

iMessage + Apps

Check that out for links to WWDC videos, sample codes, yada yada yada for apps and stickers. Never really got the whole sticker thing until moving here to Thailand where Line is the preferred means of communication to the tune of 90% of mobile Internet users; but yeah, they send a couple billion a day. If you’ve got anything resembling artistic ability, might want to look into that, hey it’s a seriously good paying market for clip art!

More interesting to most of you Dear Readers I imagine would be the opportunities to write apps, and here is an excellent article to get started on that:

Introducing the Airbnb iMessage App

We started out looking to define the grand vision of planning your Airbnb trip within Messages — what would that look like on this new platform? Over the course of just a few weeks before the iOS 10 release, our team rapidly prototyped on a variety of ideas. We started with countless drawings and mockups of possible features, and as we became more familiar with the possibilities and limitations of the Messages Framework, a product began to form. Once we had something we could use, a group iMessage thread between engineers, designers, and product managers allowed us to quickly discover the features we wanted — a rather meta approach. At this point, we had an iMessage app where people could share homes between friends and view key details about the accommodation…

Speaking of collaboration, an iMessage app wouldn’t be complete without an additional social feature: voting. When sharing a message with friends, each collaborator can vote on homes they like and see who else has voted on them. This gives the trip organizer a bird’s-eye indication of the most popular listing, greatly simplifying the decision of which one to book…

Goes on in detail about features, limitations, and process; even if you’re not currently planning an iMessage app, in which case you probably should be, this’ll get you up to speed with the state of the framework nicely!

Machines Of Learning Grace

Our nominee for Most UnderDiscussed Shiny New Stuff with this year’s Apple crop definitely has to be BNNS. What, not ringing a bell? Ch-ch-check it out:

The Accelerate framework’s new basic neural network subroutines (BNNS) is a collection of functions that you can use to construct neural networks. It is supported in macOS, iOS, tvOS, and watchOS, and is optimized for all CPUs supported on those platforms.

Of course, there’s a perfectly good reason it hasn’t made more of a splash, which is

BNNS supports implementation and operation of neural networks for inference, using input data previously derived from training. BNNS does not do training, however. Its purpose is to provide very high performance inference on already trained neural networks.

That’s a bit too high of a bar to jump, right? Well, not quite as much as you’d think! See, if you even noticed Google open sourcing TensorFlow at all, you probably figured it was a bit academic for any real world application you were working on, right? Well, here’s the inestimable Aaron Hillegass to explain the synergy here:

Use TensorFlow and BNNS to Add Machine Learning to your Mac or iOS App

Thus, there are two ways to get deep learning into your Mac or iOS application:

Solution 1: Do all the neural net work on a server using TensorFlow. You must be certain that all your users always have a good internet connection and that the data you are sending/receiving is not too voluminous.

Solution 2: Train the neural net using TensorFlow and export the weights. Then, when you write the iOS or Mac application, recreate the the neural net using BNNS and import the weights.

Google would love to talk to you about the first solution, so the rest of this posting will be about the second. I’ve used TensorFlow’s MNIST example: handwritten digit recognition with just an input and an output layer, fully connected. The input layer has 784 nodes (one for each pixel) and the output has 10 nodes (one for each digit). Each output node gets a bias added before it is run through the softmax algorithm. Here is the source, which you will get automatically when you install TensorFlow.

My sample code is posted on GitHub

So right now you can ship trainees that won’t learn any more — and feel free to fill in a simile of your choice here for a laugh — if you have a static problem space in your app that could be enhanced with a bit of clever; or you could just get up to speed on the technology now and wait for the almost certainly inevitable addition of backpropagation in future releases! Here’s some more light reading and viewing to help you out with that:

WWDC16 715 – Neural Networks and Accelerate

Basic Neural Network Subroutines: Using The Accelerate Framework’s Convolution Filters

Neural Networks in iOS 10 and macOS

The “hello world” of neural networks

The Perfect 10

Yep, it’s that time of year again, where we all panic about getting new iOS features into our apps before ship date. Know the feeling? Thought so, yep. We’ve got a better excuse than usual this year though; this last month we’ve been settling into the electric city of Bangkok to work at agoda.com. Which we’d thoroughly recommend based on our experience so far; check out all the great jobs if you’re looking for an awesome gig! Any-ways, if you’re looking to get up to speed on iOS 10, here’s some great resources to put the pedal down:

iOS 10 Day by Day

This series has been a great resource for several OS versions now, and this year sure doesn’t look like a letdown so far:

Day 1 :: Messages

One of the new features was the ability for 3rd-party developers to create their own message extensions that can be used from within the Messages application… To demonstrate this exciting new extension type, we’ll take a look at a project that allows two players to play a simplified version of the popular game, Battleships,

Day 2 :: Thread Sanitizer

Xcode has shipped with a new debugging tool called the Thread Sanitizer which can help identify [threading] issues before you even notice them. We’ll create a simple application which enables us to deposit and withdraw money in $100 denominations…

Day 3 :: Xcode Source Editor Extensions

We’ll take a look at building our own extension that replaces ASCII characters with their Emoji equivalents…

Day 4 :: UIViewPropertyAnimator

To explore this new class, we’ll go through a few examples where we animate an image across the screen…

Of course, the Mother of All Tutorial Sites aka raywenderlich.com has their (6th!) annual opus proceeding nicely:

iOS 10 by Tutorials: First 6 Chapters Now Available!

Also note the iOS 10 + watchOS 2 bundle, and check out the latest tutorials/screencasts.

And one particular to finish off with; our entire career, we’ve had requests for voice dictation apps that we’ve always begged off with “Dude, that’s hard. And expensive.” Well, LOOK HOW EASY IT IS NOW:

Building a Speech-to-Text App Using Speech Framework in iOS 10

Truly, we live in the age of marvels.


A List of All Current iOS 10 UI Kits for Sketch

iOS 10 Sampler – A Set Of Examples For Many Of The New Features Added With The iOS 10 SDK

Getting Ready for ATS Enforcement in 2017

Make Xcode 8 Again

Our favorite from the Xcode 8 beta 3 Release Notes is actually this polite little convenience:

.xcconfig files support conditional inclusion of other .xcconfig files, using the syntax #include? instead of the usual #include (which still generates a warning if the file is missing, as before). (11003005)

Sweet! As we’ve mentioned before, it’s much more elegant maintainable and trackable to manage your project settings textually, and this makes that just that much more elegant. That’s pretty much the theme of Xcode 8, it seems: make everything that much more elegant. We thoroughly recommend that you go through the release notes with every new release, but If you’ve been to keep up with that, here’s a good TL;DR on the high points:

What’s New in Xcode 8

1. Swift 2 and 3

Up until Xcode 8, every version of Xcode was tied to a specific version of the Swift programming language. That is no longer true as of Xcode 8. Swift 3 introduces a slew of changes and a considerable number of these changes are breaking…

2. Source Editor Extensions

Developers have been asking for a native plugin architecture for many years. Source editor extensions are a first good step in that direction… [However, note that Alcatraz is dead, so this is a mixed blessing at best -Ed.]

3. Debugging

View debugging is much more powerful in Xcode 8. Reliability has improved and debugging ambiguous or unsatisfiable layouts is much easier thanks to an improved view debugger that displays runtime issues … Xcode 8 also sports a pretty impressive memory debugger for tracking down memory leaks and retain cycles…

4. Code Signing

Code signing issues should be a thing of the past with Xcode 8 … I hope Apple got it right this time. And with me tens of thousands of other developers.

5. Other Improvements and Enhancements

San Francisco Mono; Line Highlighting; Code Completion for Images

6. Documentation

The new documentation format looks gorgeous and the documentation browser is fast and easy to use. Apple also consolidated the documentation for its platforms, resulting in a much smaller memory footprint….

There’s a longer list as part of this veritably encyclopedic collection of What’s New In Everything:

New Stuff from WWDC 2016

Following the tradition from last year, here’s my complete list of all interesting features and updates I could find in Apple’s OSes, SDKs and developer tools that were announced at this year’s WWDC. This is based on the keynotes, the “What’s New In …” presentations and some others, Apple’s release notes, and blog posts and tweets that I came across in the last few weeks…

We’ll go out on a limb here and predict that the thing mentioned here you’re most interested in a deeper dive into is code signing. And here’s a discussion of team implications, and here’s an optimistic article going into thorough background detail:

Code Signing in Xcode 8

Code signing and managing provisioning profiles has been an ongoing annoyance for many developers over the years. I have written and spoken extensively to help people understand what code signing and provisioning profiles are and how they can be better managed. So, you can imagine my surprise and excitement when Matthew Firlik mentioned code signing and provisioning during the Platforms State of the Union (53:30) at this year’s WWDC. It was also revealed that the schedule contained an entire session, What’s New in Xcode App Signing, and two Labs dedicated to the topic. So, does Xcode 8 solve all of my code signing and provisioning profile grievances? Pretty much…

And if you still want more, there’s details and discussions collected over at Michael Tsai’s

Xcode 8 Tips and Issues


Xcode Extensions; Xcode 8 extensions; How to Create an Xcode Source Editor Extension

Simultaneous Xcode 7 and Xcode 8 compatibility

Xcode Visual Memory Debugger; Memory Graph Debugger Tips; WWDC 2016: Visual Debugging with Xcode  

Xcode 8 Document Coding Enhancements

Multiplatform, Single-scheme Xcode Projects

Stop the Xcode 8 iOS Simulator from logging like crazy

Stylishly Swifty

Good talk and links here to keep you abreast of evolving Swift paradigms:

Swifty? Emerging patterns and idioms

Last Tuesday I gave a talk at Swift London called Swifty? looking at interesting patterns emerging from the community, as well as how Swift 3 will shape idiomatic code. You can see my slides on Speaker Deck.

The talk covered several topics, so I thought I’d link to some examples for those who want to learn more.

This is an even better post on namespacing:

Dear Erica: No-case Enums?

Dear Erica, Why would you create an enum with no cases?

This is such a great question! No-case enumerations represent a fairly obscure Swift “power tool”, and one that most developers are unaware of.

The answer, in a nutshell, is that they enable programmers to establish a mini-namespace with little overhead and an assurance that you can’t accidentally create type instances. Under their umbrella, you can group static members into namespaces, build singletons, create cohesive collections of functionality with a minimum surface eliminating freestanding functions, and in one outlier case provide services built around generic types…

And this is an interesting pattern for applying private type extensions which suits well our predisposition towards exposing only designated functionality, a position which is subject to some full and frank discourse over where they’re considering it as not just a style choice but an enforced language construct, if you’ve picked up on that brouhaha; if not, we’ll put an addendum here if/when something actionable happens. In the meantime, check out

Concealment design pattern in Swift

This article introduces a design pattern that I call Concealment, and demonstrates how to use the pattern in Swift code.


The Concealment pattern enables types to support novel, related functionality without adding nonessential members to their interface.


User-defined types can easily be overused in a codebase, giving more prominence to things than necessary. A common example is having a data model entity be involved with tangentially related concerns; such as validation checks, business rule processing, and display formatting. It is preferable to conceal the augmentation and usage of your types behind an API expressly built for a single responsibility, rather than expose those implementation details to all the types’ consumers…

Yep, we agree there; anything that reduces cognitive load is a Good Thing!

Core Data iSunny iDays

Why “iSunny iDays”? Why, because iCloud is going iAway! That’s no surprise for those of you paying attention since 2014 at least, but now it’s sorta-kinda official. As usual, Michael Tsai has a good roundup:

The Deprecation of iCloud Core Data

… When installing the Xcode 8 beta, I noticed that all of the symbols related to iCloud Core Data were marked as deprecated in macOS 10.12 and iOS 10, with the comment “Please see the release notes and Core Data documentation.” Strangely, the Core Data release notes and What’s New in macOS 10.12 documents make no mention of this. What’s New in iOS 10 simply says that “Several NSPersistentStoreCoordinator symbols related to ubiquitous content” have been deprecated.

I asked on Twitter what was up, and no one seemed to know. No one had anything nice to say about iCloud Core Data, either, though no doubt many developers still rely on it. I hoped that all would be explained in today’s WWDC Session 242: What’s New in Core Data. Alas, reports are that absolutely nothing was said about iCloud in the session…

No need to panic immediately, they’re not pulling a Parse on us or anything like that … yet … but you certainly would be well served to adopt an alternate solution if Core Data iCloud sync appears anywhere in your technology roadmap. Apparently the mothership has something in the works, but if you have an immediate development need for Core Data cloud sync, there’s one clear choice:

It seems clear that the way forward is Ensembles, unless you want to write your own sync engine or wait for Apple to announce one. I hope that the deprecation will spur more of the community to coalesce around Ensembles.

Indeed. We’ve been vaguely aware of it since the 2013 announcement, but we’d managed to miss until now that there’s a commercial with source access Ensembles 2 that includes CloudKit and other backends, whilst the original remains open source on GitHub. And in the likely event that you agree that seems a clear way forward, this is a good time to jump on board:

The Core Data Sync Deprecation Sale

If you move to Ensembles now, you not only get the usual support, documentation, and source code, you also get it all at half the standard price. The sale will continue until macOS Sierra is released later this year.

Whilst that sync thing is still up in the air, Core Data itself moved forward nicely this year, most notably in that standing up your stack is now much more straightforward:

Concurrent Core Data, Now Easier Than Ever

Core Data has a popular opinion of being hard to use, especially in concurrent environments. Why is that the case? First, it truly is complex because it solves a hard problem. Second, until WWDC16 Apple haven’t really said how to best set up the Core Data stack. There were many options, each with its own issues, that we had to choose from.

That’s why I’m super happy that things get clearer in iOS 10 with the introduction of NSPersistentContainer…

We’ve been pretty happy with JSQCoreDataKit for our Swift projects, but soon as your deployment targets allow, there’s all sorts of win with the new stuff here!

And as a final note, if you’re all excited about the new playground stuff — and who isn’t? — check out the explorations here:

Using a Core Data Model in Swift Playgrounds

Is this a great time to be alive, or what?

A Wild URL Appeared!

This is an interesting article about using Swift pattern matching for routing deeplink URLs:

URL Pattern Matching

The majority of URL routing libraries use a pattern syntax that can match each element of a URL’s path in one of three ways:

  • Equality: Path element must match the pattern expression
  • Value-binding: Path element can be anything at all, and will be made available in a parameters dictionary
  • Wildcard: Path element can be anything at all, and will be discarded

… There are a few reasons I don’t much like this approach:

  • The pattern matching is abstracted away using special syntax.
  • The parameter name userId is repeated and stringly typed, so it’s susceptible to typos.
  • parameters[“userId”] should never be nil, but the compiler doesn’t know that, so we must force unwrap or add a guard statement.

As it happens, Swift’s built-in pattern matching can be used for each of the three pattern types…

Proceeds to walk through the design process of a few abortive approaches, and ends up with the URLPatterns library here:

I prefer this approach to the approach taken by most URL routing libraries for a few reasons:

  • It’s simple to bypass URLs and open a deeplink directly, e.g. by calling DeepLinker.open(.Home).
  • The pattern-matching code is no longer in a third-party library, which makes it easier to debug.
  • The pattern-matching code leverages Swift’s built-in pattern-matching, which means it can be customized and extended.
  • The pattern-matching and routing processes are separated into two steps. This provides an override point if needed…

Neat! For even more niftiness, check out the Generator approach in URLs and Pattern Matching mentioned in the comments.

And while we’re discussing routing, if you want something more conventional, this looks like a good choice:

JLRoutes: “URL routing library for iOS with a simple block-based API.”

  • Simple API with minimal impact to existing codebases
  • Parse any number of parameters interleaved throughout the URL
  • Wildcard parameter support
  • Seamlessly parses out query string and fragment parameters and passes them along as part of the parameters dictionary
  • Route prioritization
  • Scheme namespaces to easily segment routes and block handlers for multiple schemes
  • Return NO from a handler block for JLRoutes to look for the next matching route
  • Optional verbose logging
  • Pretty-print the whole routing table
  • No dependencies other than Foundation

Looks like a sweet dropin to handle just about everything you’d want, that!

Audit Those Version Checks!

Here’s an extra-special class of problem to watch out for in your iOS 10 testing: Brain-dead version checking. Remember the gales of laughter we all had at those silly, silly Windows programmers when they had to skip Windows 9 because of Windows 95 version checks? Well, this is pretty embarrassing, but apparently there’s a good number of us that aren’t any smarter than Windows programmers:

That’s just painful. But there can’t be that many instances of that out there, right? Right? Let’s check this fine article:

Efficient iOS Version Checking

A GitHub search shows that there are over 8000 results calling substringToIndex:1. All of that code will break with iOS 10. It will instead assume iOS 1, where the only apps that existed were jailbreak apps.

Oh, dear. Well, we know that of course you personally, Dear Reader, would never do anything like that … but we very strongly indeed suggest that you do as full an audit as possible of any codebase you expect to be running on iOS 10 to make sure the Evil Code Elves didn’t sneak anything like that in behind your back.

Read the article for more discussion than you probably need of various ways to address this problem. We say “probably” because you’re all programming in Swift now, aren’t you? so you can just use Swift’s #available operator if you really need to check a specific System version. If you’re not, hey the article dives into its implementation, so copy what you need!

PSA: File Those Radars

Yep, you’ve heard this before if you’ve been around a while, but it can’t be repeated too often:

File radars early and often: The importance of bug reporting

There’s a longstanding debate in the Apple developer community over the value of filing bugs through the Apple Bug Reporter system, commonly known as Radar. Some believe it’s invaluable, the only way to give Apple the feedback they need to ensure bugs get fixed. Others believe it’s valueless, a black hole from which little action or satisfaction ever escapes…

Right now, though, right when the first betas hit, there’s some breathing room. And that’s where radar comes in. If someone at Apple wants to get a bug fixed, they need a radar to point to. If they want to get a bug fixed as a matter of priority, they need a lot of radars to point to. Otherwise they simply won’t be given the time to do it.

That’s also why it’s meaningless whether or not someone else has already found and filed the same bug. First, if everyone assumed that, no bugs would be filed. Second, duplicate filings can be considered like “up votes” that, in volume, shift priority more than they do individually…

So, if you are a developer working on iOS 10, macOS Sierra, watchOS 3, or tvOS 10 apps and you’re encountering bugs, please consider filing radars early and filing often.

Even if you never hear back about them, there are people working on those operating systems right now, people who want to make great software and provide for great experiences — people who will deeply appreciate the radars you file, and your having their backs.

Worth reading it all, but that’s the main points — even though Radar is pretty much useless as a communication tool, it’s the only way to contribute to internal priorities there is. For instance, consider the suggestions in this excellent article on that new Apple File System:

Although APFS does checksum metadata blocks it does not do anything to provide resilience for data blocks. That is a huge omission in a modern filesystem, a point I tried to politely but forcefully make in the File System Lab directly to a responsible engineer. I got the feeling that the APFS team is divided on the necessity of this feature and some people on the team would appreciate some ammo to help win the argument internally. I would encourage anyone who agrees to file radars ASAP requesting this feature…

More importantly filing radars is effectively a vote for a feature and the APFS team is listening. You will never have a greater impact on APFS than going to bugreporter.apple.com and filing radars requesting missing features like parity on data blocks or copying snapshots.

Update: Here is my radar on Data Block Integrity if you want to duplicate it. Even if you copy-paste it your separate report counts as another “vote”.

And if you’re not convinced yet that it’s worthwhile to put in this effort … at least dupe @steipete’s Expose verify state

Steps to Reproduce:

Write a radar

Get it back for review

Observe that it’s simply “Open” no matter the internal state

Expected Results:

An additional exposed field that shows if there have been significant changes.

Actual Results:

We need to rely on guesswork or subtle language changes (which are inconsistent though) to try to guess if there has been progress.

to help out the people who do all the work here!


Hmmm — looks like the wide consensus that filing duplicate Radars is a valid way to indicate support may be incorrect:


If you happen to have any informed perspective on this issue, please share!


Writing good bug reports