Ionic native InAppBrowser: how to add event listener - ionic-framework

I'm using InAppBrowser in my Ionic project the problem is adding new event listener as in the documentation of ionic-native is not working at all, I referred to original cordova-plugin-inappbrowser and none of these events are working, I know this is issue from Ionic wrapping side and their poor documentation, they change the whole way of calling plugin and you need to try until you get the right way.
So I'm asking how to add the event listeners to InAppBrowser plugin?
What I tried until now is:
var _options = 'location=no,clearsessioncache=yes,hardwareback=no';
function openLink(url, target, options) {
if (angular.isUndefined(options)) {
options = _options;
}
if (!$window.cordova) {
$window.open(url, '_blank', options);
} else {
_attachEvents(new $cordovaInAppBrowser(url, target, options));
}
}
function _attachEvents(browser) {
// FIXME this is not working seems, need to find documentation about this
browser.on('loadstart').subscribe(function (e, event) {
console.debug(e, event);
if (event.url.match("mobile/close")) {
browser.close();
}
$rootScope.$broadcast('$ionicParentView.enter');
});
browser.on('loaderror').subscribe(function (e, event) {
console.debug(e, event);
browser.close();
$rootScope.$broadcast('$ionicParentView.enter');
});
}
And tried ngCordova way:
$rootScope.$on('$cordovaInAppBrowser:loadstart', function (e, event) {
if (event.url.match("mobile/close")) {
$cordovaInAppBrowser.close();
}
$rootScope.$broadcast('$ionicParentView.enter');
});
$rootScope.$on('$cordovaInAppBrowser:loaderror', function (e, event) {
$cordovaInAppBrowser.close();
$rootScope.$broadcast('$ionicParentView.enter');
});
And they are not working, BTW, it was working with ngCordova but since I changed to ionic-native, it stopped working at all.
I'm using Ionic 1.3.2 with ionic-native 2.2.16 (since 2.2.17 and 2.3.0 are broken builds)

Related

IONIC 3 InAppBrowser executeScript

I am using this native plugin to open a InAppBrowser. Also I want to inject a css and/or JS in that page, as in that page mentioned, I should use below code for css inject but it doesn't work:
browser.on('loadstop').subscribe(event => {
browser.insertCSS({ code: "body{color: red;" });
});
Can anyone help me?
You can execute javascript with below syntax
let promise = browser.executeScript({
code: '(function() {if(functionname) { return functionname(); }}())'
});
This will return promise
promise.then((values) => {
// process values here
});
where browser is instance of your inappbrowser for example -
const browser = this.iab.create('url', "_blank", this.options);

Can I call Ionic 4 / Capacitor Electron code from the Ionic part of the application?

I am investigating using Ionic 4/ Capacitor to target Windows via the Electron option, for an application where I want to use SQLite.
Using the Ionic Native SQLite plugin, which wraps this Cordova plugin, out of the box, as far as I can see, the Windows support is for UWP, and not Desktop, which runs using Electron in Ionic Capacitor wrapper.
My plan, was to see if I could use Electron SQLite package, and then call this from my Ionic application by making a wrapper class for the Ionic native similar to what I used to get browser support by following this tutoral
If I can call the Electron code from my Ionic app, then I can't see why this wouldn't work.
So, my question here is, can I call code (I will add functions to use the SQlite) I add to the hosting Electron application from within the Ionic (web) code? And if so, how?
Thanks in advance for any help
[UPDATE1]
Tried the following...
From an Ionic page, I have a button click handler where I raise an event..
export class HomePage {
public devtools() : void {
let emit = new EventEmitter(true);
emit.emit('myEvent');
var evt = new CustomEvent('myEvent');
window.dispatchEvent(evt);
}
Then within the Electron projects index.js, I tried..
mainWindow.webContents.on('myEvent', () => {
mainWindow.openDevTools();
});
const ipc = require('electron').ipcMain
ipc.on('myEvent', (ev, arg) => {
mainWindow.openDevTools();
});
But neither worked.
I should mention I know very little about Electron. This is my first exposure to it (via Capacitor)
In case someone is interested, this is how I solved this.
Im am using Ionic 4 / Capacitor + Vue 3.
In my entry file (app.ts) I have declared a global interface called Window as follows:
// app.ts
declare global { interface Window { require: any; } }
Then, I have written the following class:
// electron.ts
import { isPlatform } from '#ionic/core';
export class Electron
{
public static isElectron = isPlatform(window, 'electron');
public static getElectron()
{
if (this.isElectron)
{
return window.require('electron');
}
else
{
return null;
}
}
public static getIpcRenderer()
{
if (this.isElectron)
{
return window.require('electron').ipcRenderer;
}
else
{
return null;
}
}
public static getOs()
{
if (this.isElectron)
{
return window.require('os');
}
else
{
return null;
}
}
}
And I use it like this:
//electronabout.ts
import { IAbout } from './iabout';
import { Plugins } from '#capacitor/core';
import { Electron } from '../utils/electron';
export class ElectronAbout implements IAbout
{
constructor() { }
public async getDeviceInfo()
{
let os = Electron.getOs();
let devInfo =
{
arch: os.arch(),
platform: os.platform(),
type: os.type(),
userInfo: os.userInfo()
};
return devInfo;
}
public async showDeviceInfo()
{
const devInfo = await this.getDeviceInfo();
await Plugins.Modals.alert({ title: 'Info from Electron', message: JSON.stringify(devInfo) });
}
}
This is working but, of course, I still need to refactor the Electron class (electron.ts). Probably using the singleton pattern is a better idea.
I hope this helps.
Update
You can communicate from the render process with your main process (index.js) like this:
//somefile.ts
if (Electron.isElectron)
{
let ipc = Electron.getIpcRenderer();
ipc.once('hide-menu-button', (event) => { this.isMenuButtonVisible = false; });
}
//index.js
let newWindow = new BrowserWindow(windowOptions);
newWindow.loadURL(`file://${__dirname}/app/index.html`);
newWindow.webContents.on('dom-ready', () => {
newWindow.webContents.send('hide-menu-button');
newWindow.show();
});
I dug into this yesterday and have an example for you using angular(this should apply to ionic too).
in your service declare require so we can use it
//Below your imports
declare function require(name:string);
Then in whatever function you want to use it in:
// Require the ipcRenderer so we can emit to the ipc to call a function
// Use ts-ignore or else angular wont compile
// #ts-ignore
const ipc = window.require('electron').ipcRenderer;
// Send a message to the ipc
// #ts-ignore
ipc.send('test', 'google');
Then in the created index.js within the electron folder
// Listening for the emitted event
ipc.addListener('test', (ev, arg) => {
// console.log('ev', ev);
console.log('arg', arg);
});
Its probably not the correct way to access it but its the best way i could find. From my understanding the ipcRenderer is used for when you have multiple browsers talking to each other within electron. so in our situation it enables our web layer to communicate with the electron stuff

how to use Ezar with ionic3

I'm trying to implement ezar to ionic but can't use it. I did ionic cordova plugin add com.ezartech.ezar.videooverlay
window["plugins"].ezar
.initializeVideoOverlay(
function () {
window["plugins"].ezar.getBackCamera().start();
document.body.style.backgroundColor = 'transparent';
},
function (err) {
alert('unable to init ezar: ' + err);
});
It can't find ezar says undefined
I tried without window[] but couldn't succeed it also I can't import at ts file because its not installed as a component. Do you have any idea?
Thank you
This worked for me:
var win: any = window;
if (win.ezar) {
var ezar: any = win.ezar;
ezar.initializeVideoOverlay(
function() {
ezar.getBackCamera().start();
},
function(err) { alert(JSON.stringify(err));
}, {fitWebViewToCameraView: true});
} else {
alert('Unable to detect the ezAR plugin');
}
Try window["ezar"] in place of window["plugins"].ezar
Worked for me (although getting ezAR to work with ionic 3 in general is quite difficult with the lack of documentation)

Tracking url of external site launched in cordova-inappbrowser-plugin

I'm currently building an ionic app which is to be a wrapper for an external web application. What I want to do is to be able to track the url being redirected to when the user changes location in the external web app.
In my main controller I have the following code.
app.controller('MainCtrl', function ($rootScope) {
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
// Now safe to use the Codova API
var url = "https://external-site/";
var target = "_self";
var options = "location=no";
var ref = cordova.InAppBrowser.open(url, target, options);
ref.addEventListener('loadstart', function () {
console.log("loadstart");
});
}
});
When the page loads I don't get the event listener to fire or when the user changes locations in the external site. I have tried pointing the target to _system and _blank which makes no difference for me.
Can anybody help me?
Thanks in advance.
It's my experience that all the events not always fires on all platforms. Try subscribing to all the events and print some debug info. Then test on different devices (iOS, android) and see what events are fired.
$rootScope.$on('$cordovaInAppBrowser:loadstart', function(e, event){console.log('start')};
$rootScope.$on('$cordovaInAppBrowser:loadstop', function(e, event){console.log('stop')});
$rootScope.$on('$cordovaInAppBrowser:loaderror', function(e, event){console.log('err')});
$rootScope.$on('$cordovaInAppBrowser:exit', function(e, event){console.log('exit')});
btw: I'm using ngCordova here...
very strange.. all I did was update ionic, run 'ionic start test blank' add the plugin modify app.js to this
angular.module('starter', ['ionic'])
.run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
if (window.cordova && window.cordova.plugins.Keyboard) {
var inAppBrowserRef;
var target = "_self";
var options = "location=no";
inAppBrowserRef = cordova.InAppBrowser.open('https://onesignal.com/', target, options);
inAppBrowserRef.addEventListener('loadstart', function () { console.log('start') });
inAppBrowserRef.addEventListener('loadstop', function () { console.log('stop') });
inAppBrowserRef.addEventListener('loaderror', function () { console.log('err') });
}
});
})
and then run 'ionic run android' and all events fires perf.

Ionic Deploy: $ionicDeploy.load not working

I'm trying out Ionic deploy. And it seems everything works fine up to the point of loading the app again after getting the update. I've provided screenshots. Let me know if there is anything else i can provide. Thank you.
Console error once the app is finished downloading and extracted, and then it tries to load it again.
Error on my webview
ionic source code for load method in deploy scripts
My javascript implementation:
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
screen.lockOrientation('portrait');
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
// Check for updates
$ionicDeploy.check().then(function(response) {
hide();
console.log(response);
// response will be true/false
if (response) {
show('Downloading update...');
// Download the updates
$ionicDeploy.download().then(function() {
hide();
show('Extracting update...');
// Extract the updates
$ionicDeploy.extract().then(function() {
hide();
// Load the updated version
$ionicDeploy.load();
}, function(error) {
show('Error extracting new update...');
setTimeout(function(){
hide();
}, 1500);
// Error extracting
}, function(progress) {
show('Extract progress...' + progress);
// setTimeout(function(){
// hide();
// }, 5000);
// Do something with the zip extraction progress
// $scope.extraction_progress = progress;
});
}, function(error) {
show('Error downloading...');
setTimeout(function(){
hide();
}, 1500);
// Error downloading the updates
}, function(progress) {
show('Download progress...' + progress);
// setTimeout(function(){
// hide();
// }, 5000);
// Do something with the download progress
// $scope.download_progress = progress;
});
}
},
function(error) {
// Error checking for updates
show('Error checking for updates');
setTimeout(function(){
hide();
}, 1500);
});
});
})
We've seen this error when downloading updates through Ionic Deploy before, and to the best of my knowledge it's caused by either an outdated version of the javascript component (ionic-service-deploy) or the Cordova plugin (com.ionic.deploy).
I think your best course of action would be to update both to the latest version with:
$ ionic plugin add https://github.com/driftyco/ionic-plugins-deploy
$ ionic add ionic-service-deploy
then run:
$ ionic platform remove android
$ ionic platform add android
$ ionic build android
to ensure no old versions of the plugin are cached.
Another possibility; you may have the plugin installed under the id com.ionic.update (You can check this with $ cordova plugins list). In this case, you can fix this by running:
$ cordova plugin remove com.ionic.update
$ ionic plugin add https://github.com/driftyco/ionic-plugins-deploy