iOS

Moving to SF Symbols by Paulo Fierro

I'm slowly working on replacing existing assets with SF Symbols wherever possible in this app I'm working on. In order to maintain a consistent look on iOS 12 and below I'm replacing the existing 1/2x/3x PNGs with a single PDF, by exporting the SVG from the SF Symbols app into Sketch.

By naming the bundled assets the same as the system names, I can use this handy extension to avoid the "if available" dance every time:

At first I wasn't sure if I wanted to update the older assets, but I think I prefer a consistent look regardless of iOS version even if it does mean a bit of extra work. Moving to PDF assets also means less files to update and hopefully a smaller app size.

I ❤️ cocoapods-binary by Paulo Fierro

I've been using Cocoapods for dependencies for as long as I can remember. Personally I never really got along with Carthage, but some people prefer it.

Over the weekend I came across a post titled "Using CocoaPods with pre-built frameworks instead of source files" which has radically decreased the build time on some of my projects. It describes how you can set up the cocoapods-binary plugin to precompile your dependencies which dramatically reduces the amount of time Xcode needs to build your app.

In two small-to-medium sized apps with 5-10 dependencies I saw upto 10x improvements. A clean build (with nuked derived data) going from about 90 seconds down to 9. 🤯🤯🤯

If you're using Cocoapods you really should try it out.

Listening for video playback within a WKWebView by Paulo Fierro

I’m currently working on an app for a client where certain features are disabled when a video starts to play. Specifically, a video that’s embedded in a WKWebView.

One way of doing this would be to inject Javascript into the page like I’ve written about before and let that attach listeners to every <video> tag on the page. When a video changes its play state our listener could post a message to the app via webkit.messageHandlers[_HANDLER_].postMessage(_OBJECT_); and we would need a handler in the app to do whatever it is we want it to do.

That's a little messy.

When a video starts to play in a WKWebView the <video> is replaced by the native video player. However, within the app we can’t get a reference to this video component in order to query its playing state, so I wondered if maybe this might just fire an NSNotification we could listen for.

I couldn’t find any documentation for this so I decided to listen for all notifications and see if I could find one that would do the trick.

To do that I added a notification center observer with no specific name, which translates to give me ALL of the notifications:

Clearing the console before tapping play on the video led me to find that there actually is a notification that gets fired from the web view — its called SomeClientPlayingDidChange.

Inside the notification’s userInfo dictionary lies an IsPlaying key, with exactly what we want.

This meant that now we could add an observer for this notification and a handler to do whatever it is we need to do:

Caveats: this notification doesn’t appear to be documented and could change at any time. It probably will. At the time of writing this works on iOS 8.x/9.x - however since we’re simply listening to the notification, the app might lose this functionality but shouldn’t lead to any crashes.

How not to lose Apple Watch Activity + achievements when migrating to a new iPhone by Paulo Fierro

As an app developer I have lots (hundreds?) of apps installed, some I use and others are to see how certain unique features work or to compare implementations of certain ideas.

As an app developer I also upgrade my iPhone every year in order to test and build against the latest hardware. I always set my phone up from scratch, as a new device, and take this time as a spring cleaning of sorts. When I picked up my 6s Plus last Friday I realised that this would not be an option this time around.

This was because of two reasons:

  1. for privacy reasons health data is not backed up to iCloud
  2. an Apple Watch can only be paired with one phone at a time.

This means that I would lose all of my Activity data from my watch, but most importantly all of my Achievements too. I guess those Achievements work if I care so much about them — some are damn hard to get.

Achievements

So in order to not lose that data we have to do a little dance:

  1. Unpair your watch from the old phone. This automatically takes a backup of the watch data onto the phone — there is no way to do this manually that I’m aware of.
  2. Take a backup of the old phone. The fastest way to do this is via iTunes, and remember to set a password. Encrypted backups contain certain information other backups don’t, including your health data.
  3. Connect your new phone to iTunes and restore the backup you just made.
  4. Pair your watch to the new phone and restore the Watch backup when prompted.

Once this is complete you should be exactly where you left off with all your apps and settings including activity history and achievements.

In retrospect this was so much easier than setting it up from scratch that I think I'll be doing this in the future regardless.

iOS 9 + App Transport Security + Amazon Web Services by Paulo Fierro

The release of iOS 9 is just around the corner and with that comes App Transport Security. This new feature will enforce that your app's network connections follow best practices. This is handled at a low level and is enabled by default in iOS 9 and OS X El Capitan — and may cause issues in existing apps.

We have a few apps that load data from Amazon Web Services over HTTPS and on iOS 9 they stopped working. The reason being that App Transport Security requires server certificates to be signed with SHA-2 by default and at the moment the AWS certificates use SHA-1.

Amazon has announced AWS will move to SHA-2 by September 30, 2015.

Until then we can add the domain in question as an exception and set NSExceptionRequiresForwardSecrecy to NO. This does not turn off ATS (that would be a bad idea) it simply states that we accept ciphers other than SHA-2.

The Info.plist entry

The Info.plist entry

A quick change to your Info.plist and you’re done!

For more information you should watch Session 711 from WWDC 2015.

Update (Oct 1, 2015)

Looks like this is still not working properly. I ran the ATS diagnostics using nscurl on El Capitan and got these results.