I recently started a Capacitor based Ionic project. After years of working with Cordova, the framework initally felt jarring. However, with even a bit of use, I'm already buying into Capacitor's benefits. The Cordova approach of generating Android and iOS projects often worked great, but at times the approach showed itself to be quite fragile. Something would change in the iOS world and you'd be at the mercy of Cordova to update the build process to catch up with this. Not so with Capacitor, which embraces the notion of working directly on Android and iOS native projects.
I do however miss a number of nicities that Cordova offered. Take versioning. It seems obvious that there would be a central location where your project's version number was set and the iOS and Android apps pulled from this. And yet, this isn't the case with Capacitor. The thought of having to launch two different IDE's to manually change the app's version number seems like a recipe for disaster.
Speaking of launching IDE's, the thought of giving up command line building and running of apps is another step backwards.
Fortunately, with a bit of shell scripting the versionining and building challenge for Android can be addressed. Building from the command line on iOS is possible but it will take a bit more research befor I get it figured out. I added this functionality to my ionicassist command line tool. It's now possible to say:
ionicassist android-cap ionicassist ios-cap
To push the version number found in capacitor.config.json to both Android and iOS and build and install the Android project from the command line. The source code for ionicassist is below. Most of the code is straightfoward, though dealing with the ridiculous Info.plist format took some work. xmlstarlet and jq both proved invaluable for this little project.
#!/bin/bash ## ## Scrip to help with ionic dev ## action=$1 ; shift case $(uname) in Darwin) PLATFORM_TOOLS=$HOME/Library/Android/sdk/platform-tools/ APK_DEST="$HOME/Google Drive (ben@ideas2executables.com)/Clients/Uchi/APKs/" ;; CYGWIN_NT-10.0) PLATFORM_TOOLS=/d/tools/android/platform-tools/ APK_DEST="/d/Google_Drive_i2x/Clients/Uchi/APKs/" ;; esac ADB=$PLATFORM_TOOLS/adb case "$action" in grab-apk) name=$(xmlstarlet sel -N x=http://www.w3.org/ns/widgets -t -v '/x:widget/x:name' config.xml | sed 's/[^A-Za-z0-9_-]//g') version=$(xmlstarlet sel -N x=http://www.w3.org/ns/widgets -t -v '/x:widget/@version' config.xml) cp -v platforms/android/app/build/outputs/apk/debug/app-debug.apk "$APK_DEST/$name-$version.apk" ;; grab-release-apk) name=$(xmlstarlet sel -N x=http://www.w3.org/ns/widgets -t -v '/x:widget/x:name' config.xml | sed 's/[^A-Za-z0-9_-]//g') version=$(xmlstarlet sel -N x=http://www.w3.org/ns/widgets -t -v '/x:widget/@version' config.xml) cp -v platforms/android/app/build/outputs/apk/release/app-release.apk "$APK_DEST/$name-$version.apk" ;; screencap) if [ -z "$1" ] ; then echo "Usage: $(basename $0) screencap {file}" exit else file=$1 ; shift $ADB shell screencap /sdcard/screen.png $ADB pull /sdcard/screen.png $file fi ;; screenrec) if [ -z "$1" -o -z "$2" ] ; then echo "Usage: $(basename $0) screencap {file} {duration}" exit else file=$1 ; shift duration=$1 ; shift $ADB shell screenrecord --verbose --time-limit $duration /sdcard/screen.mp4 $ADB pull /sdcard/screen.mp4 $file fi ;; adb) exec $ADB "$@" ;; sync-cap) cap_conf=capacitor.config.json and_conf=android/app/build.gradle ios_conf=ios/App/App/Info.plist if [ -f "$cap_conf" ] ; then version_name=$(cat $cap_conf | jq -r .appVersion) version_code=$(cat $cap_conf | jq -r .appVersionCode) if [ -f "$and_conf" ] ; then mv $and_conf $and_conf.prev sed -e "s/versionCode .*/versionCode $version_code/" \ -e "s/versionName .*/versionName \"$version_name\"/" \ < $and_conf.prev > $and_conf rm $and_conf.prev else echo "Android: $and_conf not found, skipping" fi if [ -f "$ios_conf" ] ; then mv $ios_conf $ios_conf.prev xmlstarlet ed -u '/plist/dict/key[text() = "CFBundleShortVersionString"]/following-sibling::string[1]' \ -v $version_name $ios_conf.prev > $ios_conf mv $ios_conf $ios_conf.prev xmlstarlet ed -u '/plist/dict/key[text() = "CFBundleVersion"]/following-sibling::string[1]' \ -v $version_name $ios_conf.prev > $ios_conf rm $ios_conf.prev else echo "iOS: $ios_conf missing, skipping" fi else echo "$cap_conf not found. Giving up." exit fi ;; android-cap) cap_conf=capacitor.config.json if [ -f $cap_conf ] ; then app_pkg=$(cat $cap_conf | jq -r .appId) ionic cap copy ionicassist sync-cap cd android ; ./gradlew installDebug $ADB shell monkey -p $app_pkg 1 else echo "$cap_conf not found. Giving up"; fi ;; ios-cap) ionic cap copy ionicassist sync-cap ionic cap open ios ;; *) echo "Usage: $(basename $0) {grab-apk|grab-release-apk|screencap|adb|sync-cap|android-cap}" exit 1 ;; esac
No comments:
Post a Comment