ionic-team / capacitor

Build cross-platform Native Progressive Web Apps for iOS, Android, and the Web ⚡️
https://capacitorjs.com
MIT License
11.84k stars 994 forks source link

navigator.serviceWorker is not defined on iOS #580

Closed lukas-zech-software closed 6 years ago

lukas-zech-software commented 6 years ago

I'm trying to bundle a PWA in an iOS app. The PWA should use a ServiceWorker.

I used the starter app provided by npx @capacitor/cli create and tried to enable the ServiceWorker there. My www/index.html now looks like this

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="UTF-8">
  <title>Awesome Capacitor App</title>
  <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <meta name="format-detection" content="telephone=no">
  <meta name="msapplication-tap-highlight" content="no">

  <script src="https://unpkg.com/@ionic/pwa-elements@0.0.12/dist/ionicpwaelements.js"></script>

  <link rel="icon" type="image/x-icon" href="assets/icon/favicon.ico">
  <link rel="manifest" href="manifest.json">
  <link rel="stylesheet" href="css/style.css">
  <meta name="theme-color" content="#31d53d">

  <script>
    console.log('\'serviceWorker\' in navigator', 'serviceWorker' in navigator); // logs false

    if ('serviceWorker' in navigator) {
      console.log('install service worker'); // never gets logger

      navigator.serviceWorker.register('service-worker.js')
        .then(() => console.log('service worker installed'))
        .catch(err => console.log('Error', err));
    }
  </script>
</head>
<body>
  <capacitor-welcome></capacitor-welcome>

  <!--
    This simple example uses Capacitor Core as a bundled file.
    For large apps, we recommend using a bundler/module loader such as
    rollup or webpack and importing Capacitor using ES2015 imports.
  -->
  <script src="capacitor.js"></script>

  <script src="js/capacitor-welcome.js"></script>
</body>
</html>

As mentioned in the snippet 'serviceWorker' in navigator returns false, therefore the service worker cannot be installed.

Am I missing something?

I am building an emulating the App on XCode (Version 9.4 (9F1027a)) with iOS 11.4 as deployment target.

The same code seems to work on Android 8.1 emulated with Android Studio 3.1.3

mlynch commented 6 years ago

We don’t yet support service worker polyfilling when running natively. Not sure we want to, open to any thoughts or comments

lukas-zech-software commented 6 years ago

How else am I going to implement stuff like background sync and push notifications in my PWA and deploy that to the app stores wrapped via capacitor?

lukas-zech-software commented 6 years ago

Should stuff like that be wrapped in a Plugin, which uses service workers if the target is web and native APIs else?

I was under the impression, that we could use service workers everywhere

jgw96 commented 6 years ago

@lukas-zech-software Just wanted to jump in here to clear things up. Because of security, service workers can only be used on an https connection. Capacitor, Cordova and any other native interop layer do not operate over https connections, therefore service workers will not work. I am also not completely sure that the chrome webview on Android even implements service workers (not sure on iOS either).

lukas-zech-software commented 6 years ago

ok, so the stuff I wanted to implement with service workers should rather use plugins to use the native implementation for each platform.

so im eager to see push notifications implemented: https://github.com/ionic-team/capacitor/issues/380

kevinsimper commented 5 years ago

@jgw96 I guess you could still polyfill service workers on http still, a pwa without service-workers wouldn't really be a pwa as the progressive wouldn't exist without huge changes to the original code.

diachedelic commented 5 years ago

I'm a bit stumped here - I was planning on using service workers to intercept HTTP requests and manually manage the cache. While navigator.serviceWorker exists on Android, I get these errors when calling navigator.serviceWorker.register('sw.js'):

An unknown error occurred when fetching the script.
Failed to load resource: net::ERR_CONNECTION_REFUSED
(index):1 Uncaught (in promise) TypeError: Failed to register a ServiceWorker: An unknown error occurred when fetching the script.

I know sw.js is accessible because fetch('sw.js') resolves, so it looks like the Android Chrome WebView is denying service workers. However, according to this WebViews do support service workers.

adamlacombe commented 5 years ago

@diachedelic If I'm not mistaken - Capacitor launches its own web server which may or may not have an SSL cert. If it does use SSL it may be an issue with it being self-signed.

Its been a few months since I've used Capacitor, so if there is an option to load your PWA via URL instead I would give that a shot.

I was able to run our PWA+SW using this repo https://github.com/xtools-at/Android-PWA-Wrapper just to verify that it wasn't an issue with webview.

diachedelic commented 5 years ago

@adamlacombe by "load your PWA via URL" do you mean a remote URL rather than local?

And yes, it is running on HTTPS but i suppose it will be self-signed

diachedelic commented 5 years ago

Looks like there's an unanswered stackoverflow question Service worker with self signed certificate on Android WebView

jcesarmobile commented 5 years ago

Please, stop commenting on a closed issue that is not even related to what you are commenting about as the original issues is about iOS