Is it possible to share IndexedDB stores and data between a progressive web app (PWA) and stand-alone Safari on iOS? If so, what steps do I need to take to share the stores/data?
My use case is that I have a would-be PWA that uses third party authentication. The normal behavior is that when navigating to the third party authentication page, the PWA automatically opens the page in a new Safari window since it is out of scope. I would like to save the authentication token in IndexedDB from this Safari instance, open my PWA, and then load the token from IndexedDB in my PWA.
I have tested this implementation. It works fine (ie I can read the token from IndexedDB) in Safari standalone, but when I navigate back to my PWA and attempt to read the data, it doesn't exist. This suggests that the stores cannot be shared, but I am looking for a more definitive answer. I find no indication one way or the other in internet searches.
Note: local storage, session storage, and cookies are not shared between Safari and PWAs on iOS, so those solutions do not work which necessitated the use of IndexedDB
Rather than opening a new tab, you can use a pop up, like how it has been beautifully explained here with example and source code.
The key idea used here is window.postMessage, which allows windows and frames to send data across domains to one another.
Related
For the PWA on iOS 11 we solved the external third party login opened in Safari by storing the login details in the service worker web cache.
This no longer works in iOS 12 (in beta as of writing). I think this must be because the PWA now has its own service worker cache that it no longer shares with Safari, but I can't confirm this.
Does anyone know if there is a way to share the service worker cache between safari and the PWA? Note that we already tried IndexedDB, but that is not shared, and of course neither are cookies.
As far as I can figure out this means that a PWA is totally sandboxed from safari and there is no way to get a third party login working. Any solutions?
I asked Jonathan Davis(Web Technologies Evangelist for Apple) on twitter about this question. He says Web apps on iOS (“Save to home screen” apps) do not share data stores with Safari. They work as a standalone app separate from Safari and there is no way to share data between them on device.
As a possible solution that may suit you, I propose an article written by Maciej Caputa. Quoting the author the idea is to create a fake endpoint in service worker, which would save data in the cache on POST request and return cached data on GET request. Link on this article https://www.netguru.com/codestories/how-to-share-session-cookie-or-state-between-pwa-in-standalone-mode-and-safari-on-ios.
Hope this answer was helpful!
OAuth login is now possible as of iOS 12.2 (March 2019) as links of external sites now open in a PWA in-app browser and return links point back to the PWA. As a result I am now able to deploy PWA apps on iOS with third-party Auth0 login (it was already working on Android and Windows).
Note however that login session is not shared between Safari and PWA like in earlier versions of iOS.
I learned of this from this article from Maximiliano Firtman.
I have an application built using XPages' mobile controls. On an ipHone the application behaves as I would like in the standard Safari browser. When I take the url and add it to the Home Page as an icon and use the application from there every time an action I take invokes a native application (Maps, Contacts, Phone, attachment viewers etc.) when I switch back to my application I am immediately asked for my userid and password again. Is there a way to control the behavior to not lose the login credentials the same way that the standard Safari application seems to.
This is a limitation in iOS. If you save it to the home page like that it works, but it will NOT multi-task. That's the problem. So it doesn't remember where you were or anything like that.
As David mentions it starts all over again when you switch back.... The problem is not only the credentials - it is also all the information you may have entered or where you have navigated to in the "app".
This is why I am changing to another approach. I am starting to write apps as web-apps that run locally (i.e. cache the ressources and run on the cached versions of the JS-files, CSS and images). Then I implement a localstorage where you can track where in the app you are - and return to that place again. This way you do not need the authentication for running the app - only for synchronizing the information with the server. My approach is to save data locally and sync them to the server (as a sort of replication). This obviously gives more work - but it also gives a better user experience since you can run the "app" without being connected.
I have tried to control the caching locally using a cache.manifest file. This can be done, however, it is a pain. Therefore, I am now using Sencha Touch which really does this nicely.
/John
PS. I think you may be able to handle the login issue by using the XPage Dojo login custom control (http://www.openntf.org/internal/home.nsf/project.xsp?action=openDocument&name=Xpages%20Dojo%20Login%20Custom%20Control) - however, it does not solve the issue with reloading the page...
It seems the secret to success here is NOT to tell Safari the XPage is capable of acting as a mobile web app. Add the following code inside for the XPage to ensure this is the case.
<xp:metaData
name="apple-mobile-web-app-capable"
content="no">
</xp:metaData>
Note: You can still provide an icon for the home screen, its just that icon will now act more like a bookmark with the Safari controls and (more importantly) you can switch between applications and when you return to Safari it will display your Xpages app just as you left it.
my site is responsive, and it's looking good on Safari on iPhone. But when I browse to my website from my Twitter app on my iPhone, it seems to ignore most of my mobile styling and looks very bad. Is there something I can do to detect if the browser is some kind of mobile app (such as Twitter) and cause the page to load in the default mobile browser instead (Safari, Browser, etc.)?
Edit: I strictly used CSS' max-width media query and targeted HTML5 block elements to change widths into percents. On two navs, I changed the display attribute as necessary.
Turns out it was a caching issue. It loads fine in the Twitter app. Oddly, it didn't before, even after several tries.
To the best of my knowledge, you can't force the site to open in the default mobile browser. The decision whether to open your site in the app's UIWebView or the default Safari browser is made by the Twitter app alone. If the Twitter app was gracious enough to provides any interface for you to choose, it might be possible, but they probably don't. Most app publishers try to keep users inside the app for as long as possible, and throwing them outside to a different app usually goes against this.
Your best bet is probably to try to improve your site's responsiveness to also work inside the Twitter app UIWebView as well (or inside other apps for that matter). If you base your responsiveness on screen width for example (CSS max-width and friends), I assume it should also work inside the Twitter app UIWebView.
The problem you are describing is indeed a very serious and annoying one. UIWebViews inside apps don't implement by default all of Apple's special handlers (that work inside the original Safari). The app maker is expected to implement these manually, and 99% of all apps simply don't do this. It's true for many other apps as well, the Google native search app also opens URLs inside a UIWebView - and sites tend to look lousy there too.
You should also consider filing a bug with Twitter and urge them to improve website compatibility when opened inside their app.
You can't force the user to open the link from a browser from your website. Android WebView is restricted and by default does not allow javascript and other extensions.
You can find more information here: Android WebView VS Phone Browser
I have a client that needed to abandon their very poor native app and needs a temporary solution immediately. They have a mobile optimized website and we'd like to deploy an app in the store to replace the current one, and design it such that as soon as you launch it, it either hosts the site within a web browser control, or just redirects the user to a website in the iPhone Safari app. I realize there are subtle differences between the browser control and the actual Safari browsers.
Are there any tools or products that auto create such simple apps, and are there any problems with getting such simple apps approved by Apple?
Sounds like you want to make a hybrid app.
http://www.cocoacontrols.com/posts/a-primer-on-hybrid-apps-for-ios
Your app could just be a UIWebView that shows the website. It's possible that Apple might reject ithe app if there is nothing to it except a web view -- do some research on that possibility.
Let's say I have a web app that calls out to a native app via a custom URL scheme, and after the native app has done its thing it returns to my web app by opening a callback URL.
This all works fine when my web app is running in Safari. But what happens if a user saves the web app to the home screen (creating a "Web Clip")? In that case it runs in a separate process from regular safari, and has separate cookies and cache.
So when the native app tries to return to the web app, the URL will presumably get opened by Safari, not by the Web Clip, and the session will be lost. (And not just the session -- all the page state, which in a rich Javascript-based web app can be a lot of stuff with non-trivial startup time.)
Is this assumption correct? And if so, is there any way around it? Is there some way to get iOS to try to open the URL with a web clip if installed?
In order to have something launch via a custom url scheme on iOS, you must have an application register this information via the Info.plist built into the app.
It is not possible to have a webapp/webclip register this information system-level.
So, to answer your main question, you cannot do this.
Here is the information on implementing custom URL schemes in native applications.