Maximiliano Firtman's articles, notes and learning experiences for

iOS 14.5 brings the new Safari 14.1 to PWAs and the Web Platform

What's new, what's missing, new challenges and new capabilities for iPhone and iPad

Maximiliano Firtman avatarby Maximiliano Firtman Twitter @firt About Newsletter

About 9 min reading time

Not every minor iOS version update includes changes in the Web platform, but iOS 14.5 is an exception. It has a new version of the WebKit engine, changes in WKWebView, Safari 14.1 as the browser, and an updated engine for PWAs. It's also the first update in 2021 for Web and PWA developers since the release of iOS 14. And, as usual, as of today, there are no Safari release notes for this version.

This version's research reminded me of the first article of this series 10 years ago: a feeling with a mix between excitement and frustration after finding something new but completely undocumented. How should I call the series of iOS articles I've been doing so far? Some options: "Safari on iOS: The missing documentation", "The inflammatory* guide to Safari for Web professionals", "Eternal sunshine of the documentation-less platform" 🤔

Anyway, iOS 14.5 is packed with new things you should know if you are a web developer, including some changes on the PWA platform.

Summary #

  • Progressive Web Apps: Changes in Status Bar, Media Session API (experiment), Bug and Missing Features Report
  • Speech Recognition API
  • Contact Picker API (experiment)
  • New <model> HTML element for 3D/AR models (experiment)
  • Privacy-Preserving Ad Click Attribution
  • Paint Timing API
  • Other API changes: TransformStream API, Web Authentication "Modern", WebRTC Sockets, changes in mouse events on iPadOS, Modern Web Audio API (with support for Audio Worklets)
  • CSS: individual transform properties, animations for discrete properties and pseudo-elements, flexbox gap property
  • Web Assembly: BigInt, sign-extension, bulk-memory, reference types
  • Web Views: Added full support for getUserMedia and TouchID/FaceID.
  • JavaScript: modules support in Workers and Service Workers, private static methods, top-level-await, and more

Progressive Web Apps on iOS 14.5 #

After defining the idea in 2007 and supporting all the specs in 2018, Apple finally acknowledged the name "Progressive Web App" and the platform as an alternative to the App Store. It's not how we all were expecting this to happen, but at least it's a start. No one from the WebKit and Safari teams is talking about PWAs; Apple's lawyers defined PWAs and their compatibility on iOS and iPadOS as evidence against App Store monopoly to the Australian Competition and Consumer Commission (ACCC) (see full PDF document). This declaration supports what I said earlier this year about why Apple kept the PWA platform as a minimal viable product.

Apple acknowledges the existence of the Progressive Web App platform

Status Bar Change #

The first change that I've discovered for PWAs in 14.5 is the status bar. The status bar stopped rendering a white status bar as in 14.4. So I started researching the meta with the name apple-mobile-web-app-status-bar-style, and I've found something interesting. There are new values for this meta tag, never documented by Apple. But they are doing the trick on iOS 14.5, so if you are expecting a white status bar, you need to make a change.

The Apple documentation about this meta tag was last updated in 2014 and it's outdated. It's currently under the Documentation Archive) and there is no other document replacing it.

These are the current values accepted by the meta tag: light-content, dark-content, hidden, default, and it still takes two old values now marked as deprecated: black, and black-translucent. For some years, white was also accepted, but it was never documented. Now it's officially out.

From iOS 14.5, if you want to render a white status bar in your PWA you need to make a change in your HTML and use dark-content

If you want a white status bar, then you need to use the new value:

<meta name="apple-mobile-web-app-status-bar-style" 

The value black-translucent is still the only way to simulate something similar to a display: fullscreen in the Web Manifest on iOS and iPadOS. It's marked as deprecated, but Apple never documented what's the replacement. Now that I've found the hidden value, I think that is the one that should be replacing it. However, it's not working, and while I can confirm the value is set in the Web Clip (the icon on the home screen), nothing happens differently than the default.

A white static status bar is not possible if the user has a dark appearance enabled unless you use black-translucent and a white document's background color.

Based on the appearance of the device (Light or Dark) and the value of the meta tag, the status bar of your PWA will follow the following pattern

Meta value Light Appearance Dark Appearance
(no meta present) W/B W/B
default B/W W/B
light-content W/B W/B
dark-content B/W W/B
hidden B/W W/B
black (deprecated) W/B W/B
black-translucent (deprecated) W/T W/T

B/W=Black over White, W/B=White over Black, W/T=White over Transparent (viewport takes fullscreen)

The new values make non-sense, and it seems they are shipping a half-baked implementation.

We have:

  • A deprecated value black-translucent with no alternative value
  • Three values with the same result (default, dark-content, hidden)
  • One value light-content equivalent to the deprecated black value
  • One value dark-content equivalent to the removed and never documented white value
  • A hidden value that hides nothing
  • If you don't provide a meta tag, the results are different than using default as a value

For some reason, the iOS simulator exposes different status bar colors than the ones I see on real devices

Nothing seems to make sense, but it is what it is 🤷‍♂️

I'm not sure if these new values appeared now or they've been hidden there for a while, but from iOS 14.5, the deprecated black value and the default values are changing, so the new undocumented but actual values appear as the only solution

What about theme-color? #

The Web App Manifest spec and the HTML Living Standard support the theme color, which is used by Android and desktop PWAs to tint the browser, the status bar, or the title bar. Safari was ignoring this value in the past. It's still missing it on Safari 14.1. However, there is good news: WebKit has added support for it, it's now part of the Manifest data structure, and WKWebView will have a themeColor property.

Now the internal C structure in WebKit that stores Web Manifest's meta-data includes the Theme Color, but it's still not implemented on iOS

It's still unclear if Apple will use that property parsed by WebKit to style the PWAs and stop using the meta tag in the future; we'll need to wait some months until iOS 15 maybe or wait for the miracle of hearing something from the Safari team before that.

Background Audio #

After Web Push and a better installation prompt, background audio for PWAs is the following typical complaint. Well, still no luck. Background audio from a PWA continues playing in the iOS Simulator, but that's not the situation on an actual device. I presume it's because the process is suspended not matter if you are playing audio.

But there is one hope: the Media Session API is now available as an experiment (disabled by default). When your PWA was playing audio (or even video), the user can control the media playing from the Control Center and the notifications area. That means, shortly, this can be how Safari will allow PWAs to play audio in the background. We'll see!

Bugs and Missing Features #

Some old bugs are still there, such as seeing "Untitled" in the status bar's back button when you open a link from a PWA. Another bug that I saw without consistency is that sometimes the service worker is not available when you are offline and open the app from the home screen.

The "Untitled" back button is still there to go back to a PWA when navigating to another app

Also, the missing features that a lot of people are waiting for are still pending, such as:
*PWAs in the App Library
*Web Push
*Background Sync
*Better Installation Flow (beforeinstallprompt or an App Banner)
*Ability for other browsers to install PWAs

Speech Recognition API #

Safari has supported Web Speech API partially for years (only the Speech Synthesis part). But now, the team has decided for some reason that eight years after Google Chrome started to support the Speech Recognition part of the spec, it was time for Safari to do the same.

From iOS and iPadOS 14.5, Safari and PWAs can recognize speech from the user using the microphone and an Apple cloud-based service. It works only after the user has started an interaction (such as a click handler), and it can recognize multiple languages.

Update 27/4: Unfortunately, the Speech Recognition API does NOT work inside a standalone PWA. The API is available, so a feature detection algorithm detects it, but nothing happens. My guess is that it has to do with the speech or microphone permission that is not working while in a PWA. Also, it has to do with Apple folks not testing within standalone apps, as usual.

The first time a website wants to use the Speech Recognition user will grant permission to the API and sending voice to Apple's server; then any new visit will require giving access to microphone only

The Model HTML Element experiment #

WebKit now supports a new HTML element as an experimental feature that was never proposed or discussed in any standard or spec as far as I know.

The feature is disabled by default, and it represents a 3D Model that can potentially be rendered in virtual reality or augmented reality. The model element needs one or more <source> elements, presumably in different formats. However, it's available in the DOM but not working yet:

The code to render a 3D or AR model will look like

<source src="model.usdz">

Right now, enabling the experiment does not render any model on the screen. The element is in the DOM using the new constructor HTMLModelElement, and the currentSrc property works, but nothing is rendered on the screen, so this seems like an experiment in the early stages

The model element will support a ready promise to know if the model could be loaded or not:

.then( () => console.log('Model ready') )
.catch( error => console.log('Error loading the model') )
The HTMLModelElement exist in the DOM if you enable the experiment, but I couldn't get any rendering on the screen

We need to remember the ability to render 3D/AR model was added to Safari 12 in 2018, but it is using a weird <a> element with a rel="ar".

It's interesting to see Apple innovating again with the Web; it's also odd to see them implementing something that was not discussed anywhere before when they always complain that Chrome implements features that are not yet standardized.

Contact Picker API #

The Contact Picker API is now an official experiment (disabled by default) in Safari and PWAs. It let web apps pick a contact from a selector and get the value(s) as a JavaScript object. This API has been in Chrome for a year and a half, being one of the shortest periods between Chrome and Safari implementations in several years.
    ['name', 'email'], {multiple: false}
  ).then( contacts => console.log(contacts) )
   .catch( error => console.log(error) )
A multiple contact picker from Safari or a PWA if you enable the experimental feature

The properties available for query in this version of iOS/iPadOS:

  • name
  • email
  • tel

The similar native component CNContactPickerViewController has more properties available, such as givenName, familyName, jobTitle, organizationName, postalAddress, socialProfiles that are not available from the Web platform at this time.

Android since version 83 also supports address and icon as available properties to query. The spec makes the list of properties dynamic so that every platform can pick the exposed properties. Do not query for unsupported properties, or you will get a TypeError exception.

Privacy-Preserving Ad Click Attribution #

Private Click Measurement (PCM), a new ability available in Safari from iOS 14.5, to track click conversion and link attribution for seven days is available. It's also the first time WebKit documented something new when shipping it in a beta version of iOS.

If you read the spec, the WebKit blog, the Safari settings, you will see different names for the same feature: "Privacy Preserving Ad Click Attribution," "Private Click Measurement," "Privacy Preserving Ad Measurement."

To use this feature, each link must include new attributes, and attribution will be sent over a well-known URLs. Two hundred fifty-six source IDs can be tracked with 16 different conversion events. Attribution data will be stored client-side for seven days and can be deleted or turned off by the user.

<a href="https://my.example/id" 
attributionsourceid="{8-bit source ID}"

Click here to buy

Read more about this spec in the WebKit blog.

The solution also includes a way for native apps on iOS to send click attribution for websites. (Not sure how that part can become standard as it is, though)

There is an experiment that can be enabled to help to debug the usage of this API: Private Click Measurement Debug Mode

Paint Timing API #

The Paint Timing API is out of the experiment, and it's now enabled by default. It let us query about only one web performance metric: First Contentful Paint (name equals to first-contentful-paint).

Other Changes #

Media and CSS #

  • Individual transform properties: rotate, scale, translate
  • Flexbox gap property is now available
  • Web Animations now available for discrete properties and pseudo-elements
  • Some reports are saying that Webm video container format and OGG Vorbis audio codec should be available in this version, but I couldn't confirm it with several samples. It seems that these formats are available on Safari 14.1 only for macOS.
  • CSS Aspect Ratio (experiment, disabled by default)
  • CSS Overscroll Behavior (experiment, disabled by default)

Web Platform APIs #

  • TransformStream API
  • "Modern" Web Audio API: support for Audio Worklets and other additions
  • "Modern" Web Authentication: I don't know what that means
  • WebRTC Sockets
  • WebRTC VP9 profile 0 enabled
  • Web Assembly improvements: BigInt, sign-extension, bulk-memory, reference types
  • MediaRecorder API seems to be there, but I can't confirm it yet; my code didn't work
  • Changes in mouse events on iPadOS: wheel event gestures are now non-blocking (preventDefault() is only allowed on the first wheel event); wheel event listeners on the root are not passive; some changes to hover/pointer media queries are available.
  • Fixed devicemotion and deviceorientation events to work in third-party iframes with Feature-Policy, allowing it
  • New permission dialog may be available for iframes using the Geolocation API
  • WritableStream API (previously a disabled-by-default experiment)

JavaScript runtime #

  • Modules support in Workers and Service Workers
  • Private static methods
  • Top-level await
  • WeakRef

WebViews and other browsers #

  • Full support for getUserMedia
  • TouchID and FaceID support using WebAuthentication
  • Picture in Picture support

Experiments that are still disabled by default #

  • WebGL 2
  • HTTP/3
  • Web Share Level 2
  • Lazy Image

Other New Experiments (disabled by default) #

  • Disable Media Experience PID Inheritance
  • Lazy iframe loading
  • ScreenCapture (I couldn't test it)
  • WebRTC Insertable Streams

Anything else? #

Did you find anything else? Let me know on Twitter @firt

Half typewriter, half computer

© Maximiliano Firtman (@firt) contains a collection of writings, thoughts, notes and learning experiences for web and mobile app developers authored by Maximiliano Firtman.

Contact me: Personal Website Buy Me A Coffee