Author: Mikołaj Smoleński
Support for iOS devices
The PWA concept in its current shape was propagated by Google, currently staying its biggest supporter, providing guidance in spec creation and overall promotion. Worth to note, though, is that the original technology of having webapps shortcuts was first presented by the very Steve Jobs back in 2007 (and it was called WebClip at the time). It did not gain much traction then and the tech got pretty much abandoned for over 10 years. Apple silently got back to play in March 2018 with iOS 11.3, adding support for the PWA basics - Web Manifest and Service Worker. You can now leverage caching with service workers and make your PWA work without an internet connection on iOS devices, too! It's not all roses, though.
When it comes to Worker, you can only persist app data and cache files, but no background tasks. There is also a 50MB and “few weeks” limit for storage. Manifest's icons are not working perfectly (or at all) and there’s no support for launch screens - you’ll get only a blank white screen when the app is loading. The app is reloaded each time it is brought back from the background, and there's no support for push notifications and many other functionalities which are essential for a mobile app - no support for Bluetooth Low Enegy devices, WebShare, Speech Recognition and most notably - the Web App Banner. But we will make it through - together - and try to do what we can to provide for the PWA experience. We will achieve it by adding iOS specific tags in our template.
Lack of support for some of the manifest's functionalities means we need to emulate them somehow - usually, by
adding special tags to our ./index.html
.
Shortcut Icon
Firstly, like with Windows or Android platforms, there is a baseline set of icons to cover the iOS. These are all
square, with dimensions of 120x120
, 152x152
, 167x167
and
180x180
pixels. The best option is to prepare your set of icons for different platforms and different
sizes all together, and online generators usually cover you in that. Moreover, while installing your app, iOS does
not use the icons from the manifest file - but we can get around that, by adding special tags:
<link rel="apple-touch-icon" href="static/icons/Icon-120.webp">
<link rel="apple-touch-icon" sizes="152x152" href="static/icons/Icon-152.webp">
<link rel="apple-touch-icon" sizes="167x167" href="static/icons/Icon-167.webp">
<link rel="apple-touch-icon" sizes="180x180" href="static/icons/Icon-180.webp">
Adding a Launch Icon Title
To define an app title - similar to the name and short name properties defined in the manifest.json
file, let's add an apple-mobile-web-app-title
element:
<meta name="apple-mobile-web-app-title" content="Agenda App">
Now, when the user click 'add to the homescreen" button, he will see popup as shown below:

Standalone mode
To mimic the standalone look of the native application we have to tell the browser, that we want to launch our project as a web app. We also want to hide a status bar, by default black, that is visible across the top of the screen. We can achieve this by adding these two lines:
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
Splash Screen
The last thing we have to take care of is a launch screen - right now, iOS doesn't generate splash screens from
the manifest.json - as it works in Android. Instead, we have to provide an image for each Apple device screen;
what's more, we also need to inline CSS breakpoints and the orientation
attribute into our html - not
only for each said device, but for both its landscape
and portrait
orientations.
Phew, that's around 20 tags depending on the field of device coverage you're planning. I advise to use an online
tool for splash images creation, as it can be really tiresome manually. Here, have these icons
here! Unpack in the /static
directory.
In the end our ./index.html
file will look like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="apple-mobile-web-app-title" content="Agenda App">
<title>mdbvue</title>
<script src="https://maps.googleapis.com/maps/api/js" async></script>
<link rel="manifest" href="/static/manifest.json" />
<!-- Bootstrap core CSS -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.2.1/css/bootstrap.min.css"
rel="stylesheet">
<!-- Material Design Bootstrap -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.7.1/css/mdb.min.css" rel="stylesheet">
<link rel="apple-touch-icon" href="static/icons/120.webp">
<link rel="apple-touch-icon" sizes="152x152" href="static/icons/Icon-152.webp">
<link rel="apple-touch-icon" sizes="167x167" href="static/icons/Icon-167.webp">
<link rel="apple-touch-icon" sizes="180x180" href="static/icons/Icon-180.webp">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<!-- iPhone X / XS -->
<link rel="apple-touch-startup-image"
media="screen and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
href="/static/splashscreens/Splash-2436x1125.webp" />
<link rel="apple-touch-startup-image"
media="screen and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
href="/static/splashscreens/Splash-1125x2436.webp" />
<!-- iPhone XR -->
<link rel="apple-touch-startup-image"
media="screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
href="/static/splashscreens/Splash-1792x828.webp" />
<link rel="apple-touch-startup-image"
media="screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
href="/static/splashscreens/Splash-828x1792.webp" />
<!-- iPhone 6s / 7 / 8 -->
<link rel="apple-touch-startup-image"
media="screen and (device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
href="/static/splashscreens/Splash-1334x750.webp" />
<link rel="apple-touch-startup-image"
media="screen and (device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
href="/static/splashscreens/Splash-750x1334.webp" />
<!-- iPhone XS Max -->
<link rel="apple-touch-startup-image"
media="screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
href="/static/splashscreens/Splash-1242x2688.webp" />
<link rel="apple-touch-startup-image"
media="screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
href="/static/splashscreens/Splash-2688x1242.webp" />
<!-- iPhone 6s Plus / 7 Plus / 8 Plus -->
<link rel="apple-touch-startup-image"
media="screen and (device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
href="/static/splashscreens/Splash-2208x1242.webp" />
<link rel="apple-touch-startup-image"
media="screen and (device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
href="/static/splashscreens/Splash-1242x2208.webp" />
<!-- 12.9" iPad Pro -->
<link rel="apple-touch-startup-image"
media="screen and (device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
href="/static/splashscreens/Splash-2048x2732.webp" />
<link rel="apple-touch-startup-image"
media="screen and (device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
href="/static/splashscreens/Splash-2732x2048.webp" />
<!-- 10.5" iPad Pro -->
<link rel="apple-touch-startup-image"
media="screen and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
href="/static/splashscreens/Splash-2224x1668.webp" />
<link rel="apple-touch-startup-image"
media="screen and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
href="/static/splashscreens/Splash-1668x2224.webp" />
<!-- 9.7" iPad / 7.9" iPad mini 4 -->
<link rel="apple-touch-startup-image"
media="screen and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
href="/static/splashscreens/Splash-2048x1536.webp" />
<link rel="apple-touch-startup-image"
media="screen and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
href="/static/splashscreens/Splash-1536x2048.webp" />
</head>
<body>
<div id="app">
<div class="container">
<div class="row">
<div class="col-9">
<h2 class="text-uppercase my-3">Today:</h2>
<div class="d-flex justify-content-center">
<div class="spinner-border" style="width: 3rem; height: 3rem;" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
</div>
<div class="col-3">
<h3 class="text-uppercase my-3">Schedule</h3>
<h6 class="my-3">
It's going to be busy that today. You have
<b> events</b> today.
</h6>
<h1 class="my-3">
<div class="row">
<div class="text-center col-3" i class="far fa-sun" i></div>
<div class="col-9"> Sunny</div>
</div>
<div class="row">
<div class="text-center col-3" i class="fas fa-thermometer-three-quarters" i></div>
<div class="col-9"> 23°C</div>
</div>
</h1>
<p>
Don't forget your sunglasses. Today will dry and sunny, becoming
warm in the afternoon with temperatures of between 20 and 25
degrees.
</p>
</div>
</div>
</div>
</div>
<!-- built files will be auto injected -->
</body>
</html>
Now, our app behaves in a similar way to the app on Android devices!

Something doesn't work for you? Check the code for this lesson on our repository
Previous lesson Download Live preview Next lesson
Spread the word: