dpcunningham / process-spinup-devenv-ionic4-ng-on-linux

Process: Spin Up a Development Environment for Ionic 4 (default Angular) Apps
0 stars 0 forks source link

exercise 4: Build benchmark "Photo Gallery" app & deploy using DevApp & Ionic account #19

Open dpcunningham opened 4 years ago

dpcunningham commented 4 years ago

We will follow Ionic's benchmark exercise to build an introductory "photo gallery" app.

Note that all code referenced in this guide can be found on GitHub.... However, rather than just cloning the repo & blindly building it, itis better to follow the steps and understand the (broad amount of deep) topics required to build a mobile app using Ionic, such as:

For completeness' sake, we have a local repo of the code here as well...

Problems, solutions, notes, ideas & follow-ups listed below...

dpcunningham commented 4 years ago

Survey: WTF is our build situation?

$ node --version
v12.14.0
$ npm --version
6.13.4
$ java -version   # cuz Oracle java is a diva, & can't follow "mundane" argument SOPs
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)
$ javac -version
javac 1.8.0_231
$ gradle --version

------------------------------------------------------------
Gradle 5.2.1
------------------------------------------------------------

Build time:   2019-02-08 19:00:10 UTC
Revision:     f02764e074c32ee8851a4e1877dd1fea8ffb7183

Kotlin DSL:   1.1.3
Kotlin:       1.3.20
Groovy:       2.5.4
Ant:          Apache Ant(TM) version 1.9.13 compiled on July 10 2018
JVM:          1.8.0_231 (Oracle Corporation 25.231-b11)
OS:           Linux 4.15.0-47-generic amd64

$ ionic --version
5.4.13
$ cordova --version
9.0.0 (cordova-lib@9.0.1)

OK, let's go have some fun, shall we?

dpcunningham commented 4 years ago

Step 1/4: Create the Ionic app (dir tree structure)

$ pwd
/home/dpc/dpc.data/local.FS/lfs.00-Scratch/projects/ionic4.demos
$ ionic start photo-gallery tabs

The project builds out :+1: , but we also get a bunch of warnings :-1:. Sigh...

We will need to deal with those as a "follow-up" comment/issue:

...because: I am highly intolerant of shipping anything executable unless I understand why the build process generates warnings. Even if it's only a compiler issue, or a deprecated feature issue, or a version incompatibility issue. My personal bottom line is that I don't ship stuff until I understand WTF is going on. Neither should you.

We also get a request from git to configure our username:

    *** Please tell me who you are.

    Run

        git config --global user.email "you@example.com"
        git config --global user.name "Your Name"

    to set your account's default identity.
    Omit --global to set the identity only in this repository.

...that's easy-peazy to fix, so let's do that. & continue our build process

On a parallel track, the CLI output notes the following development resources:

dpcunningham commented 4 years ago

Serve the app & continue the exercise

Recap: we are on the first of four sections in this exercise.

We will use VS Code as the IDE/editor for this exercise.

dpcunningham commented 4 years ago

Add Cordova iOS and Android Platforms

We now more to section 2/4 of the Ionic benchmark app tutorial:

These commands will create a config.xml file, which is used to define Cordova iOS and Android settings. Cordova reads this file and applies each setting as it builds each native app binary.

To setup for iOS deployments, we run:

$ ionic cordova platform add ios

We get:

ionic integrations enable cordova [INFO] Downloading integration cordova [INFO] Copying integrations files to project CREATE resources CREATE resources/splash.png CREATE resources/ios [...] CREATE resources/README.md CREATE config.xml [OK] Integration cordova added! ✔ Creating ./www directory for you - done! cordova platform add ios Using cordova-fetch for cordova-ios@^5.0.0 Adding ios project... Creating Cordova project for the iOS platform: Path: platforms/ios Package: io.ionic.starter Name: MyApp iOS project created with cordova-ios@5.1.1 Plugin 'cordova-plugin-whitelist' found in config.xml... Migrating it to package.json [...] Plugin 'cordova-plugin-ionic-keyboard' found in config.xml... Migrating it to package.json Discovered saved plugin "cordova-plugin-whitelist". Adding it to the project Installing "cordova-plugin-whitelist" for ios Adding cordova-plugin-whitelist to package.json [...] Discovered saved plugin "cordova-plugin-ionic-keyboard". Adding it to the project Installing "cordova-plugin-ionic-keyboard" for ios Adding cordova-plugin-ionic-keyboard to package.json [WARN] cordova-res was not found on your PATH. Please install it globally: npm i -g cordova-res [WARN] Cannot generate resources without cordova-res installed. Once installed, you can generate resources with the following command: ionic cordova resources ios --force

We install the missing components to correct the build warning:

$ npm i -g cordova-res
npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules
[...]
npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'
[...]
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
[...]

We complete the installation of the component using proper privileges:

$ sudo npm i -g cordova-res
[sudo] password for dpc:                  
/usr/local/lib/nodejs/node-v10.16.3-linux-x64/bin/cordova-res -> /usr/local/lib/nodejs/node-v10.16.3-linux-x64/lib/node_modules/cordova-res/bin/cordova-res
+ cordova-res@0.8.1
updated 2 packages in 2.954s
$ ionic cordova platform add ios
Platform ios already exists.
$ ionic cordova resources ios --force
> cordova-res ios
[ERROR] cordova-res was not found on your PATH. Please install it globally:

        npm i -g cordova-res

OK... that's... confusing.

Let's research this path issue. I think my previous install of node/npm might be... "snarled":

$ which npm
/usr/local/bin/npm

$ ls -l /usr/local/bin/npm
lrwxrwxrwx 1 root root 38 Dec 17 18:15 /usr/local/bin/npm -> ../lib/node_modules/npm/bin/npm-cli.js

$ ls  -l /usr/local/bin
total 46312
-rwxr-xr-x 1 root root     6546 Feb  7  2019 apt
lrwxrwxrwx 1 root root       57 Dec 21 18:48 cordova -> /usr/local/lib/nodejs/node-v10.16.3-linux-x64/bin/cordova
-rwxr-xr-x 1 root root      504 Dec 12  2018 gnome-help
-rwxr-xr-x 1 root root      196 Feb  7  2019 highlight-mint
lrwxrwxrwx 1 root root       55 Dec 20 14:00 ionic -> /usr/local/lib/nodejs/node-v10.16.3-linux-x64/bin/ionic
-rwxr-xr-x 1 root root      243 Aug 30  2017 mint-sha256sum
-rwxr-xr-x 1 root root 45605784 Dec 17 18:15 node
lrwxrwxrwx 1 root root       38 Dec 17 18:15 npm -> ../lib/node_modules/npm/bin/npm-cli.js
lrwxrwxrwx 1 root root       38 Dec 17 18:15 npx -> ../lib/node_modules/npm/bin/npx-cli.js

$ ls  -l /usr/local/bin/cordova 
lrwxrwxrwx 1 root root 57 Dec 21 18:48 /usr/local/bin/cordova -> /usr/local/lib/nodejs/node-v10.16.3-linux-x64/bin/cordova

$ which cordova
/usr/local/bin/cordova
$ ls  -l /usr/local/bin/cordova 
lrwxrwxrwx 1 root root 57 Dec 21 18:48 /usr/local/bin/cordova -> /usr/local/lib/nodejs/node-v10.16.3-linux-x64/bin/cordova
y$ ls /usr/local/lib/nodejs/node-v10.16.3-linux-x64/bin/cordova
/usr/local/lib/nodejs/node-v10.16.3-linux-x64/bin/cordova

OK, let's try this as a fix:

$ ionic cordova resources ios --force
> cordova-res ios
[ERROR] cordova-res was not found on your PATH. Please install it globally:

        npm i -g cordova-res

$ echo $PATH
/home/dpc/.local/bin:/usr/lib/jvm/jdk1.8.0_231/bin:/opt/gradle/bin:/home/dpc/Android/Sdk/bin:/home/dpc/Android/Sdk/tools:/home/dpc/Android/Sdk/platform-tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
$ export PATH=/usr/local/lib/nodejs/node-v10.16.3-linux-x64/bin/:$PATH
$ echo $PATH
/usr/local/lib/nodejs/node-v10.16.3-linux-x64/bin/:/home/dpc/.local/bin:/usr/lib/jvm/jdk1.8.0_231/bin:/opt/gradle/bin:/home/dpc/Android/Sdk/bin:/home/dpc/Android/Sdk/tools:/home/dpc/Android/Sdk/platform-tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
$ ionic cordova resources ios --force
> cordova-res ios
[cordova-res] Generated 50 resources for ios
[cordova-res] Wrote to config.xml

Well. That was a PITA. We"ll have to come back to this & resolve it as a configuration issue.

To setup for Android deployments, we run:

ionic cordova platform add android

We get:

cordova platform add android Using cordova-fetch for cordova-android@^8.0.0 Adding android project... Creating Cordova project for the Android platform: Path: platforms/android Package: io.ionic.starter Name: MyApp Activity: MainActivity Android target: android-28 Subproject Path: CordovaLib Subproject Path: app Android project created with cordova-android@8.1.0 Installing "cordova-plugin-device" for android Installing "cordova-plugin-ionic-keyboard" for android Installing "cordova-plugin-ionic-webview" for android Subproject Path: CordovaLib Subproject Path: app Installing "cordova-plugin-splashscreen" for android Installing "cordova-plugin-statusbar" for android Installing "cordova-plugin-whitelist" for android This plugin is only applicable for versions of cordova-android greater than 4.0. If you have a previous platform version, you do not need this plugin since the whitelist will be built in. ionic cordova resources android --force cordova-res android [cordova-res] Generated 18 resources for android [cordova-res] Wrote to config.xml

A pleasant surprise! Probably because of grinding through all the previous Android build issues.

dpcunningham commented 4 years ago

Step 2/4: Enable DevApp deployments onto iOS & Android devices

We continue with section 2/4 of the Ionic benchmark app tutorial:

To run your app on DevApp, you will first need to add a reference to cordova.js in your index.html file. Open up the file at src/index.html and add the following tag into the head section:

    <head>
      <!-- ... Other HTML tags... -->

      <script src="cordova.js"></script>
    </head>

Note: Usually, building the app with Cordova will add this script tag into the index.html file for us. Since we are skipping that step and using DevApp instead, we have to do it manually ourselves.

We will skip the normal steps required to configure iOS and Android native tooling -- for example:

Fortunately, Ionic provides a way to bypass the frustration of dealing with native SDK tooling: Ionic DevApp! The Ionic DevApp is a free app that makes it easy to run your Ionic app directly on your iOS or Android device.

  1. Download it from one of the app stores, then open it on your device:
  2. Next, sign into your Ionic account.
  3. Follow the steps in DevApp.
    • I had one minor issue, b/c I run multiple WiFi networks.
    • But once I had both my server/host and the iPhone on the same WiFi, the auto-detection and display worked just dandy.
    • It's always nice to see an immediate deployment onto an iPhone from a nom-Mac platform, even if you know that you will eventually need to deploy the whole Mac-based hardware, OS, IDE, etc.
  4. Et, Voila!

Here we are on iOS:

ionic app on iOS

And here we are on Android:

ionic app on android

dpcunningham commented 4 years ago

Add camera components and functionality

We continue with section 2/4 of the Ionic benchmark app tutorial:

We:

  1. Add the camera button
  2. Add the Camera Dependencies via the CLI

$ sudo npm install @ionic-native/camera

npm WARN karma-jasmine-html-reporter@1.5.1 requires a peer of jasmine-core@>=3.5 but none is installed. You must install peer dependencies yourself. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.11 (node_modules/webpack-dev-server/node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.11: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) [...] npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

found 3 moderate severity vulnerabilities run npm audit fix to fix them, or npm audit for details

$ ionic cordova plugin add cordova-plugin-camera

cordova plugin add cordova-plugin-camera Installing "cordova-plugin-camera" for android Subproject Path: CordovaLib Subproject Path: app Installing "cordova-plugin-camera" for ios Adding cordova-plugin-camera to package.json

  1. Edit config.xml for iOS 10 device (camera) access

  2. Add Camera plugin to Angular App Module

    • NB! As written, the code in the guide:

      {provide: ErrorHandler, useClass: IonicErrorHandler}

      • ...will fail.
    • Compared to the code in the current GutHub repo:

      { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }

      • ...which will work.
    • This should be resolved with Ionic support staff.

  3. Add the Camera to the Gallery page

dpcunningham commented 4 years ago

Test the camera functionality (w/ partial failures)

The bug issue around incorrect code (in the comment above) caused the infamous IWOD (Ionic Whitescreen of Death). Resolving that bug was a touch & go game "duh -- guess here" involving multiple app restarts. No dynamic reloading will fix your problem here, amigos.

In other words, experimentation with the auto-update feature of ionic serve coupled with DevApp performed... poorly. Complete restarts of DevApp (after code changes to troubleshoot the bug by comparing the documented steps to what was actually checked into the Ionic project repo) were required.

There may also have been permission problems with iOS preventing camera access. Again, multiple source code comparisons, (re)edits to bring code into exact alignment, and complete restarts finally solved these problems.

The "breakthrough" came from testing on Android, where we finally did realize that camera access was working -- after dealing with the combinatorics of troubleshooting in all the steps previously mentioned.

Further testing on iOS exhibited reasonable behavior:

  1. Meaning that pressing "OK" to save the image to the page:

test app ios 1

  1. ...worked as anticipated:

test app ios 2

However, on Android,

  1. Pressing the OK button:

test app android 1

  1. ...causes the app to hard-fail:

test app android 2

Conclusion: We will need to spin-up on debugging methods ASAP!

dpcunningham commented 4 years ago

Test: Is the code listed in the exercise up-to-date?

Given the results in the comments above, I will test if there are other code-related issues that might be contributing to the the hard-failure on Android. We'll just walk through the file changes listed in the exercise, and make sure our local code is in-line with what's on Ionic's repo...

Hmmm... there's a faster way to test this. Let's just clone & build their repo, and see what our results are...

...OK. Their current codebase in their repo fails on Android as well. Gonna need to get on the phone with these guys...

Good to know we're not complete dummies. We can at least continue on with the exercise...

dpcunningham commented 4 years ago

Step 3/4: Add photo storage into the app

We now move on to section 3/4 of the Ionic benchmark app tutorial:

We will:

  1. Create a PhotoService class in a dedicated "services" folder
  2. Add the Ionic Storage plugin

$ ionic g service services/Photo

ng generate service services/Photo CREATE src/app/services/photo.service.spec.ts (328 bytes) CREATE src/app/services/photo.service.ts (134 bytes) [OK] Generated service!

...and we now make the edits...

NB: This section in the tutorial is very imprecise, and needs rework:

Next, move all code pertaining to the Camera plugin to the PhotoService class. This includes the takePicture method, the Camera and CameraOptions imports, and the Tab2Page page constructor.

dpcunningham commented 4 years ago

Deal w/ config.xml errors from the exercise instructions

As you follow the exercise, you are told to:

$ ionic cordova plugin add cordova-sqlite-storage

[ERROR] Cannot load Cordova config.

  Error: Cannot parse config.xml file: Error: Text data outside of root node.
  Line: 114
  Column: 13

[...stack trace follows...]

This is caused by the additions in the config.xml file called for in the tutorial to allow iOS camera use, namely:

<!-- Required for iOS 10: Camera permission prompt -->
<edit-config file="*-Info.plist" mode="merge" target="NSCameraUsageDescription">
    <string>Used to take pictures</string>
</edit-config>

Temporarily deleting these lines, we re-run the command:

$ ionic cordova plugin add cordova-sqlite-storage

cordova plugin add cordova-sqlite-storage Installing "cordova-sqlite-storage" for android installing external dependencies via npm for package name: cordova-sqlite-storage npm install of external dependencies ok Installing "cordova-sqlite-storage" for ios installing external dependencies via npm for package name: cordova-sqlite-storage npm install of external dependencies ok Adding cordova-sqlite-storage to package.json

...without a lot of BS.

FFS! This tutorial needs serious re-work.

Previously, I thought I had broken my build environment (opened & close and entire issue), and spent a shitload of time re-configuring things.

Ionic should be able to do better than this.

dpcunningham commented 4 years ago

Resolve: The examples that DO work do NOT comply with spec!

First of all, because on Android, the app just fails.

Next, on iOS, the tutorial spec calls for a two-column display, and the code in tab2.page.html looks like this:

<ion-grid>
    <ion-row>
      <ion-col size="6" *ngFor="let photo of photoService.photos">
        <img [src]="photo.data" />
      </ion-col>
    </ion-row>
  </ion-grid>

And displays -- to spec -- like this:

tutorial 2-col per-spec

On the other hand, the code in the official repo looks like this:

  <ion-grid>
    <ion-row>
    <ion-col col-6 *ngFor="let photo of photoService.photos">
        <img [src]="photo.data" />
        </ion-col>
    </ion-row>
  </ion-grid>

...and displays like this (which ain't to spec, and looks goofy as hell):

tutorial N-col non-spec

dpcunningham commented 4 years ago

Step 4/4: Theme the App

We continue with section 4/4 of the Ionic benchmark app tutorial:

Per the walk-thru, we'll play around with: src/theme/variables.scss

We can make use of the handy Ionic Color Generator Tool...

NB: It looks like the recommended code change (to experiment w/ Android MD styling):

imports: [
    BrowserModule,
    IonicModule.forRoot({
      mode: "md"
    }),
    IonicStorageModule.forRoot()
  ],

...is incorrect. Perhaps this is old/crufty code & syntax has changed?

Perhaps the Ionic dev team should look at this as well?