Maximiliano Firtman's articles, notes and learning experiences for devs-firt.dev

iPhone 11, iPadOS and iOS 13 for PWAs and web development

Maximiliano Firtman avatarby Maximiliano Firtman Twitter @firt About Newsletter

About 17 min reading time

iOS 13 and iPadOS 13

It’s that time again. iOS 13 has just been released with the new branded iPadOS 13 coming in a few days, and iPhone 11 variations being sold from today. So it’s time again to talk what’s new or different for Progressive Web Apps, web design and web development in general.

It’s incredible it’s been 9 years since my first post discovering what’s new in a version of Safari for iOS. More incredible is that Apple is not doing a better job documenting and explaining the differences today. In fact, I think it’s much worse right now.

9 years ago I discovered the first time a browser was implementing a motion sensor API and I did this test video; today, this API is changing; and like 9 years ago, it’s not well documented.

It’s curious that in that old article I was discovering a new API to access the accelerometer that wasn’t documented at that time; in this article, I’m documenting a braking change on that same API that, again, it’s not documented by the WebKit team.

The only good news is that now some Apple and WebKit employees are interacting on social networks and other places, so some answers might appear sometimes, and that’s appreciated.

Get updates on this article by following me on Twitter or subscribing to my email newsletter.

While iOS 13 is now out, iOS 13.1 beta is on the works but for what I can tell so far, there are no differences in the web field yet.

Follow me on this journey. Let’s do it.

In a nutshell #

Short of time? Here is the list of topics I’m covering in the rest of the article:

🚀 Progressive Web Apps #

  • Don’t look further: no Web Push and no App installation APIs, but hope was born on push
  • Apple’s take on the PWA term: we don’t know what you mean by that
  • PWAs in the AppStore? Please no, says Apple
  • New “Hide Toolbar” in Safari that’s kind of fullscreen without installation
  • PWA Lifecycle 3.0: finally, they act like native apps in the app switcher, and they execute code in the background.
  • New PWA installation user interface
  • PWAs don’t share any storage now with Safari, not even Service Worker’s Cache Storage
  • No support for WebSQL anymore
  • Apple Pay now available

🎨 Web Design #

  • Dark mode available
  • iPhones 11, 11 Pro and 11 Pro Max don’t add new viewport sizes to Responsive Web Design
  • MathML coming (it’s an experiment today)
  • CSS conic gradients
  • Adaptive font sizes with website settings
  • One-finger accelerated scrolling now supported on every scrollable DOM element (_iframe_s and elements with overflow: scroll)
  • Careful with iPads: by default now pages will be scaled to prevent horizontal scrolling, no matter your viewport declaration

🛠 APIs for Safari, WebViews, and PWAs #

  • WebSQL support disabled by default
  • Visual Viewport API: detect virtual keyboards
  • Pointer Events
  • Big change on Motion Sensors APIs: we need to request permission explicitly
  • LinkPresentation Framework for native apps
  • 3DTouch support on iPhone 11 was removed, no way to emulate the Haptic Touch replacement on the Web
  • Different image sizes option now available when uploading images
  • New experiments available
  • Keep Alive for fetch requests
  • Sign In with Apple now available
  • Apple Pay on WebViews and PWAs

🆕 iPadOS 13 #

  • Desktop-class browser by default on most iPads
  • iPadOS and macOS expose same Safari, is there any way to still detect iPads?
  • Media Source Extensions available
  • Hover events on the iPad are now emulated
  • Two Safari instances can now run side by side on multitasking
  • Final iPadOS 13 does not support Slide view or Sides view completely for PWAs as in the first betas

🔥Miscellaneous #

  • New Safari per Website Settings menu
  • Download Manager now available on Safari
  • Safari will suggest opened tabs instead of opening a new one for the same site; no PWA suggestion though
  • New performance enhancements to render faster websites on iOS, iPadOS, and watchOS (no exact details on what)
  • Scrollbars are now draggable on iOS and iPadOS
  • iOS Simulator: SE/iPod Touch and iPad Mini factors are not available by default — but you can add a profile manually
  • WebDriver is now available for automation on Safari for iOS and iPadOS

Compare the previous list from what’s offered by Apple as the official changelog.

Progressive Web Apps #

If you’ve followed PWAs on iOS, you probably know that the relationship between Apple and it, it’s weird. From creating the platform a decade ago with the name Home Screen Web Apps to ignore them completely, to implement the standards at least partially to finally changing their lifecycle completely and silently in the last versions.

My first article published on PWAs for iOS is actually close to three-quarters of a million reads, which defines how interesting is this to the web community despite Apple’s reactions.

Apple with PWAs: friends or enemies? #

Despite actually supporting PWAs in a decent way compared to other browsers, Apple is the only company not embracing the PWA term. While we know it’s not a clear concept, and it’s more like a design pattern to create web apps with modern APIs, Apple has said in the past few months that they don’t want the name. And they reinforced the idea that if you create a web app it should be to use within Safari, don’t go and publish it in the AppStore because it will likely be rejected.

4 years ago I was asking about PWA term acceptance. Today, only Apple rejects the usage of the term.

A few weeks ago, Apple published an official document asking developers to stop submitting PWAs to the AppStore, but they called them “HTML5 Apps” a term I have not seen in a while.

“Apps that provide core features and functionality dynamically with web technology like HTML5 are best delivered to everyone in Safari, rather than through the curated App Store” — Apple on September, 6th 2019

That doesn’t mean you can’t publish apps with web content, but the core features should not be downloaded from a web server, such as typical PWAs are doing with a local cache managed by the Service Worker. So if you convert your PWA into a hybrid app (with all JS files within the store package), the app might be accepted in the app store, but it’s losing one of the key aspects of a Progressive Web App in that case.

Also on Twitter some Apple employees — with their own views, but similar to what Apple with omissions or explicit mentions thinks- were criticizing the PWA term and/or idea. You can see some of those in this interesting thread after a tweet I’ve published from my latest JSConf Talk.

At the same time, Apple started to create PWAs fully or partially, such as the new Feedback Assistant or the new Apple Music web app, but they don’t implement the Web App Manifest spec fully to let us, for example, trigger the installation dialog from the user interface.

New App Installation screens #

Safari redesigned the Share sheet completely, changing how PWAs are installed from the browser. When a user clicks on the Share icon in the toolbar, now Safari renders the icon from the apple-touch-icon meta tag and the title of the current page in the share sheet header.

“Add to the HomeScreen” is below the fold, but the new sheet invites the user to scroll so it’s better than before; if the user edits the Share sheet, she can make Add to HomeScreen a favorite option and move it to the top as well.

New Share Sheet in Safari 13

The new Share sheet taking the icon, page’s title (left image), offering Add to Home Screen after scroll (middle image) unless to add it as a favorite (right image). BTW, here you can see Dark mode in action.

If you were providing screenshots to your users to help the user, it’s time to update those screenshots to the new user interface.

Unfortunately, Safari is still not supporting beforeinstallprompt to offer an install/add to home button within our user interface.

On iPadOS, there is no need for scroll and Add to HomeScreen appears on the first click on the Share sheet.

On iPadOS Add to Home Screen is visible without any scroll after using the Share button

On iPadOS Add to Home Screen is visible without any scroll after using the Share button

Also, Safari now supports hiding the URL bar which leads to a similar experience as a standalone installed PWA. The only problem is that the option is available on a per-case usage and Safari doesn’t remember the settings, so the user has to “hide toolbars” every time she wants to.

Hide Toolbar

TowerGame.app from normal Safari with the Hide Toolbar about to be enabled (left image), same app with the hidden toolbar (middle image), and the same app installed as a PWA (right image)

App Lifecycle 3.0 #

Finally, we’ve got a PWA Lifecycle that actually makes sense. Well, most of it :)

From a user perspective, from iOS and iPadOS 13, PWAs now look and act like native apps. There are two main important changes from 12.x:

  • When you get out of a PWA, not the OS takes a screenshot an use it in the app switcher view, instead of the white screen or the static launch image if you define it. That matches the native app behavior, which is a great deal.
  • If you want to restart or reload a PWA, now you can swipe up the app or close it from the app switcher and when you open it again, it will start from scratch as most users will expect.
Same PWA set on iOS 12.2 (left) and on iOS 13 (right); the experience shows screenshots of the last usage as with native apps

Same PWA set on iOS 12.2 (left) and on iOS 13 (right); the experience shows screenshots of the last usage as with native apps

Progressive Web Apps typically were not executing any code in the background after a few seconds from being out of the screen.

That’s not the case anymore. Yes: PWAs run in the background 😱

But wait a minute: I think this is a non-desired side effect. I don’t think it was intended and this might change in the future.

As far as I can tell from my testings when you open your first PWA, the Web.app process starts and it loads your content. When you get out of the PWA, the Web.app process takes a screenshot for the app switcher and then moves into a state similar to a recent background tab in Safari: it still executes some code, including timers (with less frequency) and it stops every rendering code including requestAnimationFrame. But the Web.app process is still there up and running in the iOS background. In the meantime, your PWA is not inspectable, so it appears to be off, but it turns out, it’s not off.

I tested this sending console.log messages in the background in a timer: I stop receiving messages when the app is the background; but if I restore the app, I receive in the console all the messages that were buffered somewhere while in the background.

How much time is it executing in the background? Impossible to know, but my impression is that while the Web.app process is there, it will be there. If there is memory pressure because of other native apps, the Web.app process might be suspended and with that, also your JavaScript code.

If the Web.app process restarts, it seems it’s not saving the state as in 12.2 anymore; all the PWAs in the background seem to start from scratch. If the user manually terminates one PWA, it seems it’s only terminating that one and it’s not affecting other PWAs still in the background.

Another side effect of background PWAs is that when you are inspecting one PWA, all the background available PWAs are also inspectable at that time, where you can see all of them are capable of executing code while hidden.

We’ll see with time if this affects battery life. Unfortunately, I’m not sure how Screen Time and the Battery screens measure “Web.app” time if it’s executing code in the background. My tests on that are inconclusive so far.

Several webapps running in the background

Here we can see several “web” (aka PWAs in standalone mode) inspectable at the same time from one iOS 13 simulator, only one is in the foreground. We have duplicates because one set is for the Service Worker context of each app.

So this is the current versioning system for PWAs:

First version: from iPhone OS 2.0 to iOS 11.1 without Web App Manifest support and from iOS 11.2 to iOS 12.1 with partial Web App Manifest support. The web app was terminated every time you were out; in the app switcher, only a static launcher image was used (mostly a white image because of the lack of it.

Second version: from iOS 12.2 to iOS 12.3: Now the app state was saved and restored when you were getting out of a PWA, but there was no way to restart the app, even when closing or terminating the app from the app switcher. I reported this odd behavior in this post. In the switcher, static launcher image or white screen was still the way to render PWAs.

Third version: From iOS 13: a screenshot of the PWA is used in the app switcher, and now terminating the app from the switcher terminates its saved state as well. Every PWA can still execute code in the background for some time while there is no memory pressure.

In-App Browser #

The In-App browser when you link to external scopes (such as different domain) seems to be the same as in 12.2–12.3. The only thing that seems to be working now is when you make a link to some other native apps (using Custom URIs or Universal Links) the right app seems to appear instead of an error within the In-App browser for some protocols.

Unfortunately, there is a bug, where the back button to your PWA shows “◀Untitled” and not the actual PWA’s name or short name (see image below)

It’s still not possible to open a link in Safari from a standalone PWA.

Same PWA on iOS 12.2 (left) and on iOS 13.3 (right) in dark mode after clicking on an Apple Maps link. Look at the back button in the URL bar

Same PWA on iOS 12.2 (left) and on iOS 13.3 (right) in dark mode after clicking on an Apple Maps link. Look at the back button in the URL bar

Also, some bugs such as the “Done” button not appearing all the times, seem to be solved now. The In-App browser seems to be based on Safari View Controller to it now includes the drop-down website settings menu. Unfortunately, there is no “Open in Safari” option there; it will be a good place for it!

Apple Pay now available on PWAs #

Simple as that, the Apple Pay JS API is now working for standalone PWA
Apple Pay working within a standalone PWA
Apple Pay working within a standalone PWA

PWAs Inspectable again #

Progressive Web Apps in standalone mode are now remotely inspectable in Safari, which is good news! Separating the contexts from a Service Worker and the actual PWA client is still a challenge, but it’s good to have inspection back.

I’ve found a weird bug on iOS 13, but then I realized it might have been there for a while. If you search for a PWA in the Search screen, they appear but if you click on them they open in Safari and not within its standalone window.

An installed PWA appears in Search but when you click on it, the URL opens in Safari and not in standalone mode

An installed PWA appears in Search but when you click on it, the URL opens in Safari and not in standalone mode

Web Push #

There is still no news on Web Push notification support for iOS. However, one tweet may be saying that it’s finally a possibility at the WebKit team.

Cache Storage sharing #

Cache Storage is not shared between Safari and standalone PWAs now, compared to what happened in previous versions. Therefore, two different service worker registrations happen in Safari and after icon installation, as well as downloading resources twice. If you have two PWA installations from the same origin or scope (same or different PWA), service worker registration and app cache storage will be shared among those.

Web Design #

There are many web resources to understand some of these changes, and how to apply them in your designs, so I’ll just list the changes and comments on things you might not find somewhere else.

Dark mode #

The dark mode is now available on iOS and iPadOS and our websites can (and should at one point) optimize content to that users’ preference. From a website point of view, Safari on iOS follows the same specs currently on Safari on macOS that were properly documented by WebKit previously this year.

What it’s important to mention is that Dark mode availability happens on: Safari and standalone PWAs by default but not in Safari View Controller or WebViews (such as Facebook Mobile Browser or Chrome on iOS) unless those apps are compiled against iOS 13 SDK that will happen with time.

There is no way to adapt the app’s icon or metadata while on dark mode, but the same limitation happens on Android and desktop OSs as well.

iPhone 11 viewports and pixel densities #

The new series of iPhones 11 doesn’t change the landscape of possible available combinations of viewport sizes and pixel densities:

320w–2xDPR: SE, iPod Touch
375w–2xDPR: 6, 6S, 7, 8
375w–3xDPR: X, XS, 11 Pro 🆕
414w–2xDPR: XR, 11 🆕
414w–3xDPR: 6+, 6S+, 7+, 8+, XS Max, 11 Pro Max 🆕

Other changes #

  • MathML coming (it’s an experiment today)
  • CSS conic gradients
  • Adaptive font sizes with website settings
  • One-finger accelerated scrolling now supported on every scrollable DOM element (_iframe_s and elements with overflow: scroll) which makes the -webkit-overflow-scrolling style to promote momentum scrolling officially deprecated.
  • iPads: by default now pages will be scaled to prevent horizontal scrolling, no matter your viewport declaration

APIs availability #

For PWAs and web sites, there are changes in terms of API availability

Good-bye WebSQL #

WebSQL was never standardized but it was the only serious storage available from iPhone OS 2.0 for web apps. A few years ago, some browsers decided to mark it as deprecated and it was time for Safari to remove it by default. So from iOS and iPadOS 13, WebSQL is disabled.

The API is still there but if you try to create a Database it generates the exception UnknownError: Web SQL is deprecated.

If you still need it, the user can re-enable it by deselecting “Remove WebSQL” from Advanced Safari settings.

Motion Sensors #

The simple API available since iOS 4.2 to read the accelerometer and later with gyroscope and magnetometer support from JavaScript was changed in the past year after discovering that several websites and iframes with ads were using that to fingerprint users based on how they use the phone. It was first removed; then removed by default with a global on/off (off by default) in Safari’s settings, and now it’s back with a change that makes every web app using the feature incompatible since iOS 13.

Apple announced the change but unfortunately, it didn’t update the documentation or publish anything about it more than on some web spec discussion forums.

The new permission dialog available on iOS13

We need to request permission to sensors before trying to read their values, and a dialog similar to other permissions will appear for the user to grant or deny. This change is affecting only Safari; WebViews and PWAs are still using the old way — sensors are available without requests, but this change will arrive there as well.

You request permission within the DeviceOrientationEvent or DeviceMotionEvent objects with the requestPermission function returning a promise. You can only do that after a user gesture. If granted, you can then use the sensors as before.

Visual Viewport API #

The Visual Viewport API lets us recognize when there is a change in the available viewport that doesn’t involve a resize from a window or device point of view (such as a landscape). Example of this behavior is when the user resizes the page with the pinch gesture.

To detect visual viewport changes with event “resize” over the visualViewport global object. Over that object we can also query the current scale and other properties.

LinkPresentation Framework #

LinkPresentation framework is available for native apps that want to show snippets of web content within its app. If you own a website, to serve content for that framework you just need to implement the Open Graph protocol.

Sign In with Apple now available #

Thanks to the Sign In With Apple JS library you can implement a native Apple sign in process with Apple’s account similar to Facebook or Google, but with a more automatic process for iOS and iPadOS users.

Sign In with Apple

Talking too much about this framework is out of the scope of this article, but you can check more in the official docs.

3D Touch #

3D touch is officially out of all the new iPhones, leaving screen pressure control for the future only on iPad with Apple pencil. Its replacement, the haptic touch pattern (short vibration after long press) is not available on WebKit − Vibration API is not implemented.

Other changes #

  • Pointer Events are now available, closing a fight that has been in the web field for a decade. Pointer events are more useful on iPadOS where we can tell the difference between a touch, an Apple pencil tap or stroke, and a mouse pointer click.
  • Different image sizes option now available when uploading images with <input type=file>, that let the user select the original size or one of the available sizes.
  • New Experiments Available (off by default): Ad Click Attribution, MathML Core, Automatic HTTPS Upgrade, Link prefetch, Link preload responsive images, @page CSS, Refer Policy Attribute, ResizeObserver,
  • New Experiments Available (on by default): Fetch API Request Keep-Alive, Quirk to prevent delayed initial paint (whatever that means), Media Capabilities Extension, Pointer Events, Synthetic Editing Commands, Block top-level redirects (to avoid iframes redirecting top page), Visual Viewport API, Disable WebSQL
  • Keep Alive is now available for fetch requests, to keep alive some requests even when the JavaScript context is closed
  • Apple Pay on WebViews and PWAs is now available.

iPadOS #

It’s the time for iPads to get their own OS separated from iPhones, and version 13 is the first iPadOS. Safari also did a big change here, offering the macOS desktop class browser in iPads by default.

Safari on iPadOS now works in two content modes: desktop, or mobile. It’s not just a change of User-Agent, it also makes changes on layout viewport behavior, touch and mouse emulation, and other “tricks”.

The content mode is automatically defined by Safari on load based on available screen size, with the current modes set by default as:
− mobile for iPad Minis
− desktop for iPad, iPad Air, and iPad Pro
− mobile on all iPads in Side View or SplitView (1/3 screen)

User can change the default mode from the new Website settings menu in the URL bar.

Desktop class experience #

On the new desktop content mode the User-Agent is the same from Safari on macOS, the viewport with a viewport declaration of width=device-width will be the real size and not the typical iPad 768px on portrait; also the viewport declaration will be ignored if the site doesn’t fit horizontally (font sizes will keep legibility); if your website expects horizontal scrolling, add shrink-to-fit=no to the layout viewport definition, or your website will shrink until it fits completely without horizontal scrolling.

Same browser, same iPad, different engine modes (desktop at the left, mobile at the right)

If Safari thinks your desktop website relies on hover (for example on a drop-down menu), it will enter an especial mode for those elements:
− The first tap will trigger hover/mouseover
− A second tap will click

BTW, a desktop-class experience means a modern experience with no plugins. Apart from all the iOS 13 news, Safari on iPadOS will take advantage of Media Source Extensions (desktop mode only) for live video and it’s now possible to open two Safari windows side-by-side (or a floating Slide View) by dragging the URL bar into the corner.

Two Safaris running on the same iPad

SafariViewController will also autodetect content mode, and for WKWebView there is a new API for the developer to define auto/mobile/desktop and to query about current mode enabled, so we might not get the same behavior on Facebook Mobile Browser or Chrome, Firefox or Edge on iPadOS until they update the app.

Detecting iPads #

The idea is to stop designing websites or web apps for iPad and just make desktop content fully compatible with these devices. Apple doesn’t want us to use User-Agent to do special things for iPad and to use just feature detection. Sounds good, but…there are many situations where you want to know if it’s an iPad or a macOS, such as:
− Gaming (don’t rely on a present keyboard on iPad)
− AppStore links
− PWA support and instructions -not available on macOS yet-
− UI design decision (such as top-bar vs bottom-bar)
− Multitasking

WARNING: The new desktop mode means you will start seeing changes in your statistics: more mac users and fewer iPad users, but it won’t be the real scenario.

Detecting iPads in desktop mode can happen only client-side, and the best way I found is to ask for the following condition:

const isIPad = 'standalone' in navigator;

PWAs in iPadOS #

During the betas, two PWAs side by side was possible; not on the final version

PWAs in standalone mode, of course, got zero attention on docs and videos from WWDC, but in my testings, I can confirm that mobile and desktop content modes are also working on PWAs but only on the first load. For example, if you open a PWA in fullscreen on non-mini iPads, it enters the desktop content mode. If you then move it to the side with SplitView it doesn’t reload with mobile mode as with Safari.

During the first betas of iPadOS, I could confirm that side view and split view were working with PWAs, to have two PWAs side by side (or two installed icons of the same one); unfortunately, this behavior didn’t get to the final version and PWAs won’t work as expected in those multitasking modes. There is only one case that is still working. If you open first a fullscreen PWA, you can open a non-PWA native app in the side after and then both will work, but the PWA side won’t have the typical behavior when dragging from the top bar.

Other changes #

iOS 13 also includes some new changes that will affect web engineers, such as:

  • New Safari per Website Settings menu that let the user change properties on each domain.
  • Download Manager now available on Safari, so we can now serve any kind of file to iPhones and iPads, not just compatible content.
  • If you are typing a URL of a tab that is already opened, Safari will suggest to just focus on that tab instead of opening a new one; unfortunately, this behavior doesn’t suggest installed PWAs instead.
  • New performance enhancements are in the web engine to render faster websites on iOS, iPadOS, and watchOS (no exact details on what, but the docs specify it)
Performance enhancements according to Safari Release Notes
  • Scrollbars are now draggable on iOS and iPadOS
  • iOS Simulator: SE/iPod Touch and iPad Mini factors are not available by default — but you can add a profile manually
  • WebDriver is now available for automation on Safari for iOS and iPadOS

Did you find anything else? Let me know in the comments. Remember I will be updating this article with new findings and sending alerts on Twitter.

Half typewriter, half computer

© Maximiliano Firtman (@firt)

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

Contact me: hi@firt.dev Personal Website Buy Me A Coffee