On 30th of March long awaited iOS 11.3 update was released, with support for basic PWA features on iPhones and iPads – service workers and app manifest files. As it is great to finally have a support for those, user experience of Progressive Web Applications on iOS is still not perfect.
That means that many of released PWAs are still having serious issues on Apple devices when providing nearly native experience on Android at the same time. In the frontend community comments of disappointment were already raised, and the list of issues and bugs is long. Don't lose your hope, though! Below you will find a few tips on how to fix these issues and make your PWA as close to a regular mobile app as you can.
In the latest iOS update, Apple added support for service workers and app manifest. Now you can leverage caching with service workers and make your PWA work without internet connection. Let's remember – this is a basic requirement within the PWA definition. And unfortunately there are a few drawbacks in Apple's implementation.
Service workers support is very limited compared to Android. You can only persist app data and cache its files (no background tasks). There is also a 50MB and “few weeks” limit for storage.
iOS 11.3 also introduced support for the manifest file. But our tests showed that it is far from perfect. Icons are not working perfectly (or at all) and there’s no support for launch screen - you’ll get only a blank white screen when the app is loading. The app is reloaded each time it goes from the background, and there's no support for push notifications and many others functionalities, which are essential for a mobile app. To sum up - overall UX is quite bad.
Thankfully, there's a lot you can do to improve your app's look and provide better UX. With a few simple tricks, you can build an app that in a lot of cases will be indistinguishable from a native one.
I believe that PWAs are the future of inclusive, performative and intuitive web so that’s why I would like to share some tips to overcome iOS limitations in terms of PWA.
We've encountered that iOS does not use icons from manifest and that makes a shortcut to your app on the home screen look really bad. There is a simple solution to overcome this issue - just add apple-touch-icon meta tag with proper image. But avoid icons with transparency - those will not work.
And now your app will look perfect from the beginning!
Launch screen is displayed before the app is fully loaded and ready to use. Unfortunately iOS doesn't support launch screen generated from manifest as it is on Android - instead, it shows white, blank screen That's definitely not the experience we would like to serve to our users.
Thankfully we've found the solution which is described in apple developer's page. Apple supports custom meta tags to specify pre-generated splash screen - apple-touch-startup-image. So you just have to generate splash images in proper sizes which you can find listed below:
When you have your stunning launch screens ready, the only thing left to do is to link them in the head section like this:
Now you can see that ugly white screen on launch is gone:
Thanks to that tip our PWA is looking much better, isn't it?
On Android, there is a native popup which encourages the user to add an app to a home screen and informs him that our page is a PWA. Unfortunately, on iPhone there's no such thing, so our visitor is not even aware of our app capabilities. Moreover on iOS it requires as much as 3 taps to add the app to the home screen.
But don't worry, we have a fix for that! We can add a custom popup which will indicate that our app can be added to home screen.
You are free to design that popup as you wish, our example is shown below. The hard part is to display it only in safari and not in standalone mode (when the app is already added to home screen). You can check if your app is in standalone mode with window.navigator.standalone.
Take a look at this snippet:
After creating proper popup component and pasting detection code in proper lifecycle method it will look like this:
Just bear in mind that on iPad the share button is located at the top of a screen, next to the address bar, so you should change out popup's location accordingly.
Since iOS restarts your app on every launch/going to background you should take care of persisting its state yourself. If you use react and redux there are some great packages to help - redux-persist and react-router-redux. For vue you could use similar vuex-persist and vuex-router-sync. Of course, you can create your own solution which would be the best fit for your case.
In react by default react-router-redux will redirect on mount to the route specified in URL. As it might be ok for regular use, we would like to prefer route which was persisted in our store. This is an example how to achieve that:
To make sure your app will be usable in standalone mode you have to check if you have implemented your navigation correctly. On Apple devices there's no back button, so you have to make sure that user is able to go back from any screen using navigation built-in to your app.
You can do that by displaying back button or by adding additional menubar if on iOS.
To provide the true native experience you should be prepared for weak or no connection at all. In some simple cases, persisting store data will be enough, but this is where we can leverage our brand new (on iOS) Service Workers API - we are able to cache network requests (eg. API calls) there.
To take advantage of caching with service worker, you could use example code provided by Google. Make sure that you've read the linked article to be aware of pros and cons of that template.
After setting proper paths to assets which you'd like to cache and registering service worker, you should be good to go (offline). It's also good to indicate that the app is offline - you can add online/offline events listeners to display a proper notification.
That's how the final result looks in our example app:
These tips will help you to provide nearly native UX for your PWA on iOS. But of course, there are still some issues that could be solved. We still don't have support for:
Also, you should keep in mind that caches and any locally-stored data is not shared between Safari, WebView, and Web.App. So after adding your app to home screen user will have to e.g. log in again, which could cause bad UX in some cases.
Have an idea? share with us!