Skip to content

cordova

A way of making android and iphone apps with one codebase. It uses html javascript and css.

installation

You will need cordova, and plugin manager, but also nodejs and it's package manager nps (visit)

install
1
2
3
4
5
wget http://nodejs.org/dist/v0.10.26/node-v0.10.26.tar.gz
tar -zxvf node-v0.10.26.tar.gz
cd node-v0.10.26
./configure
make install

There are binaries as well, but this installed smoothly so i prefer that. Now if you did this on linux chances are nodejs will be called node and clashes with another package called node (ax25-node). Making a link to nodejs will solve that problem

install
/usr/local/bin $ sudo ln -s ../../bin/nodejs node
install
sudo npm install -g cordova
sudo npm install -g plugman

If you cannot run plugman after this you probably forgot the -g, which means global. I got a problem with downloading errors, this could be solved using http instead of https:

plugman
sudo npm set registry http://registry.npmjs.org/
sudo npm install -g plugman

Now you will need the platforms to create any usable phone app, so for iphone take a look at this, and for android here or pick your taste We might need to install osX and xcode, i surely hope not.

android

Now if you have android sdk correctly installed, you could run :

start app
1
2
3
cordova create helloworld org.klopt.hello "hello world"
cd helloworld
cordova platform add android

But if not, you probably get an error on the last call, something like :

error
Error: An error occurred while listing Android targets

Now if you can't list the android by hand you cannot expect cordova to do it. So if

targets
android list targets

Does not work, neither will cordova. So you probably need to install the adt bundle

debugging

As stated below in this chapter webview is a very neat way of debugging cordova apps, however i also wanted to test apps on my older phone which is a samsung 3 mini and that runs 4.1.X (jellybean) and webview debugging is only working from kitkat (4.4) and up.

Therefore you need the good ole way which i will describe below.

logcat

My app was working perfectly on honor6 but just printed the background on samsung galaxy 3s. The only way to get some sensible information on this is to test if there is a device listening, and if so start logcat.

logcat
adb devices
adb logcat > log.txt

The last command is vital because you get a LOT of debugging and you will have to filter it out.

Now start the app until the screen appears, and hit CTRL+C on the logcat command. In my case the problem was found in these debug messages :

log
1
2
3
4
5
D/SystemWebChromeClient( 8753): file:///android_asset/www/js/game.js: Line 49 : Uncaught SyntaxError: Unexpected identifier
E/Web Console( 8753): Uncaught SyntaxError: Unexpected identifier:49
D/SystemWebChromeClient( 8753): file:///android_asset/www/js/tabs.js: Line 35 : Uncaught SyntaxError: Unexpected identifier
E/Web Console( 8753): Uncaught SyntaxError: Unexpected identifier:35
D/SystemWebChromeClient( 8753): file:///android_asset/www/js/speelschema.js: Line 5 : Uncaught ReferenceError: Tabs is not defined

The first of course is the best to tackle first and it turns out i used the for of construct in javascript :

for of loop
1
2
3
for (elm of list) {
    // use elm
}

And this is not supported in older javascript versions, so turning them into this helped :

for in loop
1
2
3
4
for (i in list) { 
    var elm = list[i];
    // use elm
}

So better not use that at all in cordova apps.

webview

Google has some features in this case. Install webview-debug plugin :

Please note that as of Cordova 3.3.0, this functionality is supported directly by Cordova, and this plugin is not required.

Chances are HUGE you can skip this step : .. code-block:

cordova plugin add https://github.com/jrstarke/webview-debug.git

See here for more information.

To debug webview: Make sure that you have adb installed, and that USB debugging is enabled on your device.

  1. Connect your device to your computer using a USB cable.
  2. In your Chrome 30+ browser, open the url . (or )
  3. Start debugging and wait until this sdk appears in the devices list.
  4. Find the application you would like to debug in the list, and click the inspect link.

mapkit plugin

First you need to install the plugin itself.

mapkit
cordova -d plugin add https://github.com/imhotep/MapKit --variable API_KEY="your_key_here"

This should install the plugin for you and use you key in the correct places. ### troubleshooting com.google.android.gms.common.ConnectionResult #### Could not find gradle wrapper cordova clean android ANDROID_HOME=/home/kees/Install/android-studio JAVA_HOME=/home/kees/Install/jdk1.8.0_91 Error: Could not find gradle wrapper within Android SDK. Might need to update your Android SDK. Looked here: /home/kees/Install/android-studio/tools/templates/gradle/wrapper This problem was caused by a wrong ANDROID_HOME setting. The place where android installs other tools is not where you unpack the android-studio files, but in my case it was : ~/Android/Sdk. To get the above warning to go away you need this setting: export ANDROID_HOME=/home/kees/Android/Sdk

cordova-plugin-file

You can use this with the browser plugin, but it's a bit of a search for the places. A very handy tool is chrome webview to debug your apps (see above). To quickly see what's wrong and where the files might be print the cordova object on the console :

webview
1
2
3
console.log(cordova)

You will get an [Object] line in the console which you can ‘open’. If it does not have a file member at all recheck if you have the plugin installed correctly. Otherwise open in up. You will see all possibilities for the system directories and a hint about their placement :

reloading cordova run browser

Having to restart this command again on every change becomes a little tedious :

manual
cordova run browser

So here is a plugin that does the reloading for you , however an F5 will still be necessary of course.

reload
cordova plugin add cordova-plugin-browsersync
cordova run browser -- --live-reload
output
applicationDirectory: "file:///android_asset/"
applicationStorageDirectory: "file:///data/data/org.klopt.registratie/"
cacheDirectory: "file:///data/data/org.klopt.registratie/cache/"
dataDirectory: "file:///data/data/org.klopt.registratie/files/"
documentsDirectory: null
externalApplicationStorageDirectory: "file:///storage/emulated/0/Android/data/org.klopt.registratie/"
externalCacheDirectory: "file:///storage/emulated/0/Android/data/org.klopt.registratie/cache/"
externalDataDirectory: "file:///storage/emulated/0/Android/data/org.klopt.registratie/files/"
externalRootDirectory: "file:///storage/emulated/0/"
sharedDirectory: null
syncedDataDirectory: null
tempDirectory: null

Browser

output
applicationDirectory: "http://localhost:8000/"
applicationStorageDirectory: null
cacheDirectory: "filesystem:file:///temporary/"
dataDirectory: "filesystem:file:///persistent/"
documentsDirectory: null
externalApplicationStorageDirectory: null
externalCacheDirectory: null
externalDataDirectory: null
externalRootDirectory: null
sharedDirectory: null
syncedDataDirectory: null
tempDirectory: null

The first reason is that the dataDirectory for instance is not readable for a normal user (you cd int /data/data/* but nothing will be listed). Maybe if you are rooted it works, but i don't want to root yet. In fact it won't matter where the file is if we can get it to sync with the back end, so we may opt for another file.

Also be sure to initialize the log after the device is initialized, for instance the member .file might not be available while starting up . So do it in the onDeviceReady callback !!

The music on my honor is in :

music on phone
/storage/sdcard1/DCIM/Music 

/storage is the location where all sdcards are mounted.

iOs

If you get problems with cordova on IOS, especially with xcode 7 beta installed.

It will say something about simctl not found. If you run this command :

xcodebuild
/usr/bin/xcodebuild xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

You might need to reset the developers directory :

xcode-select
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer

or for the beta (or just use TAB to see what you have)

xcode-select
sudo xcode-select --switch /Applications/Xcode-Beta.app/Contents/Developer

Also install cordova etc :

install for ios
npm install -g cordova
npm install -g ios-sim

provisioning profile

To deploy an app to the device, at least with command line like below, you need a distribution profile. I managed to create a profile for both development and distribution using the same key. On the developer if you create the provisioning profile, you automatically get asked to perform the other steps of generating what you need. You need to install the key in your mac's (vm's) keychain access and download the provisioning profile. I double clicked it but i don't know if that is needed. You need to copy the certificate and profiles to other machines/vms to use it there as well.

Creating the .ipa file

As said before you need to set the provisioning profile correctly for this. First install the cordova project :

.ipa file
1
2
3
4
5
git clone https://keesklopt@bitbucket.org/keesklopt/registratie.git
cd registratie/registratie
cordova platform add ios
cordova prepare ios
cordova platform update ios@3.9.2

I don't remember if that last one was needed, but it works with so.... Now there should be an xcode project generated, which you can open with xcode. It will be in

ios
platform/ios/

Now you will have to set the correct profile and scheme. Select the scheme you want to use in product->scheme and remember the name , then set the provisioning profile to the distribution or 'ad hoc' profile.

Now some commandline action, still in the directory of the .xcodeproject source : visit

xcodebuild
xcodebuild -target "My Target" -scheme "Registration" -configuration Release clean archive

Watch the output, it will mention the app directory somewhere near the end, you need it for this next command :

xcrun
/usr/bin/xcrun -sdk iphoneos PackageApplication "/absolute/path/to/MyApp.xcarchive/Products/Applications/MyApp.app" -o "/absolute/path/to/MyApp.ipa"

and... it does not work. step 1 gives an empty archive. Fuck you apple ... For now the only way to do this is to open the project in xcode, then choose as active scheme (with the button in the top bar) to "Generic ios device". Just do both Registratie and Cordovalib that way.

nativescript version

For nativescript, you should open the helloworld.xcodeproject in the platform/ios/.. directory tree. Then to spare an endless searching this horrible p.o.s.

Everything takes place in the 'project editor' : what a crap interface if you have to make a bullet list for this :

  • Click on the folder icon in the topleft corner, if you hover over it it will say "Show the project navigator". Now you projects should be shown in treeview.
  • Select the root of your project, let's say "HelloWorld", then there should be another menu "HelloWorld" in the menu to the right with a dropdown menu.
  • Open the dropdown menu and you will see "Targets" with one or more options, choose "HelloWorld".
  • Now you seem to be in the project editor, thanks apple !!

You will probably have to fix some things here, like altering the team option to your own email address (or at least the one your apple account is bound to). When the red crosses are gone you have installed a provisioning profile for this project. You will be able to re-run the xcodebuild command from before again.

In my case it was :

xcodebuild
xcodebuild -scheme "HelloWorld" -configuration Debug clean archive 

And it mentioned near the end the archive that was built which is needed for the package step :

The archive option in the "Product" Menu should now be 'ungreyed' . Run it, and watch it build.

Moreover.. after that if you build cordova from then on ... :

ios
cordova build ios --device 

If this complains about a missing key, you probably installing on a second machine , and have to install the original key pair on this machine as well. Go to the original machine, and export the private and public key, it will be a .pem and a .p12 file so you will have to provide a password for the private key. Copy these to the new machine and install them again, after that .....

If should give :

output
Results at '/Users/klop/projects/registratie/registratie/platforms/ios/build/device/Registratie.ipa'
** BUILD SUCCEEDED **

So ..

scp '/Users/klop/projects/registratie/registratie/platforms/ios/build/device/Registratie.ipa' kees@10.0.2.2:

And install it on linux !!;) .. .See next chapter

ideviceinstaller and libimobiledevice

This is a neat set of tools on linux. Though you may need to install this from source if you get the message about not being able to find a proxy. Just install both libimobiledevice and ideviceinstaller again and it worked for me

If the libidevice.so can't be found, just run :

ldconfig
sudo ldconfig 

Once.. then install the ipa file created earlier with :

ideviceinstaller
ideviceinstaller -i Registratie.ipa
ios-deploy
deploy
npm -g install ios-deploy, this is on osx

problems with connecting to lockdownd

Installation guide for ideviceinstaller and libidevice here

Additional problems arose on stretch, where i get error when running ideviceinstaller.

First problem is when you cannot connect to the iphone with ideviceinfo

ideviceinstaller
ideviceinstaller -l

Should list all devices, but instead it says :

This one is easily fixed because the device was not paired. Run :

idevicepair
idevicepair pair

That should fix it.

Ideviceinstaller however keeps on spawning this error :

Could not start com.apple.mobile.installation_proxy!

At least if you have the other tools working you can get the syslog by running :

idevicesyslog
idevicesyslog

Then when you rerun ideviceinstaller -l you see :

output
Nov  7 09:24:07 iPhone notification_proxy[122] <Error>: 0x2dd000 -[MNPLockdownConnection receiveMessage]: lockdown_receive_message error!
Nov  7 09:24:12 iPhone mobile_installation_proxy[123] <Error>: Could not check in with lockdown at 'xpc': 1

Here is a comparison with the working version on power. Be cautious with that one, it is the ONLY installation that works !!

description power hoek
architecture intel amd
os ideviceinstaller libimobiledevice libusbmux-dev Debian 3.16.43-2+deb8u2 1.0.1-02+b1 1.1.6+dfsg-3.1 1.0.9-1 Debian 3.16.43-2+deb8u3

Could not start com.apple.mobile.installation_proxy!

Hoek and power now work, but laptop fail still. I reconstructed that i did this :

output
1
2
3
4
5
6
7
8
ideviceinstaller -l
Could not start com.apple.mobile.installation_proxy!
sudo apt-get install libimobiledevice-dev
ideviceinstaller -l
Could not start com.apple.mobile.installation_proxy!
sudo apt-get install ideviceinstaller
ideviceinstaller -l
Could not start com.apple.mobile.installation_proxy!

toplap does not respond to that even after a reboot. Also servert does not work. So i'm sad to say still no definite answer.

  • If i copy ideviceinstaller executable to laptop, it still won't work ! So it's not the executable.
  • ...

problems with android icon

If you get this error....

Error /home/kees/projects/registratie/registratie/platforms/android/build/intermediates/manifests/full/debug/AndroidManifest.xml:27: error: Error: No resource found that matches the given name (at 'icon' with value '@drawable/icon').

... it wants to get an icon from the res/drawable directory, however i had a directory structure with more specify drawable directories. drawable-land-hdpi, etc

I solved this by creating a drawable directory and putting my icon there.

icon
platforms/android/res/drawable/icon.png

Maybe this should all be automatically done, but how ?

visit

update 2017

Actually last time tried (August 2017) it worked to put a png file in :

icon
project/res/icon.png

And one line in config.xml

icon
<icon src="res/icon.png" />

This showed in the emulator as app icon. I did not try IOs etc.

Debug ios with emulator

This is much like the chrome development on linux/android. This would also be the one reason to buy a mac, since you could attach the actual phone there. For now we must use the emulator.

Just build the app like described before and run it in the emulator:

cordova run ios --emulator

Of course since we have no phone this will be enough

cordova run ios

Now startup safari, and enable the development menu : Go preferences -> advanced -> Show Develop menu in menu bar. Once you have done that, go Develop -> iPhone Simulator -> Your App Name.

There is your debugging, and all console.log messages for instance.

Autorotate for ios

It just does not work. This method can be used to circumvent :

After installing the platform there should be a file :

vi .platforms/ios/Registratie/Classes/MainViewController.m

Change the function shouldAutorotateToInterfaceOrientation

To :

auto rotate
1
2
3
4
5
6
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    // Return YES for supported orientations 
    -- return [super shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
    ++ return true; 
}

It works !

always timeout geolocation.watchPosition()

I fought with this for two days, no matter what you do there are coordinates in the browser but not in the device. One distracting factor here was that the emulator also gave no output. But that is because you need to set the coordinates by hand since it has no GPS.

The solution turned out to be : reboot

uninstalling apk

This is needed in some cases. First list the apps to find the name you want, and then remove it :

uninstalling
adb shell pm list packages
adb shell pm uninstall org.klopt.speelschema

Now you can install speelschema again without complaints

disable gpu acceleration

To disable hardware acceleration that (probably) caused my X server to crash when running 'cordova run browser', edit this file :

disable acceleration
vi ./cordova/node_modules/cordova-serve/src/browser.js

Edit the variable chromeArgs to contain --disable-gpu :

chromeArgs
var chromeArgs = ' --disable-gpu --user-data-dir=/tmp/' + dataDir;

Startup the cordova run browser and go to the three-stripe-menu -> settings -> Advanced and look at System -> "Use hardware acceleration when available".

It should now be off !

admob

admob support can be done using cordova-plugin-admobpro : visit

There is also an simpler version but it just does not compile. compile-plugin-admob. Every one on that site has the same problem and there is no one answering.

So use :

admob
cordova plugin add cordova-plugin-admobpro

Or visit the site for an explanation. The revenues can be seen on this page : Admob.

of course it does not start with much when you just view your own app.

android run specific target

If you have multiple android devices (like x86 and devices) you can choose to install or run on one of them, but the main problem is finding the names :

targets
cordova targets

Will list something like :

output
192.168.2.27:5555
X9LDU15430002750

Then take you pick, and run :

-target
cordova run android -target X9LDU15430002750

horrible black color jquery-mobile

The default theme is bollocks, use :

better theme
<body data-role="page" data-theme="b">

cannot find property 'x' of undefined

In jquery-mobile.

Where x is different all the time : 'fn', 'compact', .. more Mostly you have to match up jquery-mobile with a compatible jquery. See next chapter on how to best install jquery-mobile

cannot load ajax-loader.gif

Install jquery-mobile locally from a zipfile, because you need more than just the .js and .css files.

  • Download the latest stable zip file of jquery-mobile
  • unzip it into one directory : /jquery/
  • look what version of jquery is still compatible with this one, could go way back (1.11.1)
  • put that jquery.js or jquery.min.js in the same /jquery/ directory
  • reference all links and scripts to this local directory, then it get's reachable from android device etc without any downloads