Check if running phonegap or apk - phonegap

I have a code that will not run if the app is running via Phonegap (it will completly stop the script), will only run as an apk (needs to be built). How can I create an if that will check if its in phonegap or a standalone apk?

I test my apps using IIS (localhost). I use to check if the url contained "localhost", later found out about checking window.cordova to determine if the app is running as Cordova App.
Example:
function isRunningLocalhost() {
if (window.cordova) {
console.log('runningLocalhost() - False In Cordova');
return false;
}
else {
console.log('runningLocalhost() - True Running Localhost');
return true;
}
}
if (isRunningLocalhost() === true)
{
//Not running as an APK
}

Related

How do I include cross compiled client JS Code in the Fat Jar or the Docker Container on a Kotlin Multiplatform/Ktor application?

I inherited a small Kotlin Multiplatform/Ktor application a little while ago and and moving on to deployment. I'm extremely new to this framework, and gradle as a whole and I'm having issues including cross compiled client side JS inside of the Fat Jar or the Docker Container. I'm not entirely sure if this is supposed to be inside of the Fat Jar, or if I include the JS into the Docker Container, I just know that it doesn't work like it is supposed to and I can't find any good documentation or answers to these questions.
The error I get specifically is this:
The HTML Page errors here:
<script>
Application.main();
</script>
Uncaught Reference Error: Application is not defined
The page works normally and the function is called when running the project in Intellij IDEA, but when I create a Docker Image out of the Fat Jar, or run it outside of IDEA, it no longer works. Here is the Kotlin source file just for posterity:
(In Application.kt)
fun main() {
Here's my Dockerfile:
FROM gradle:7-jdk11 AS build
COPY --chown=gradle:gradle . /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle buildFatJar --no-daemon
FROM openjdk:11
EXPOSE 8080:8080
RUN mkdir /app
COPY --from=build /home/gradle/src/build/libs/MyApp.jar /app/MyApp.jar
ENTRYPOINT ["java","-jar","/app/MyApp.jar"]
Here's my build.gradle.kts:
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack
val kotlinVersion = "1.7.20-Beta"
val ktorVersion = "2.0.3"
val kotlinxHtmlVersion = "0.8.0"
val kotlinxCoroutinesVersion = "1.3.8" //curr: 1.6.4
val kotlinWrappersVersion = "1.0.0-pre.354"
val logbackVersion = "1.2.3" //11
plugins {
id("io.ktor.plugin") version "2.1.3"
kotlin("multiplatform") version "1.7.20-Beta"
application
}
application {
mainClass.set("com.example.application.ServerKt")
}
ktor {
fatJar {
archiveFileName.set("MyApp.jar")
}
}
group = "com.example"
version = "1.0-SNAPSHOT"
repositories {
jcenter()
mavenCentral()
}
dependencies {
implementation("org.apache.commons:commons-email:1.5")
}
kotlin {
jvm {
compilations.all {
kotlinOptions.jvmTarget = "1.8"
}
withJava()
testRuns["test"].executionTask.configure {
useJUnitPlatform()
}
}
js {
browser {
binaries.executable()
dceTask {
keep("Application.columnIndex", "Application.prepareTable")
}
}
}
sourceSets {...} // excluded for brevity
}
// include JS artifacts in any JAR we generate
tasks.getByName<Jar>("jvmJar") {
val taskName = if (project.hasProperty("isProduction") || project.gradle.startParameter.taskNames.contains("installDist")) {
"jsBrowserProductionWebpack"
} else {
"jsBrowserDevelopmentWebpack"
}
val webpackTask = tasks.getByName<KotlinWebpack>(taskName)
dependsOn(webpackTask) // make sure JS gets compiled first
from(File(webpackTask.destinationDirectory, webpackTask.outputFileName)) // bring output file along into the JAR
}
tasks {
withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
distributions {
main {
contents {
from("$buildDir/libs") {
rename("${rootProject.name}-jvm", rootProject.name)
into("lib")
}
}
}
}
// Alias "installDist" as "stage" (for cloud providers)
tasks.create("stage") {
dependsOn(tasks.getByName("installDist"))
}
tasks.getByName<JavaExec>("run") {
// so that the JS artifacts generated by `jvmJar` can be found and served
classpath(tasks.getByName<Jar>("jvmJar"))
}
After running the docker file, which runs buildFatJar, it copies the created Jar to the Docker Image, then I manually add in static files & some .json files and all of that works fine; however, I cannot for the life of me get the cross compiled JS to work or be referenced in the application.
TLDR: How can I include the cross compiled JS either within the Fat Jar itself or in the Docker container?
I've already tried this: https://stackoverflow.com/questions/61245847/create-fat-jar-from-ktor-kotlin-multiplatform-project-with-kotlin-gradle-dsl
and many variations of this plus several other stack overflow answers and nothing seems to work for me.
I have tried several different methods to get the Cross compiled JS into the fat jar, and when that failed, I tried taking the contents of the build/js/ directory and copying them into the docker container instead to see if that would allow it to run and neither method worked for me.
I've been looking for answers on this all day and have found nothing, so any suggestions would be helpful, thanks!
Turns out the answer was actually pretty simple. The file from /build/distributions called Application.js needed to be moved into the project and in a place where the server could see & serve it, i.e. /static/script.
Leaving this up here because this isn't documented anywhere and I spent like 4 hours looking for a solution, so I hope this helps people in the future.

Ionic App - SQLite error "plugin_not_installed" only when running app in iOs devices

I builded an hybrid app using Ionic3+AngularJS and it uses the SQLite database.
When I run the app in Android's devices it works perfectly but when I try to run it in an iPhone or iPad I get the following error: plugin_not_installed. It happens when the app tries to create the database.
This is how it's creating the database:
public getDB(){
return this.sqlite.create({
name: 'namedatabase.db',
location: 'default'
}).catch( error => this.showError(error));
}
The catch() is called and it shows the error message "plugin_not_installed".
SQLite installed using:
$ ionic cordova plugin add cordova-sqlite-storage
$ npm install --save #ionic-native/sqlite
Any ideas?
I'm getting the same issue when I run my app in an android emulator using
ionic cordova run android -lc
When the app start, everything is ok. But after a couple of changes in my code and a save command, the app reload and show in my console
console.warn: Ionic Native: deviceready did not fire within 5000ms. This can happen when plugins are in an inconsistent state. Try removing plugins from plugins / and reinstalling them.
console.warn: 'Native: tried accessing the SQLite plugin but it's not installed.
console.warn: Install the SQLite plugin: 'ionic cordova plugin add cordova-sqlite-storage'
console.log: err "plugin_not_installed"
Even if I followed what the console asked me to do, I'm still getting the same error and it cannot create my SQLite database
What I did next is to re-run the app using the run command above, but it waste a lot of time for me to wait for the app to get started again... and again :(
createDBFile() {
this.sqlite.create({
name: DB_NAME,
location: 'default'
}).then((db: SQLiteObject) => {
this.db = db;
console.log('BDD cree')
this.stockageLocal.get('dbstatus').then(opened => {
if (opened) {
console.log('DB deja ouvert');
}
else {
console.log('create all table')
this.createTables();
}
})
}).catch(err => {
console.log(' err', JSON.stringify(err))
});
}
I had the same problem: plugin_not_installed.
I resolved putting console.log check after the promise errors and seeing that the table didn't exist.
The code:
this.sqlite.create({
name: 'ionicdb.db',
location: 'default'
})
.then((db: SQLiteObject) => {
db.executeSql('create table if not exists MY_SQLITE_STORAGE(key VARCHAR(32) PRIMARY KEY, value VARCHAR(32))', [])
.then(() => {
console.log('Executed Create table if not exists');
this.toastCtrl.create({
message: 'Table created ',
duration: 5000,
position: 'center'
}).present();
}).catch(e => console.log('error: '+JSON.stringify(e)));
}).catch(e => console.log('error: '+JSON.stringify(e)));

How do I set NODE_ENV=production on Electron app when packaged with electron-packager?

How do I make packaged releases of my Electron application set NODE_ENV=production when packaged with electron-packager?
UPDATE 2019/12
Use app.isPackaged: https://electronjs.org/docs/api/app#appispackaged-readonly
It returns true if the app is packaged, false otherwise. Assuming you only need a check if it's in production or not, that should do it. The env file solution detailed below would be more suitable if you had different environments/builds with different behaviors.
To my knowledge, you can't pass env vars to a packaged electron app on start (unless you want your users to always start it from the command line and pass it themselves). You can always set that env variable in your application like this: process.env.NODE_ENV = 'production'. You could integrate that with electron-packager by having an env file that gets set in your build and is required by your application to determine what environment it's in.
For example, have a packaging script that looks like:
"package": "cp env-prod.json src/env.json && npm run build"
and in your src/main.js file:
const appEnv = require('./env.json');
console.log(appEnv) //=> { env: "prod", stuff: "hey" }
//you don't really need this, but just in case you're really tied to that NODE_ENV var
if(appEnv.env === 'prod') {
process.env.NODE_ENV = 'production';
}
You can set it in 2 ways.
By command line with --no-prune see here in the usage guide
Or programmatically with this API
var packager = require('electron-packager');
var options = {
'arch': 'ia32',
'platform': 'win32',
'dir': './'
'prune': true //this set the enviroment on production and ignore dev modules
};
packager(options, function done_callback (err, appPaths) { /* … */ })
For more options see this guide

Electron - How to add react dev tool

What is the easy way to add react dev tool to electron window? I try add the extension hash
BrowserWindow.addDevToolsExtension('path/to/extension/ade2343nd23k234bdb').15.01
But when the extension update, I had to manually update the string in main.js. I'm looking for a better way.
Here is a Solution for Electron <= 1.2.1 version
1- In your app folder
npm install --save-dev electron-react-devtools
2- Open your electron app, click on (view/toggle developer tools). In the console tab insert the following code and hit enter:
require('electron-react-devtools').install()
3- Reload/refresh your electron app page and you'll see the react dev tools appear.
4- Done!
See screen shots bellow
You can add react devtools directly from your main.js file like this
const installExtensions = async () => {
const installer = require('electron-devtools-installer')
const forceDownload = !!process.env.UPGRADE_EXTENSIONS
const extensions = [
'REACT_DEVELOPER_TOOLS',
'REDUX_DEVTOOLS',
'DEVTRON'
]
return Promise
.all(extensions.map(name => installer.default(installer[name], forceDownload)))
.catch(console.log)
}
app.on('ready', async () => {
if (dev && process.argv.indexOf('--noDevServer') === -1) {
await installExtensions()
}
createWindow()
})
addDevToolsExtension is not an instance method, so you need to call BrowserWindow.addDevToolsExtension('path/to/extension').
Below solution worked for me (https://github.com/MarshallOfSound/electron-devtools-installer#usage) -
npm install electron-devtools-installer --save-dev
or
yarn add electron-devtools-installer -D
import installExtension, { REDUX_DEVTOOLS } from 'electron-devtools-installer';
// Or if you can not use ES6 imports
/**
const { default: installExtension, REACT_DEVELOPER_TOOLS } = require('electron-devtools-installer');
*/
const { app } = require('electron');
app.whenReady().then(() => {
installExtension(REDUX_DEVTOOLS)
.then((name) => console.log(`Added Extension: ${name}`))
.catch((err) => console.log('An error occurred: ', err));
});
If you see a blank component when launching react-devtools, it's probably because you've installed the package globally as it is recommended in the react-native docs, in the debugging section. What's happening is it doesn't get connected to your app, because it's not your app-specific.
You need to install it locally.
npm install --save-dev react-devtools
or
yarn add -D react-devtools

How to start the Appium server from command prompt in MAC machine?

I am automating ios native mobile application using appium. Until now I was launching the server from the Appium GUI by clicking on the Launch button. Now I want to start the server from a command prompt.
I was able to do the same in Windows machine by following the below steps:
Launch Node.js command prompt
Navigate till the Appium bin folder
Use the command node appium
I got blocked on how to start the Node.js command prompt on a Mac. Can you pleases tell me how I can start the Appium server from a command prompt on a Mac.
if you used npm install -g appium then you should be able to directly open one with the command
appium //plus any server args you want ex: appium -p 4474
Or you can still navigate to the folder of your node_modules and into appium and go with
node . //plus any server args you want
if you want to have additional server flags, all are available at their site with documentations.
Open the terminal and type in the following command
appium --address 127.0.0.1 --port 4723
Press enter then it will register itself to 127.0.0.1 and will listen 4723 port. You can extend this command by adding app type etc.
Hope this will help you
cheers
/Applications/Appium.app/Contents/Resources/node/bin/node /Applications/Appium.app/Contents/Resources/node_modules/appium/bin/appium.js --address 127.0.0.1 --chromedriver-port 9516 --bootstrap-port 4725 --no-reset --local-timezone --command-timeout 7200 --session-override --debug-log-spacing --platform-version 9.0 --platform-name iOS --app /Users/chennareddy/u/apps/TestApp/build/release-iphonesimulator/Handstand/Handstand.app --show-ios-log --device-name iPhone-6s --native-instruments-lib --orientation Portrait
To start appium in MAC, all you need to do is to type => appium & in the terminal application. In order for the above command to work, you have to install appium in terminal mode. However there are 2 ways of doing it, one is with HomeBrew and the other directly with Node.js . You can find the tutorial of installing HomeBrew online. Follow the steps below to install it directly with node.js -
Go to https://nodejs.org/
Download and install the latest stable version of node.js package in your mac
Now open the terminal application
Run the following command => npm install -g appium
This should install Appium in your system with global privileges. After installation of appium, you can run the command => appium-doctor in the same terminal window to verify if everything is installed properly.
If everything is in green ticks, run => appium & to start the appium server
Hope this helped.
As other answers points out, if you have installed Appium thru terminal then simply type appium & on a terminal window to start appium server. Here all you need to know, how to install appium thru terminal.
1. Install Homebrew.
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
2. Give Following commands one by one to install appium
brew install node # get node.js
npm install -g appium # get appium
npm install wd # get appium client
appium & # start appium
You can find refer to step by guide for appium download osx here.
String tellCommand = "tell application \"Terminal\" to do script \"/usr/bin/node_modules/appium/bin/appium.js";
String parameters = " -p "+port;
parameters += " "+ (fullReset ? "--full-reset" : "--no-reset")+"\"";
tellCommand += parameters;
String[] command = { "osascript", "-e",
tellCommand };
ProcessBuilder pBuilder = new ProcessBuilder(command);
pBuilder.start();
Try this to launch your appium server programmatically for mac os, it includes automating the webkit debug proxy as well which is needed for debugging.
//customize the below in start server method
//Webkit Proxy command
CommandLine iOSProxyCommand = new CommandLine("ios_webkit_debug_proxy");
iOSProxyCommand.addArgument("-c");
iOSProxyCommand.addArgument(udid+":27753");//provide your udid of the device
iOSProxyCommand.addArgument("-F");//to disable console output in eclipse
DefaultExecuteResultHandler iOSProxyresultHandler = new DefaultExecuteResultHandler();
DefaultExecutor iOSProxyexecutor = new DefaultExecutor();
iOSProxyexecutor.setExitValue(1);
try {
iOSProxyexecutor.execute(iOSProxyCommand, iOSProxyresultHandler);
iOSProxyCommand.toString()));
Thread.sleep(5000);
System.out.println("iOS Proxy started.");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
CommandLine command = new CommandLine(
"/Applications/Appium.app/Contents/Resources/node/bin/node");
command.addArgument( "/Applications/Appium.app/Contents/Resources/node_modules/appium/bin/appium.js",
false);
command.addArgument("--address", false);
command.addArgument("127.0.0.1");
command.addArgument("--port", false);
command.addArgument("4723");
command.addArgument("--full-reset", false);
command.addArgument("--log-level", false);//to disable console output in eclipse
command.addArgument("error");
command.addArgument("--log", false);
Timestamp currentTimestamp = new java.sql.Timestamp(Calendar.getInstance().getTime().getTime());
command.addArgument("/Users/sethupandi/appium"+currentTimestamp+".log");
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(1);
try {
executor.execute(command, resultHandler);
Thread.sleep(5000);
System.out.println("Appium server started.");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//customize the below in stop appium server-
//kill appium node after end of your execution
String[] command = { "/usr/bin/killall", "-9", "node" };
try {
Runtime.getRuntime().exec(command);
System.out.println("Appium server stopped.");
} catch (IOException e) {
e.printStackTrace();
}
//Kill webkit proxy for iOS
String[] commandProxy = { "/usr/bin/killall", "-9", "ios_webkit_debug_proxy" };
try {
Runtime.getRuntime().exec(commandProxy);
System.out.println("iOS Webkit proxy stopped");
} catch (IOException e) {
e.printStackTrace();
}
For anybody reading this who happens to be using npm (node/js/typescript), I've created a module called appium-controller that starts and stops appium in the background programmatically (mac or windows). It has an option to pass in a specific port either through a node call to the method or through cli.

Resources