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.

Two Things I Learned About My Phone by Paulo Fierro

Today I learned two things about my iPhone I didn’t know you could do. I’m not sure how long they’ve been iOS features, but I wasn’t aware of them — for all I know they’ve been there since the beginning.

The first involves receiving a call. Any time someone calls me, whether its a regular phone call or FaceTime, my desk explodes into a cacophony of ring tones, all slightly out of sync of one another, and sometimes just about loud enough to knock me out of my chair. Its close.

Today I found this screen in iOS 9, Settings > Phone > Calls on Other Devices.

I unselect the devices that I’m signed into but don’t want to ring. So simple, so useful.

The second involves receiving a call while using Bluetooth headphones. I’ve been bitten by the wireless headphone craze and have a pair of Beats Studio Wireless headphones that I use at my desk (they’re great) and Powerbeats 2 while on the go.

However every time my phone rings and my wireless headphones are connected I have to tap the Audio button and select the headphones as the audio source. This means that whenever I get a call I have to say “hold on, one sec” while I route the audio to the headphones — its a little annoying.

Choose your own audio route

Today I found a gem hidden in Settings > General > Accessibility > Call Audio Routing.

If you set this to Bluetooth Headset the audio routes automatically and the problem goes away.

Very cool.

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.

Apple Pay + HSBC UK by Paulo Fierro

Apple Pay launched in the UK last month and I’d been looking forward to it because now I’d be able to use contactless payment methods when in the US using my UK bank cards.

First available was American Express, and setting up this card was very straightforward. Simply complete the guided process and you’re done.

I had been using Amex’s fantastic Passbook integration for several months now and had grown accustomed to the notifications you receive when you use your card. Its lightning fast too and I’d often get a notification before the receipt had even been printed.

Thankfully this is another feature of Apple Pay so I promptly removed the pass from Passbook — renamed to Wallet in iOS 9.

Next up was HSBC. They were supposed to be ready at launch, but then got delayed until July 28. I tried the following day and it didn't work. Thinking there were probably teething problems on HSBC's side I decided to leave it for a few days.

So last week I try to add my HSBC card and it still wouldn’t work.

#really

#really

After some searching I came across an article with a solution to the problem and I could barely believe it. Then I realized it was HSBC after all — lets just say that our experiences with them have been less than impressive, so this is actually par for the course.

Turns out, you can't add an HSBC card to Apple Pay if you're outside of the UK.

Amazing. #amazing

You have to:

  1. Disable Location Services (so your location remains unknown).
  2. Use a VPN to tunnel in to the UK. I recommend TunnelBear.
  3. Add your card.
#finally

#finally

Good job HSBC. I guess I feel more secure?