Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to package a hosted web app with Ionic Capacitor

I have a hosted, CMS-based web app that I want to package as an Android / iOS app with Ionic Capacitor. So I added

  "server": {
    "url": "https://my.domain/"
  },

to capacitor.config.json and did

import { Capacitor, Plugins } from '@capacitor/core';

console.log('Plugins', Capacitor.Plugins);

in the main Javascript file of my app (I use webpack for bundling). This basically works, i.e. the app gets loaded and displayed properly. But on the console I see that Capacitor loads the web versions of the plugins, and Device.getInfo() says that the platform is "web", not "android".

How can I make Capacitor act like it would when my app was loaded from the device's file system, and in particular how can I make it use the native versions of the plugins in this setup?

like image 702
Matthias Avatar asked Apr 28 '19 21:04

Matthias


1 Answers

As it turned out, the reason for my troubles where that my pages had an active service worker. Capacity uses WebViewClient::shouldInterceptRequest for injecting the Javascript code that initializes the bridge to the native world, and Android does not call this callback for requests that a service worker handles. Instead, it has a separate callback for these requests that is available via a ServiceWorkerController.

So what I did was creating my own tiny plugin:

@NativePlugin
public class ServiceWorker extends Plugin {

  @RequiresApi(api = Build.VERSION_CODES.N)
  @Override
  public void load() {
    ServiceWorkerController swController = ServiceWorkerController.getInstance();

    swController.setServiceWorkerClient(new ServiceWorkerClient() {
      @Override
      public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) {
        return bridge.getLocalServer().shouldInterceptRequest(request);
      }
    });
  }

}

and then it worked as expected. (I also had to add the getter for localServer to the Bridge class.)

like image 175
Matthias Avatar answered Nov 01 '22 11:11

Matthias