Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Setting up your development environment for the Moodle App: Difference between revisions

From MoodleDocs
No edit summary
mNo edit summary
(13 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{Moodle Mobile}}
{{Moodle Mobile}}
{{Moodle Mobile 3.5}}
Note: These instructions do work (give or take) for the current 3.5.x version of the Moodle Mobile app.


== Overview ==
== Overview ==
Line 23: Line 26:
For Mac users we recommend to install NodeJS via Macports.
For Mac users we recommend to install NodeJS via Macports.


Node 6.9.1 has been verified to work fine with the app. If you're having problems with later versions you might want to check if it works with 6.9.1.
On Ubuntu you may be best off installing Node via [https://github.com/creationix/nvm nvm] - this lets you switch Node versions, and makes the install a bit easier than the official installation route.
 
"note": if you also need later versions of node for other projects, use Node Version Manager aka "nvm" [https://github.com/creationix/nvm here]. Linux and OSX is supported, and the site has pointers to windows alternatives. Simply type:
  nvm install 6.9.1
  nvm use 6.9.1


'''Install ionic:'''  
'''Install ionic:'''  
Line 55: Line 54:
== Clone the app base code ==
== Clone the app base code ==


'''Clone the code base into a local directory in your computer.'''
Clone the code base into a local directory in your computer.
It may be an idea to work from the integration branch rather than master.
  git clone https://github.com/moodlehq/moodlemobile2.git moodlemobiledirectory
  git clone https://github.com/moodlehq/moodlemobile2.git moodlemobiledirectory
  cd moodlemobiledirectory
  cd moodlemobiledirectory
  git checkout v3.5.0
  git checkout integration


== Setup the environment ==
== Setup the environment ==
Line 85: Line 85:
Update project platforms:
Update project platforms:


  ionic platform remove android
  ionic cordova platform remove android
  ionic platform remove ios
  ionic cordova platform remove ios
  ionic platform add android
  ionic cordova platform add android
  ionic platform add ios
  ionic cordova platform add ios


== Updating plugins ==
== Updating plugins ==
Line 97: Line 97:
== Building for Android and iOS ==
== Building for Android and iOS ==


Please see this guide to be able to build for Android and iOS using the command line:
Please see the guides below to be able to build for Android and iOS using the command line:


http://cordova.apache.org/docs/en/5.0.0/guide_platforms_index.md.html#Platform%20Guides
Android: https://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html
 
iOS: https://cordova.apache.org/docs/en/latest/guide/platforms/ios/index.html
 
If the build fails, please run <code>cordova requirements</code> to check that you fulfilled all requirements for the platform.


If you get errors while building, please see the Troubleshooting section below.
If you get errors while building, please see the Troubleshooting section below.
If using '''Ubuntu''' you should install the packages: gradle and libgradle-android-plugin-java (and all its dependencies) to build.
== Compiling using AOT ==
Angular has 2 ways of compiling: JIT and AOT. Running "ionic serve" or "ionic build" compiles using JIT by default, which is faster to compile but the app takes longer to start.
When building for release you should always compile using AOT, otherwise the app can take too long to start in some devices. The default AOT compiling causes some issues with the database activity and the [[Mobile support for plugins]], so you have to modify a couple of files in order to make this work.
First you need to open the file: ''node_modules/@angular/platform-browser-dynamic/esm5/platform-browser-dynamic.js''. Search the variable called "''_NO_RESOURCE_LOADER''", you'll see it has a function named "''get''" with this line:
<code javascript>
throw new Error("No ResourceLoader implementation has been provided. Can't read the url \"" + url + "\"");</code>
Remove that line and put this code instead:
<code javascript>
        url = 'templates/' + url;
        var resolve;
        var reject;
        var promise = new Promise(function (res, rej) {
            resolve = res;
            reject = rej;
        });
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.responseType = 'text';
        xhr.onload = function () {
            // responseText is the old-school way of retrieving response (supported by IE8 & 9)
            // response/responseType properties were introduced in ResourceLoader Level2 spec (supported by IE10)
            var response = xhr.response || xhr.responseText;
            // normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
            var status = xhr.status === 1223 ? 204 : xhr.status;
            // fix status code when it is 0 (0 status is undocumented).
            // Occurs when accessing file resources or on Android 4.1 stock browser
            // while retrieving files from application cache.
            if (status === 0) {
                status = response ? 200 : 0;
            }
            if (200 <= status && status <= 300) {
                resolve(response);
            }
            else {
                reject("Failed to load " + url);
            }
        };
        xhr.onerror = function () { reject("Failed to load " + url); };
        xhr.send();
        return promise;
</code>
We tried to replace the default loader with our own implementation, but we weren't able to make the compiler work so the only solution left was to modify the default one.
Now you need to open the file: ''node_modules/@ionic/app-scripts/dist/util/config.js''. In that file you need to remove the ''context.isProd'' condition from the options ''runMinifyJs'' and ''optimizeJs''. So the final code for that part should be like this:
<code javascript>
    context.runMinifyJs = [
        context.runMinifyJs,
        hasArg('--minifyJs')
    ].find(function (val) { return typeof val === 'boolean'; });
    context.runMinifyCss = [
        context.runMinifyCss,
        context.isProd || hasArg('--minifyCss')
    ].find(function (val) { return typeof val === 'boolean'; });
    context.optimizeJs = [
        context.optimizeJs,
        hasArg('--optimizeJs')
    ].find(function (val) { return typeof val === 'boolean'; });
</code>
We want to compile in production mode but without optimizing and minifying Javascript because that breaks our plugins support. However, Ionic doesn't let you do that, so the only option is to do this change.
With these changes done you can now compile using production mode:
<code php>
npm run ionic:build -- --prod</code>
This command will generate the app files and put them inside ''www'' folder. If you now want to install that app in a real device you can run "''cordova run android''" or "''cordova build ios''" (please don't use "''ionic cordova ...''" or "''ionic serve''" because it will override your build files!).


== Troubleshooting ==
== Troubleshooting ==
Line 141: Line 224:
     buildToolsVersion "26.0.1"
     buildToolsVersion "26.0.1"
  }
  }
=== Error: Could not find gradle wrapper within Android SDK. Might need to update your Android SDK.  ===
1. Download Android studio - https://developer.android.com/studio/
2. Copy the folder android-studio/plugins/android/lib/templates
3. Paste in the folder android-sdk-folder/Sdk/tools
=== Could not find com.android.support:support-v4:27.1.0 ===
Open the file ''platforms/android/build.gradle'' and configure like this:
  allprojects {
      repositories {
          jcenter()
          maven {
              url "https://maven.google.com"
          }
      }
  }
=== Error: not found: make ===
If you see this error in Ubuntu, run <tt>sudo apt-get install build-essential</tt> and retry.
=== Current working directory is not a Cordova-based project. ===
If you see this error during <tt>npm setup</tt>, run <tt>mkdir www</tt> and retry.
=== ReferenceError: internalBinding is not defined ===
This [https://stackoverflow.com/questions/53146394/node-app-fails-to-run-on-mojave-referenceerror-internalbinding-is-not-defined seems to be] an error with 'natives' prior to 1.1.6. I fixed it using <tt>npm install natives@1.1.6</tt>.


== See also ==
== See also ==


http://ionicframework.com/docs/cli/
http://ionicframework.com/docs/cli/

Revision as of 11:33, 8 March 2019

This template is unused and can be deleted.

Note: These instructions do work (give or take) for the current 3.5.x version of the Moodle Mobile app.

Overview

The majority of your development work will be done using the browser. You will likely begin to use an emulator once you need to simulate a real mobile device.

Remember that the majority of your development can be done using the online version https://mobileapp.moodledemo.net/ (requires Chrome or Chromium browser) as indicated in Mobile support for plugins

Requirements

Install a browser for development

We recommend Chromium browser (Google Chrome open source version) https://download-chromium.appspot.com/ Please, read Moodle_Mobile_development_using_Chrome_or_Chromium for more information

Install git

https://git-scm.com/book/en/v2/Getting-Started-Installing-Git

Install Node.js

http://nodejs.org

For Mac users we recommend to install NodeJS via Macports.

On Ubuntu you may be best off installing Node via nvm - this lets you switch Node versions, and makes the install a bit easier than the official installation route.

Install ionic:

npm cache clean
npm install -g cordova ionic    # (If it throws an EACCESS error, run it again with sudo)

Install the npm required packages

sudo npm install -g gulp                      # (This will install gulp in a folder that should be in the PATH)

Native build dependencies for Windows

node-gyp requires native build tools for your platform. If you're developing on Mac or Linux, you'll probably have these already (refer to the docs if not), on Windows, run the following command as administrator (in cmd or Powershell):

npm install --global --production windows-build-tools

Push notifications for Mac

Phonegap plugin push 1.9.0 requires CocoaPods to work. The installation steps can be found in https://cocoapods.org/

E.g. in Mac OS X you have to run:

sudo gem install cocoapods
pod setup

Please note that for compiling the app in Mac you need to open the .xcworkspace file, more information here: MOBILE-1970

Clone the app base code

Clone the code base into a local directory in your computer. It may be an idea to work from the integration branch rather than master.

git clone https://github.com/moodlehq/moodlemobile2.git moodlemobiledirectory
cd moodlemobiledirectory
git checkout integration

Setup the environment

Please, note that if you are creating a custom app with a custom URL scheme, you should edit the /package.json and /config.xml files and specify there your custom URL_SCHEME (replacing the existing value) and your GCMPN SENDER_ID.

The following command must be run in the project's root folder:

npm run setup

Open the app in the browser

First start Chromium via the command line using the custom parameters as is mentioned here: Moodle Mobile development using Chrome or Chromium

and then, start the Ionic server:

ionic serve --browser chromium

If you don't want to open any browser you should run:

ionic serve -b

Updating ionic and cordova

sudo npm update -g cordova
sudo npm update -g ionic

Update project platforms:

ionic cordova platform remove android
ionic cordova platform remove ios
ionic cordova platform add android
ionic cordova platform add ios

Updating plugins

cordova plugin remove your_plugin_id
cordova plugin add your_plugin_id

Building for Android and iOS

Please see the guides below to be able to build for Android and iOS using the command line:

Android: https://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html

iOS: https://cordova.apache.org/docs/en/latest/guide/platforms/ios/index.html

If the build fails, please run cordova requirements to check that you fulfilled all requirements for the platform.

If you get errors while building, please see the Troubleshooting section below.

If using Ubuntu you should install the packages: gradle and libgradle-android-plugin-java (and all its dependencies) to build.

Compiling using AOT

Angular has 2 ways of compiling: JIT and AOT. Running "ionic serve" or "ionic build" compiles using JIT by default, which is faster to compile but the app takes longer to start.

When building for release you should always compile using AOT, otherwise the app can take too long to start in some devices. The default AOT compiling causes some issues with the database activity and the Mobile support for plugins, so you have to modify a couple of files in order to make this work.

First you need to open the file: node_modules/@angular/platform-browser-dynamic/esm5/platform-browser-dynamic.js. Search the variable called "_NO_RESOURCE_LOADER", you'll see it has a function named "get" with this line:

throw new Error("No ResourceLoader implementation has been provided. Can't read the url \"" + url + "\"");

Remove that line and put this code instead:

       url = 'templates/' + url;
       var resolve;
       var reject;
       var promise = new Promise(function (res, rej) {
           resolve = res;
           reject = rej;
       });
       var xhr = new XMLHttpRequest();
       xhr.open('GET', url, true);
       xhr.responseType = 'text';
       xhr.onload = function () {
           // responseText is the old-school way of retrieving response (supported by IE8 & 9)
           // response/responseType properties were introduced in ResourceLoader Level2 spec (supported by IE10)
           var response = xhr.response || xhr.responseText;
           // normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
           var status = xhr.status === 1223 ? 204 : xhr.status;
           // fix status code when it is 0 (0 status is undocumented).
           // Occurs when accessing file resources or on Android 4.1 stock browser
           // while retrieving files from application cache.
           if (status === 0) {
               status = response ? 200 : 0;
           }
           if (200 <= status && status <= 300) {
               resolve(response);
           }
           else {
               reject("Failed to load " + url);
           }
       };
       xhr.onerror = function () { reject("Failed to load " + url); };
       xhr.send();
       return promise;

We tried to replace the default loader with our own implementation, but we weren't able to make the compiler work so the only solution left was to modify the default one.

Now you need to open the file: node_modules/@ionic/app-scripts/dist/util/config.js. In that file you need to remove the context.isProd condition from the options runMinifyJs and optimizeJs. So the final code for that part should be like this:

   context.runMinifyJs = [
       context.runMinifyJs,
       hasArg('--minifyJs')
   ].find(function (val) { return typeof val === 'boolean'; });
   context.runMinifyCss = [
       context.runMinifyCss,
       context.isProd || hasArg('--minifyCss')
   ].find(function (val) { return typeof val === 'boolean'; });
   context.optimizeJs = [
       context.optimizeJs,
       hasArg('--optimizeJs')
   ].find(function (val) { return typeof val === 'boolean'; });

We want to compile in production mode but without optimizing and minifying Javascript because that breaks our plugins support. However, Ionic doesn't let you do that, so the only option is to do this change.

With these changes done you can now compile using production mode:

npm run ionic:build -- --prod

This command will generate the app files and put them inside www folder. If you now want to install that app in a real device you can run "cordova run android" or "cordova build ios" (please don't use "ionic cordova ..." or "ionic serve" because it will override your build files!).

Troubleshooting

Error: libsass bindings not found. Try reinstalling node-sass?

Please read: http://fettblog.eu/gulp-and-node4-first-aid/, alternatively you must be sure that you installed Node v0.12

node-gyp\src\win_delay_load_hook.c(34): error C2373: '__pfnDliNotifyHook2': redefinition; different type modifiers

Try updating npm to the latest version using:

 npm install -g npm@latest


com.android.dex.DexException: Multiple dex files define XXX

Open the file platforms/android/build.gradle and add this code at the end:

 configurations {
     all*.exclude group: 'com.android.support', module: 'support-v4'
 }

Could not resolve all dependencies for configuration ':_debugCompile'.

Open the Android SDK Manager and make sure you have installed: Android Support Repository, Android Support Library, Google Play Services and Google Repository.

Could not find com.android.support:support-v4:XXX

Open the file platforms/android/build.gradle and add this code at the end:

 configurations.all {
     resolutionStrategy.force 'com.android.support:support-v4:24.0.0'
 }

ERROR: In <declare-styleable> FontFamilyFont, unable to find attribute android:font

Open the file platforms/android/build.gradle and add this code at the end:

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.1"
}

Error: Could not find gradle wrapper within Android SDK. Might need to update your Android SDK.

1. Download Android studio - https://developer.android.com/studio/

2. Copy the folder android-studio/plugins/android/lib/templates

3. Paste in the folder android-sdk-folder/Sdk/tools

Could not find com.android.support:support-v4:27.1.0

Open the file platforms/android/build.gradle and configure like this:

 allprojects {
     repositories {
         jcenter()
         maven {
             url "https://maven.google.com"
         }
     }
 }

Error: not found: make

If you see this error in Ubuntu, run sudo apt-get install build-essential and retry.

Current working directory is not a Cordova-based project.

If you see this error during npm setup, run mkdir www and retry.

ReferenceError: internalBinding is not defined

This seems to be an error with 'natives' prior to 1.1.6. I fixed it using npm install natives@1.1.6.

See also

http://ionicframework.com/docs/cli/