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
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.
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.
If you want a white status bar, then you need to use the new value:
<meta name="apple-mobile-web-app-status-bar-style"
content="dark-content">
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 deprecatedblack
value - One value
dark-content
equivalent to the removed and never documentedwhite
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.
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.
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 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
<model>
<source src="model.usdz">
</model>
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 thecurrentSrc
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:
document.querySelector("model").ready
.then( () => console.log('Model ready') )
.catch( error => console.log('Error loading the model') )
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.
navigator.contacts.select(
['name', 'email'], {multiple: false}
).then( contacts => console.log(contacts) )
.catch( error => console.log(error) )
The properties available for query in this version of iOS/iPadOS:
- name
- 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
andicon
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}"
attributeon="https://my.shop">
Click here to buy
</a>
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 firstwheel
event);wheel
event listeners on the root are not passive; some changes tohover
/pointer
media queries are available. - Fixed
devicemotion
anddeviceorientation
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