2014年12月28日日曜日

環境設定をライブラリ化(使用例編)

環境設定機能をライブラリ化する話の続きです。出来上がったSwiftコード(PrefControllerクラス)の使い方を紹介します。難しい点はないので、ちょっとした注意点が中心です。

 

アプリで使い始めるには、最低限の準備が必要です。環境設定値を保存するファイル名、バージョン番号、個々の環境設定値に使うキー、それぞれのデフォルト値です。デフォルト値はDictionaryとして、その他はStringとして用意します。具体的なSwiftコードは、次のようなものです。見やすくするために、環境設定値が4つ(扱えるデータが4種類なので)と少なめです。

// 環境設定クラスを使う(準備)
...
// 環境設定機能の変数
var zPref : PrefController!
// 環境設定のファイル名とバージョン番号
let PREF_FNAME : String = "sample_pref.plist"
let PREF_VER_NUM : String = "010001"
// 環境設定キーの定義
let PREF_KEY_SNmae_S : String = "ShopName"
let PREF_KEY_SId_I : String = "ShopId"
let PREF_KEY_GRank_B : String = "GoldRank"
let PREF_KEY_TRate_F : String = "TargetRate"
// 環境設定のデフォルト値
let dictPref : Dictionary<String,AnyObject> = [
    PREF_KEY_SNmae_S : "○○屋",
    PREF_KEY_SId_I : 999,
    PREF_KEY_GRank_B : false,
    PREF_KEY_TRate_F : 0.6 ]
...
// アプリの初期処理の中でインスタンス生成
zPref = PrefController(dictPref, PREF_FNAME, PREF_VER_NUM)
...

それぞれの値を定義した後、アプリの初期処理の中で、PrefControllerクラスのインスタンスを生成します。これで準備が整いました。もし初期設定ファイルが保存してあり、バージョン番号が同じであれば、デフォルト値が更新されます。

zPrefというのは、私なりの使い方です。zDateなどもあり、共通ライブラリのインスタンスを生成する際、アプリのどこからでも使える変数として用意します。この変数を通して、クラスのメソッドを利用します。

この準備で重要なのは、環境設定キーの定義です。以降の処理でも、ここで定義したキーを使います。もし定義値を使わずに環境設定値にアクセスすると、文字列のリテラルを指定することとなって、間違ったリテラルを指定しても、エラーかどうか分かりません。実行時に間違いだと気付くことになります。そうならないために、ここで定義した値を使い、コーディング時点でエラーを発見するわけです。決まったリテラル文字列を使う際に、実行時ではなくコンパイル時にエラーを発見するための、よく使われる工夫ですね。

定義に使うキーの変数名にも注目です。ここでは、変数名の最後の1文字で、データ型を表しています。「S, I, B, F」は、それぞれ「String, Int, Bool, Float」を意味してます。データ型が間違っていないか、変数名で注意しながらコーディングできます。

変数名が長くなるとか、データ型を含む変数名を間違えるとか、心配する必要はありません。Xcodeのテキストエディタには、入力支援機能があり、定義した変数も出てきます。「PREF」とタイプしたあたりで、一連の定義値名が並んでいるはずです。それを選んで入力すれば、データ型付きの変数名も間違えずに入力可能です。

 

環境設定の準備ができたので、いよいよ使う段階です。環境設定値の関係する個々の処理で、取得メソッドを用います。次のSwiftコードのように。

// 環境設定クラスを使う(個々の処理で値を取得)
...
let iShopId : Int = zPref.getPrefF(PREF_KEY_SId_I)
...
if zPref.getPrefF(PREF_KEY_GRank_B) {
    ...
}
...
let iRate : Float = zPref.getPrefF(PREF_KEY_TRate_F)
let iAmountLevel : Float = StdAmount * iRate
...

取得メソッドを使うときは、データ型の指定に注意を払わなければなりません。同じメソッド名で、戻り値の異なる4つがあります。そのどれが選ばれるのか、特定できる形で使わないと、余計なエラーを生んでしまいます。

基本的には、型を指定した変数に入れるということです。型が指定されていることで、間違ったメソッドが呼ばれることはありません。

変数以外でも、データ型が特定できる場合があります。たとえば、if文です。条件式はBool型と決まっているため、そこに参照メソッドを入れると、戻り値がBool型に特定されます。また、関数やメソッドの引数でも、型が特定されているので、同じように正しいメソッドが選ばれます。

計算式の場合は、少し注意が必要です。計算に使われるリテラル値や変数の型によって、特定しづらい場合もあります。そのようなときは、取得メソッドの値をいったん変数に入れてから、計算で使うほうが安全でしょう。

 

環境設定の値は、アプリごとに専用画面を用意して、ユーザーが変更可能に作ります。その処理では、すべての環境設定値を取得し、画面に表示します。ユーザーが画面上で変更した後、新しい値を受け取って設定メソッドで更新し、ファイルに保存する流れとなります。たとえば、次のようなSwiftコードに。

// 環境設定クラスを使う(環境設定画面)
...
// 環境設定値の取得
let iShopName : String = zPref.getPrefF(PREF_KEY_SNmae_S)
let iShopId : Int = zPref.getPrefF(PREF_KEY_SId_I)
let iGoldRank : Bool = zPref.getPrefF(PREF_KEY_GRank_B)
let iRate : Float = zPref.getPrefF(PREF_KEY_TRate_F)
...
// 環境設定値のファイルへの保存
zPref.setPrefF(PREF_KEY_SNmae_S, iShopName)
zPref.setPrefF(PREF_KEY_SId_I, iShopId)
zPref.setPrefF(PREF_KEY_GRank_B, iGoldRank)
zPref.setPrefF(PREF_KEY_TRate_F, iRate)
zPref.writePrefFileF()
...

これは、あくまで一例です。すべての環境設定値を更新する必要はありません。更新が必要な環境設定値だけ更新するのが、一般的でしょう。

 

バージョン番号の使い方にも、少しだけ触れます。ここで用いるバージョン番号は、String型です。文字列ですから、何でも構わないわけです。でも、やっぱり上手に使う方法はあります。

1つは、意味を持たせることです。ここに示した例では、6桁の数字を用いました。「010001」です。これは、バージョン「1.0.1」を意味していて、それぞれの数値に2桁を与えて文字列化したものです。もちろん「01.00.01」でも「1.0.1」でも構いません。好きな形を使いましょう。

もう1つの工夫は、アプリのバージョンに合わせる方法です。アプリのバージョンアップで、環境設定値も必ずバージョンアップするとは限りません。そうではなく、バージョンアップしないほうが多いでしょう。アプリの最新のバージョン番号ではなく、環境設定値を最後にバージョンアップしたときのアプリのバージョン番号を、環境設定のバージョン番号として用いるという考え方です。どのバージョンから同じなのか、明確に分かる利点があります。

ちなみに私の場合ですが、アプリのバージョン番号とは関係なく、環境設定独自のバージョン番号を付けています。特に大きな理由はありませんが、関係を気にしないほうが自由に付けられてよいと思っただけです。

 

以上で、環境設定機能のライブラリ化の話は終わりです。

今までは、アプリごとに環境設定クラス(ファイル名:MC_Pref.swift)を用意していましたが、これからは共通ライブラリ(ファイル名:BC_Pref.swift)をアプリに追加して、キーやデフォルト値を定義すれば済みます。

環境設定変更用の画面作りは同じですが、手間の何割かは減ると思います。独自ライブラリの種類が増えるほど、アプリ開発の手間が減りますね。

 

(使用開発ツール:Xcode 6.1.1, SDK iOS 8.1)

0 件のコメント:

コメントを投稿