LoginSignup
24
19

More than 5 years have passed since last update.

CordovaでversionCodeやCFBundleVersionは何になる?

Last updated at Posted at 2015-10-22

最近、IonicでCordova始めました。
いろいろと触ってみてますが、小綺麗なCSSフレームワークが用意されていると、細かい調整をしなくてもなんとなくそれっぽくなるので、結構好きです。

本記事では、バージョン命名をCordovaで運用するときに直感的ではない動きをするところがあったので、調べて分かったことを備忘録がてら紹介します。

読むの面倒くさい人向けのまとめ

  • config.xmlのversionにsemver形式のバージョンを指定できる
  • versionCodeやCFBundleVersionはバージョンから自動生成される
  • versionCodeを自動生成に任せると、1のケタに不思議な数字が入るので気をつけろ
  • 自分で指定するオプションもあるので自動生成が気に食わない場合はそちらを使おう

confix.xmlのversionは何を表す

少し話がそれましたが、モバイルアプリケーションでもバージョンを表すパラメータがあります。以下の記事が詳しいです。

Cordovaのconfig.xmlにも、このバージョンを記述するための場所があります。

config.xml
<widget
   id="com.example.my-app"
   version="0.1.0"
   xmlns="http://www.w3.org/ns/widgets"
   xmlns:cdv="http://cordova.apache.org/ns/1.0">

このversionに指定したものが、AndroidのversionNameとiOSのCFBundleShortVersionStringになります。

では、versionCodeやCFBundleVersionはどのように指定するのでしょうか?

一応、指定しなくても動くようになっています。一度ビルドした後の、各設定を見てみると、このようになっています。

スクリーンショット_2015-10-20_10_51_33.png

スクリーンショット_2015-10-20_10_38_00.png

このへんのルールについては公式リファレンスに記述がある通り、

  • AndroidのversionCodeはversionNameがX.Y.Zであることを前提にして、PATCH + MINOR * 100 + MAJOR * 10000
  • iOSのCFBundleVersionはCFBundleShortVersionStringと同じ

になるようです。

ふーん。Androidに関して言えば、よくある生成ルールじゃん。

と思っていたのですが。

versionCodeの生成規則が変

最終的に採用されるであろう、BuildConfig.xmlで設定されているversionCodeを見てみましょう。

platforms/android/build/generated/source/buildConfig/debug/com/example/my_app/BuildConfig.java
package com.example.my_app;

public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String APPLICATION_ID = "com.example.my_app";
  public static final String BUILD_TYPE = "debug";
  public static final String FLAVOR = "";
  public static final int VERSION_CODE = 1008;
  public static final String VERSION_NAME = "";
}

期待していた値と違いますね。0 + 1 * 100 + 0 * 10000、つまり100になることを期待していたのですが、右側に1ケタ多くなっています。

まだ慌てる時間ではありません。AndroidManifest.xmlには100と書いてあるのですから、きっとPlayストアに上げれば100として表示されるかもしれません。

スクリーンショット_2015-10-20_11_47_35.png

1008でした。どうやらこの値で決まりのようです。

何故ケタが変わったのでしょうか。何故8が入ったのでしょうか。

アーキテクチャやバージョンによって変わる1の桁

一度AndroidManifest.xmlに書かれた内容を覆せるやつなんて限られています。そう、build.gradleです。Cordovaプロジェクトが用意しているAndroidアプリのテンプレートがそのまま取り込まれたものということで、なにかやっていないかチェックしてみましょう。

platforms/android/build.gradle
android {
    // 略
    defaultConfig {
        versionCode cdvVersionCode ?: Integer.parseInt("" + privateHelpers.extractIntFromManifest("versionCode") + "0")
        if (cdvMinSdkVersion != null) {
            minSdkVersion cdvMinSdkVersion
        }
    }
    // 略
    if (Boolean.valueOf(cdvBuildMultipleApks)) {
        productFlavors {
            armv7 {
                versionCode cdvVersionCode ?: defaultConfig.versionCode + 2
                ndk {
                    abiFilters "armeabi-v7a", ""
                }
            }
            x86 {
                versionCode cdvVersionCode ?: defaultConfig.versionCode + 4
                ndk {
                    abiFilters "x86", ""
                }
            }
            all {
                ndk {
                    abiFilters "all", ""
                }
            }
        }
    } else if (!cdvVersionCode) {
      def minSdkVersion = cdvMinSdkVersion ?: privateHelpers.extractIntFromManifest("minSdkVersion")
      // Vary versionCode by the two most common API levels:
      // 14 is ICS, which is the lowest API level for many apps.
      // 20 is Lollipop, which is the lowest API level for the updatable system webview.
      if (minSdkVersion >= 20) {
        defaultConfig.versionCode += 9
      } else if (minSdkVersion >= 14) {
        defaultConfig.versionCode += 8
      }
    }
// 略

簡単に解説すると、

versionCode cdvVersionCode ?: Integer.parseInt("" + privateHelpers.extractIntFromManifest("versionCode") + "0")

↑でversionCodeを左に1ケタシフトして、そのあとのif文の中でflavorやバージョンに応じて、1ケタ目に新しい数字を放り込んでいるようです。

判定 1のケタ
MultipleAPKをARMv7向けにビルド 2
MultipleAPKをx86向けにビルド 4
MultipleAPKをall向けにビルド そのまま(0)
API20(Android 4.4W)以上向けにビルド 9
API14(Android 4.0)以上向けにビルド 8

統一感ないな!!! しかも、"20 is Lollipop"って普通にチョンボじゃないか・・・?

ともあれ、これで謎は解けました。

config.xml
<preference name="android-minSdkVersion" value="16"/>

今回扱っているプロジェクトのminSdkVersionは16なので、1のケタに8が入り、元々のルールと合わせる形で1008という値になったのでしょう。

どこかのドキュメントに書いといてくれないかなこれ!!!

自分で指定できる

さて、自動生成されるversionCodeはちょっとアレな感じでした。こうなってくると、自分で設定したくなってくる人も多いと思います。

ということで、自分で設定する方法を紹介して、締めにしたいと思います。

config.xml
<widget
   id="com.example.my-app"
   version="0.1.0"
   android-versionCode="12345"
   ios-CFBundleVersion="25.20151124"
   xmlns="http://www.w3.org/ns/widgets"
   xmlns:cdv="http://cordova.apache.org/ns/1.0">

上記のような形で、android-versionCodeやios-CFBundleVersionを指定しておくと、ビルド時に考慮してもらえます。
こんな感じに。

platforms/android/build/generated/source/buildConfig/debug/com/example/my_app/BuildConfig.java
package com.example.my_app;

public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String APPLICATION_ID = "com.example.my_app";
  public static final String BUILD_TYPE = "debug";
  public static final String FLAVOR = "";
  public static final int VERSION_CODE = 12345;
  public static final String VERSION_NAME = "";
}

スクリーンショット_2015-10-20_11_19_25.png

スクリーンショット_2015-10-20_11_19_44.png

まとめ

versionCodeの自動生成そのものはネイティブ開発でもときどき見かけるベストプラクティスですし、いちいち自分で決めるのも面倒なので、いいことだと思います。

ただ、一度PlayストアにリリースしてしまったversionCodeは、加算はできても減算はできない厄介なシロモノになります。自動生成に任せるのはよいですが、生成ルールに気を配って、良いリリースエンジニアリングをしましょう。

宣伝

ウォーターセル株式会社では、「ネイティブアプリ開発はある程度経験したし、そろそろJS覚えてハイブリッドアプリ開発とかしてみたいなー」という挑戦的なエンジニアを募集しています。

24
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
19