InAppBrowser & code execution in app

Situation

I’m building a Proof of Concept of an app with Ionic, that initially is a shell around an existing website. What I would like to do, is open the website via the InAppBrowser plugin. This works fine. However, one of the most important functionalities of this app would be to show a LocalNotification, based upon information that is polled from the server every 30 seconds.

I do understand that this is not an ideal scenario for production but in this case it’s good enough for a PoC.

Separately I can get this to work: either opening the existing website in the InAppBrowser works, or the polling of the server and showing the notification works. Combining the two does not. In this case the existing website will be openend, but it seems like other code execution within the app is paused. Unfortunately I have not been able to find documentation on this.

I’ve seen some hints that using the InAppBrowser will mean that the app is pushed to the background, but I have not found any information that confirms this.

So my question is: Is it possible to keep the polling running while opening the website in the app browser?

For completeness sake here the relevant code:

import { Component, OnInit } from '@angular/core';
import { NavController, Platform } from 'ionic-angular';
import { InAppBrowser } from '@ionic-native/in-app-browser';
import {TaskMessageProvider } from '../../providers/task-message/task-message';

/* 1 */
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage implements OnInit {

  constructor(public navCtrl: NavController,
              private platform: Platform,
              private iab: InAppBrowser,
              private taskMessageProvider: TaskMessageProvider
              ) {
  }

  ngOnInit() {

    console.log('Application initializing');

    this.platform.ready().then((readySource) => {
     // const browser = this.iab.create(' http://localhost:3000/prototype/', '_self', {location: 'no'});
      }
    )
  }
}

And the class that does the polling

import {HttpClient} from '@angular/common/http';
import {Injectable} from '@angular/core';

import {LocalNotifications} from '@ionic-native/local-notifications';
import {timer} from 'rxjs/observable/timer';
import {map} from 'rxjs/operators';
import {concatMap} from 'rxjs/operators';
import {TaskMessage} from "../../models/TaskMessage";

@Injectable()
export class TaskMessageProvider {

  pollingData: any;

  constructor(public http: HttpClient, private localNotifications: LocalNotifications) {
    console.log('Hello TaskMessageProvider Provider');


    const taskMessages = this.http.get('http://localhost:3000/prototype/resources/json/pushstatus.json');

    this.pollingData = timer(0, 30000).pipe(
      concatMap(_ => taskMessages),
      map((data) => {

        let returnValue: any = null;

        if (data instanceof Array) {


          let taskMessages: Array<TaskMessage> = [];

          for (let dataRecord of data) {
            let taskMessage = new TaskMessage(dataRecord);
            taskMessages.push(taskMessage);
          }

          returnValue = taskMessages;
        }

        return returnValue;
      }))
      .subscribe((data) => {
        console.log(data);
        this.showNotifications(data);
      }, () => {
        console.log('some kind of error');
      }, () => {

      });
  }

  showNotifications(taskMessages) {

    let notifications = [];

    for (let taskMessage of taskMessages) {

      let notification = {
        id: taskMessage.id,
        title: taskMessage.title,
        text: 'Lama',
        trigger: {at: new Date()}
      };

      notifications.push(notification);

    }

    this.localNotifications.schedule(notifications);
  }
}


Please note that I’m pretty inexperienced when it comes to Ionic / Angular so there will probably be a lot more that can be improved upon. Rest assured that when this PoC is a success someone will be hired to do this properly :wink:

Quite interesting topic, hope to see nice discussion here!
My guess:
From the native app’s perspective: Your hybrid app is a webview, inside of this webview is your HTML, styles and JS executed. Opening an InAppBrowser you are opening new webview with HTML, styles and JS from external webpage, so your scripts can not be executed the same time, you won’t achieve having InAppBrowser opened and subscription from Ionic’s app controller active same time.
My suggest would to to check PWA as the shell for your webpage, seems like this is ideal scenario to convert to progressive wep app, have you considered this option?

Hi Michal, we have indeed considered PWA’s. The problem is that currently PWA’s do not support all required features, this is especially the case for iOS, which is the largest part of our current mobile user base.

I’ve figured it out! (of course just moments after posting here) but your comment did point me in the right direction. Since ionic is based on Cordova, it opens in the Cordova webview. From the docs of Cordova:

target : The target in which to load the URL, an optional parameter that defaults to _self . (String)

  • _self : Opens in the Cordova WebView if the URL is in the white list, otherwise it opens in the InAppBrowser .
  • _blank : Opens in the InAppBrowser .
  • _system : Opens in the system’s web browser.

Changing the target to _blank works. This leads to some controls being shown, but I’ll probably be able to hide those.

Thanks!

1 Like