Build your PhoneGap/Cordova app the Right Way

With PhoneGap/Cordova, the usual process is to use Cordova’s tools to generate a project for whatever platform, copy your files at the appropriate place, install native plugins, tweak the project and build.

This is fine but really suboptimal, especially when it comes to upgrading to the next version of PhoneGap or managing multiple platforms simultaneously (which is really the point about PhoneGap, isn’t it?). Yes, they do provide some upgrade scripts, but it’s still a pain: you have to upgrade all your platforms and doesn’t always work the way it should.

So why not do things The Right Way, ie. the other way round?

In my PhoneGap project, I maintain a single app/ folder where you find the javascript, css and html. No PhoneGap project at all. The build script then create (at build time) a PhoneGap project using the command line tools, install native plugins using plugman, copy my files to the right place for the targeted platform then build.

There are a few special case for each platform to take into account, especially the plugins to install.

I won’t leave you without some sugar, here is a build script for iOS (to be adjusted for your needs):

#!/bin/bash
 
    IOS_PROJECT_PATH="build/ios/$PROJECT_NAME"
    mkdir -p "$IOS_PROJECT_PATH"
    PLUGMAN="node_modules/.bin/plugman"
 
    # Create PhoneGap iOS Project
    "phonegap/lib/ios/bin/create" \
        --shared "$IOS_PROJECT_PATH" "$IOS_BUNDLE_ID" "$PROJECT_NAME"
 
    # Patch the XCode project (set our code signing identity)
    patch -l -p0 << EOF > /dev/null || error "Patch failed"
--- $IOS_PROJECT_PATH/$PROJECT_NAME.xcodeproj/project.pbxproj	2013-03-23 09:24:16.000000000 +0200
+++ $IOS_PROJECT_PATH/$PROJECT_NAME.xcodeproj/project.pbxproj	2013-03-23 11:28:31.000000000 +0200
@@ -530,7 +530,7 @@
            CLANG_WARN_ENUM_CONVERSION = YES;
            CLANG_WARN_INT_CONVERSION = YES;
            CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
-				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "$DEVELOPER_NAME";
            GCC_C_LANGUAGE_STANDARD = c99;
            GCC_THUMB_SUPPORT = NO;
            GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
@@ -556,6 +556,7 @@
                "-all_load",
                "-Obj-C",
            );
+				"PROVISIONING_PROFILE[sdk=iphoneos*]" = "$PROVISIONING_PROFILE_ID";
            SDKROOT = iphoneos;
            SKIP_INSTALL = NO;
            USER_HEADER_SEARCH_PATHS = "";
EOF
 
    cp "ios/Info.plist" "$IOS_PROJECT_PATH/$PROJECT_NAME/$PROJECT_NAME-Info.plist"
    cp "ios/config.xml" "$IOS_PROJECT_PATH/$PROJECT_NAME/config.xml"
 
    # Install Cordova Plugins.
    cd "build"
    mkdir -p "$IOS_PROJECT_PATH/cordova/plugins"
    "$PLUGMAN" --prepare --platform ios --project "$IOS_PROJECT_PATH"
 
    function plugmanInstall {
        pname="$1"
        ppath="$2"
        echo -n .
        "$PLUGMAN" --fetch --platform ios \
            --project "$IOS_PROJECT_PATH" \
            --plugin "$PROJECT_PATH/.downloads$ppath/$pname" \
        && "$PLUGMAN" --platform ios \
            --project "$IOS_PROJECT_PATH" \
            --plugin "$pname" \
        || error "Failed to install $pname plugman plugin"
    }
 
    plugmanInstall "TestflightPlugin"
    plugmanInstall "PhoneGap-SQLitePlugin-iOS"
    plugmanInstall "EmailComposerWithAttachments" "/phonegap-plugins/iOS"
 
    cd ..
 
    # Generate icons and splash screens.
    . "ios/generate-assets.sh"
 
    # Remove useless assets.
    rm -fr "www/res"
  
    # Install our files
    rsync -a build/www/ "$IOS_PROJECT_PATH/www"
 
    # Remove version number from cordova.js
    if test -e "$IOS_PROJECT_PATH/www/cordova-$PHONEGAP_VERSION.js"; then
        mv "$IOS_PROJECT_PATH/www/cordova-$PHONEGAP_VERSION.js" "$IOS_PROJECT_PATH/www/js/cordova.js"
    fi
  
    # Add project version into the info.plist file.
    if test -e /usr/libexec/PlistBuddy && test -e "$IOS_PROJECT_PATH/$PROJECT_NAME/$PROJECT_NAME-Info.plist"; then
        VERSION=`cat "VERSION"`
        /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $VERSION" "$IOS_PROJECT_PATH/$PROJECT_NAME/$PROJECT_NAME-Info.plist"
    fi
 
    # Build
    "$IOS_PROJECT_PATH/cordova/build"
fi

I’m a consultant and developer for Mobile, Web, Games and Apps projects. I co-founded Fovea 8 years ago.

Tagged with: ,
Posted in Blog