PWA support on iOS 11.3 #45

Open
nolanlawson opened this Issue Apr 9, 2018 · 25 comments

Comments

Projects
None yet
10 participants
@nolanlawson
Owner

nolanlawson commented Apr 9, 2018

Reported here:

PWA functionality does not play nicely yet on iOS11.3 because when adding an instance, Safari opens & gets the login cookie instead of the sandboxed PWA webview, so it cannot login.

@nolanlawson nolanlawson added the bug label Apr 9, 2018

@nolanlawson

This comment has been minimized.

Show comment
Hide comment
@nolanlawson

nolanlawson Apr 11, 2018

Owner

BTW my hunch is that this breaks for more than just Pinafore: any site that does an OAuth login should be hit by this. So I kind of suspect the WebKit team may move fast to fix this.

FWIW, PWAs on Edge on Windows 10 do not have this issue, nor do Firefox/Chrome PWAs on Android AFAICT.

Owner

nolanlawson commented Apr 11, 2018

BTW my hunch is that this breaks for more than just Pinafore: any site that does an OAuth login should be hit by this. So I kind of suspect the WebKit team may move fast to fix this.

FWIW, PWAs on Edge on Windows 10 do not have this issue, nor do Firefox/Chrome PWAs on Android AFAICT.

@SpankyWorks

This comment has been minimized.

Show comment
Hide comment
@SpankyWorks

SpankyWorks Apr 12, 2018

Contributor

I read a little bit about PWAs on iOS today and remembered seeing this issue. iOS apparently clears its data when the PWA goes into the background. Could be complicating the default OAuth process in the masto API?

For reference, here’s one of the articles I read: https://www.netguru.co/codestories/few-tips-that-will-make-your-pwa-on-ios-feel-like-native

Contributor

SpankyWorks commented Apr 12, 2018

I read a little bit about PWAs on iOS today and remembered seeing this issue. iOS apparently clears its data when the PWA goes into the background. Could be complicating the default OAuth process in the masto API?

For reference, here’s one of the articles I read: https://www.netguru.co/codestories/few-tips-that-will-make-your-pwa-on-ios-feel-like-native

@technopagan

This comment has been minimized.

Show comment
Hide comment
@technopagan

technopagan Apr 12, 2018

I'm quoting Maximiliano Firtman (@firtman) when asking him how to address the current limitations of PWAs on iOS 11.3 (see https://medium.com/@firt/progressive-web-apps-on-ios-are-here-d00430dee3a7):

I think storing the data in Cache Storage is the best solution to share between sessions and safari/webapp. Just save a JSON as a Response and get it back from cache

This might be a viable workaround to keep users logged in, but it does not address the issue of not even being able to complete the OAuth session.

I'm quoting Maximiliano Firtman (@firtman) when asking him how to address the current limitations of PWAs on iOS 11.3 (see https://medium.com/@firt/progressive-web-apps-on-ios-are-here-d00430dee3a7):

I think storing the data in Cache Storage is the best solution to share between sessions and safari/webapp. Just save a JSON as a Response and get it back from cache

This might be a viable workaround to keep users logged in, but it does not address the issue of not even being able to complete the OAuth session.

@nolanlawson

This comment has been minimized.

Show comment
Hide comment
@nolanlawson

nolanlawson Apr 12, 2018

Owner

Sharing data between the main Safari app and the PWA is not a big concern to me as long as users can log back in. Edge on Windows has the same limitations for its PWAs, but at least the OAuth flow works.

If the OAuth flow doesn't work and data isn't shared between the main browser and the PWA app, though, then I'm not sure I see any workaround for this. 😕

Owner

nolanlawson commented Apr 12, 2018

Sharing data between the main Safari app and the PWA is not a big concern to me as long as users can log back in. Edge on Windows has the same limitations for its PWAs, but at least the OAuth flow works.

If the OAuth flow doesn't work and data isn't shared between the main browser and the PWA app, though, then I'm not sure I see any workaround for this. 😕

@firtman

This comment has been minimized.

Show comment
Hide comment
@firtman

firtman Apr 12, 2018

To be honest, I didn't get exactly what was the issue. If it was a) passing data from Safari to the installed PWA (Web.app process), b) keeping data between PWA sessions or c) get back again from Safari after an OAuth login and keep the session details somehow in the PWA.

Right now, the only storage shared properly between Safari and installed PWA is "Cache Storage" (from the Service Worker spec). Therefore, as a hack, the OAuth final endpoint (rendered in Safari) can put in the cache a "fake" resource, such as in "./_private/data/session.json" creating a Response object with data. You then read that object from the same cache within the installed PWA; if the URL is in the cache you have the data and you can "import it" into the PWA context.

firtman commented Apr 12, 2018

To be honest, I didn't get exactly what was the issue. If it was a) passing data from Safari to the installed PWA (Web.app process), b) keeping data between PWA sessions or c) get back again from Safari after an OAuth login and keep the session details somehow in the PWA.

Right now, the only storage shared properly between Safari and installed PWA is "Cache Storage" (from the Service Worker spec). Therefore, as a hack, the OAuth final endpoint (rendered in Safari) can put in the cache a "fake" resource, such as in "./_private/data/session.json" creating a Response object with data. You then read that object from the same cache within the installed PWA; if the URL is in the cache you have the data and you can "import it" into the PWA context.

@nolanlawson

This comment has been minimized.

Show comment
Hide comment
@nolanlawson

nolanlawson Apr 12, 2018

Owner

OK thanks, that actually does sound like it might work.

BTW does anyone know if there is a WebKit bug or Radar for this issue? I can't seem to find it.

Owner

nolanlawson commented Apr 12, 2018

OK thanks, that actually does sound like it might work.

BTW does anyone know if there is a WebKit bug or Radar for this issue? I can't seem to find it.

@firtman

This comment has been minimized.

Show comment
Hide comment
@firtman

firtman Apr 12, 2018

I'm not sure if this is a bug or a feature. Web.Apps and Safari had different storage contexts for years. Some bugs: https://bugs.webkit.org/show_bug.cgi?id=181849 https://bugs.webkit.org/show_bug.cgi?id=181850 Bugs links shared on Twitter https://twitter.com/tomayac/status/984290732499447808

firtman commented Apr 12, 2018

I'm not sure if this is a bug or a feature. Web.Apps and Safari had different storage contexts for years. Some bugs: https://bugs.webkit.org/show_bug.cgi?id=181849 https://bugs.webkit.org/show_bug.cgi?id=181850 Bugs links shared on Twitter https://twitter.com/tomayac/status/984290732499447808

@tomayac

This comment has been minimized.

Show comment
Hide comment
@tomayac

tomayac Apr 14, 2018

FYI, the login flow for Pinafore seems broken in general on iOS 11.4 Beta 1, not just limited to added to home screen. It shows the authorize/deny buttons, then stays there if I try to press either. Seems like the redirect flow isn’t working.

tomayac commented Apr 14, 2018

FYI, the login flow for Pinafore seems broken in general on iOS 11.4 Beta 1, not just limited to added to home screen. It shows the authorize/deny buttons, then stays there if I try to press either. Seems like the redirect flow isn’t working.

@nolanlawson

This comment has been minimized.

Show comment
Hide comment
@nolanlawson

nolanlawson Apr 14, 2018

Owner

I just tested in iOS 11.2.6 both in Safari and as a homescreen app, and the OAuth flow works. So this seems to be a new issue in 11.3. 😕

Owner

nolanlawson commented Apr 14, 2018

I just tested in iOS 11.2.6 both in Safari and as a homescreen app, and the OAuth flow works. So this seems to be a new issue in 11.3. 😕

@tomayac

This comment has been minimized.

Show comment
Hide comment
@tomayac

tomayac Apr 14, 2018

I'm on 11.4 Beta 1 actually.

tomayac commented Apr 14, 2018

I'm on 11.4 Beta 1 actually.

@MarcoZehe

This comment has been minimized.

Show comment
Hide comment
@MarcoZehe

MarcoZehe Apr 15, 2018

@technopagan

This comment has been minimized.

Show comment
Hide comment
@technopagan

technopagan Apr 15, 2018

I can confirm the OAuth workflow working correctly on iOS11.3, stock Safari browser, as long as I don’t use a Webview as is used when coming from Add-To-Homescreen.

I’ll try another Webview mode (called “Sidefari”) next to see if this breaks the OAuth flow, too.

A comment from one of trivago’s PWA developers: the PWA OAuth login issue is probably unfixable on iOS11.3 and it needs fixing by the Safari devs. His suggestion is to provide an alternative login mechanism if possible.

I can confirm the OAuth workflow working correctly on iOS11.3, stock Safari browser, as long as I don’t use a Webview as is used when coming from Add-To-Homescreen.

I’ll try another Webview mode (called “Sidefari”) next to see if this breaks the OAuth flow, too.

A comment from one of trivago’s PWA developers: the PWA OAuth login issue is probably unfixable on iOS11.3 and it needs fixing by the Safari devs. His suggestion is to provide an alternative login mechanism if possible.

@technopagan

This comment has been minimized.

Show comment
Hide comment
@technopagan

technopagan Apr 15, 2018

Just tested OAuth inside a normal Webview and can confirm the OAuth workflow working correctly for it on iOS11.3. So I think we are looking at two different issues:

  1. OAuth workflow being broken on iOS11.3 when using the PWA after doing Add-To-Homescreen

  2. OAuth workflow broken on iOS11.4 Beta 1 Safari as reported by @tomayac & @MarcoZehe

Just tested OAuth inside a normal Webview and can confirm the OAuth workflow working correctly for it on iOS11.3. So I think we are looking at two different issues:

  1. OAuth workflow being broken on iOS11.3 when using the PWA after doing Add-To-Homescreen

  2. OAuth workflow broken on iOS11.4 Beta 1 Safari as reported by @tomayac & @MarcoZehe

@MarcoZehe

This comment has been minimized.

Show comment
Hide comment
@MarcoZehe

MarcoZehe Apr 15, 2018

@technopagan

This comment has been minimized.

Show comment
Hide comment
@technopagan

technopagan Apr 16, 2018

Thanks @MarcoZehe!

So we’re only looking at one specific issue: you currently cannot use Pinafore as a PWA (via Add-To-Homescreen) on iOS 11.3 or above due to the current limitations of Apple’s PWA implementation. What breaks is the OAuth flow due to the sandboxing of the PWA.

Thanks @MarcoZehe!

So we’re only looking at one specific issue: you currently cannot use Pinafore as a PWA (via Add-To-Homescreen) on iOS 11.3 or above due to the current limitations of Apple’s PWA implementation. What breaks is the OAuth flow due to the sandboxing of the PWA.

@technopagan

This comment has been minimized.

Show comment
Hide comment
@technopagan

technopagan Apr 16, 2018

Maybe @addyosmani, @tomdwyer or @firtman or another person with in-depth PWA knowledge has an idea if there’s anything that can be done inside Pinafore to make this work.

Otherwise, all that remains might be to +1 this issue in the Safari issue tracker.

Maybe @addyosmani, @tomdwyer or @firtman or another person with in-depth PWA knowledge has an idea if there’s anything that can be done inside Pinafore to make this work.

Otherwise, all that remains might be to +1 this issue in the Safari issue tracker.

@ram1225

This comment has been minimized.

Show comment
Hide comment
@ram1225

ram1225 Apr 18, 2018

We are also facing the same issue. i.e. OAuth flow breaks in iOS 11.3 in PWA.
Should we have to wait for Apple developers to fix this?

We have reported the issue at https://discussions.apple.com/message/33306161#33306161 .

ram1225 commented Apr 18, 2018

We are also facing the same issue. i.e. OAuth flow breaks in iOS 11.3 in PWA.
Should we have to wait for Apple developers to fix this?

We have reported the issue at https://discussions.apple.com/message/33306161#33306161 .

@nolanlawson

This comment has been minimized.

Show comment
Hide comment
@nolanlawson

nolanlawson Apr 28, 2018

Owner

Thanks @technopagan for the details. I looked a bit into window.open() or an embedded iframe as an alternative to document.location.href = ..., but this has security implications (window.opener, iframe CSP), it might trigger popup blockers, and I also have no evidence that it would even fix iOS or work with Mastodon's existing OAuth implementation. So it seems to me there is indeed no workaround.

To clarify: the data issue is not a problem for me. Edge has exactly the same data model (installed PWAs are sandboxed with their own storage), but it's fine because users can just log in again when they install a PWA. On iOS 11.3+ they can't, because when you do document.location.href = <other origin>, it opens in Safari instead of in the PWA.

I'm inclined to just wait for the WebKit team to fix this, unless there is some simple workaround that doesn't affect security / popup blockers / UX / etc.

Owner

nolanlawson commented Apr 28, 2018

Thanks @technopagan for the details. I looked a bit into window.open() or an embedded iframe as an alternative to document.location.href = ..., but this has security implications (window.opener, iframe CSP), it might trigger popup blockers, and I also have no evidence that it would even fix iOS or work with Mastodon's existing OAuth implementation. So it seems to me there is indeed no workaround.

To clarify: the data issue is not a problem for me. Edge has exactly the same data model (installed PWAs are sandboxed with their own storage), but it's fine because users can just log in again when they install a PWA. On iOS 11.3+ they can't, because when you do document.location.href = <other origin>, it opens in Safari instead of in the PWA.

I'm inclined to just wait for the WebKit team to fix this, unless there is some simple workaround that doesn't affect security / popup blockers / UX / etc.

@MaksymKarpenko

This comment has been minimized.

Show comment
Hide comment
@MaksymKarpenko

MaksymKarpenko Apr 30, 2018

How can I pass data from Safari to the installed PWA ( Process Web.app)? Is it possible?

MaksymKarpenko commented Apr 30, 2018

How can I pass data from Safari to the installed PWA ( Process Web.app)? Is it possible?

@tomayac

This comment has been minimized.

Show comment
Hide comment

tomayac commented May 7, 2018

I've just filed https://bugs.webkit.org/show_bug.cgi?id=185400 that tracks this.

@socceroos

This comment has been minimized.

Show comment
Hide comment
@socceroos

socceroos May 8, 2018

@tomayac I don't think the unload issue has anything to do with the OAuth workflow issue. When going through OAuth workflow, it redirects to Safari and never redirects back to the PWA - unloaded or not.

@tomayac I don't think the unload issue has anything to do with the OAuth workflow issue. When going through OAuth workflow, it redirects to Safari and never redirects back to the PWA - unloaded or not.

@JanDeDobbeleer JanDeDobbeleer referenced this issue in thepracticaldev/dev.to Jun 9, 2018

Open

Unable to log in when using iOS PWA #202

@nikolaydyankov

This comment has been minimized.

Show comment
Hide comment
@nikolaydyankov

nikolaydyankov Jun 25, 2018

I found this discussion from google and I'm not part of this project, but I managed to fix this by removing the manifest meta tag:

<link rel="manifest" href="/tracker/site.webmanifest">

Hope it works for you too, wasted 2 days trying to find a solution.

nikolaydyankov commented Jun 25, 2018

I found this discussion from google and I'm not part of this project, but I managed to fix this by removing the manifest meta tag:

<link rel="manifest" href="/tracker/site.webmanifest">

Hope it works for you too, wasted 2 days trying to find a solution.

@nolanlawson

This comment has been minimized.

Show comment
Hide comment
@nolanlawson

nolanlawson Jun 28, 2018

Owner

Unfortunately that would disable PWA support for non-iOS platforms. Wish there was a way to just disable it for iOS. 😕

Owner

nolanlawson commented Jun 28, 2018

Unfortunately that would disable PWA support for non-iOS platforms. Wish there was a way to just disable it for iOS. 😕

@tomayac

This comment has been minimized.

Show comment
Hide comment
@tomayac

tomayac Jun 28, 2018

One super ugly idea might be to (temporarily until this gets fixed) do something along the lines of the loadCSS folks. Their approach is:

<link rel="preload" href="path/to/mystylesheet.css" as="style" onload="this.rel='stylesheet'">

You could try the following instead:

<link rel="preload" as="fetch" href="manifest.json" onload="if !(/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) this.rel='manifest'">

Not tested, just an idea. In theory this should only make this to link[rel="manifest"] on non-Safari browsers. The regular expression is from StackOverflow. Did I say this is ugly?

tomayac commented Jun 28, 2018

One super ugly idea might be to (temporarily until this gets fixed) do something along the lines of the loadCSS folks. Their approach is:

<link rel="preload" href="path/to/mystylesheet.css" as="style" onload="this.rel='stylesheet'">

You could try the following instead:

<link rel="preload" as="fetch" href="manifest.json" onload="if !(/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) this.rel='manifest'">

Not tested, just an idea. In theory this should only make this to link[rel="manifest"] on non-Safari browsers. The regular expression is from StackOverflow. Did I say this is ugly?

@firtman

This comment has been minimized.

Show comment
Hide comment
@firtman

firtman Jun 28, 2018

With JS (ES5 just in case) you can remove the manifest on iOS with

var manifest = document.querySelector('link[rel=manifest]');
if ('standalone' in navigator) manifest.parentNode.removeChild(manifest);

Also, you can change it to a different one, with display: browser

if ('standalone' in navigator)  document.querySelector('link[rel=manifest]').href='manifest_ios_url';

firtman commented Jun 28, 2018

With JS (ES5 just in case) you can remove the manifest on iOS with

var manifest = document.querySelector('link[rel=manifest]');
if ('standalone' in navigator) manifest.parentNode.removeChild(manifest);

Also, you can change it to a different one, with display: browser

if ('standalone' in navigator)  document.querySelector('link[rel=manifest]').href='manifest_ios_url';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment