2008年11月30日(日) 02時50分57秒

iPhoneアプリ開発、その(44) 過去は捨てたとは言わせない

テーマ:Xcode
 前回のLocalizable.stringsのファイル開いたら下のような状態で悲鳴あげた子はいねが~。

Fig.1

 こういう時は、まず、赤枠内で右クリック(ワンボタンマウスならコントロールキー押しながらクリック)して出てくるメニューの「独立したエディタで開く」を選んで、単独のウィンドウで表示させる。

Fig.2

 でもって、「表示>テキスト>ファイルエンコーディング」メニューのサブメニューから「Unicode (UTF-16)」を選択。

Fig.3

出てきたダイアログで「再解釈」ボタンを押す(「変換」は押さないように。こっちは今表示されている状態をUTF-16として確定させる事になる)。

Fig.4

ふう、やれやれだぜ。

Fig.5

ということで、無事日本語化も完了っす。

 で、まあ、楽しく遊んでみると、いいかげん起動時に一から始めるのがめんどくさくなるわけですよ。
できれば、最後に到達したレベルから始めたい。
 というわけで、レベル情報を記憶する方法。
 その方法は「iPhone OSプログラミングガイド」の「第11章アプリケーション環境設定」で説明されている。始めの方は、iPhoneの言語を設定する時にも利用した"Settings"

Fig.6

に自分のアプリケーション用の設定機能を追加する方法の説明。これを読み進んでいくと最後の方に「環境設定へのアクセス」てのがあって、設定を記憶したいならNSUserDefaultsを使いましょうって記述にぶつかる。
 でもって、このNSUserDefaultsについては「NSUserDefaults Class Reference」を読みましょうときたもんだ。ちなみに、日本語訳の方の「NSUserDefaults Class Reference」へのリンクは切れているので、英語の方のリンクをたどりましょう。

NSUserDefaults概要
 NSUserDefaultsを使えば、初期設定を記憶するためにシステムが用意したデータベースを利用できるよ、この場合、ユーザー別に初期設定を持つ事になるので、その動いているマシン全ユーザー共通の設定を持ちたかったらCFPreferencesの方を使ってね、両方を混在しての使用も可能ですよん。だそうです。たぶん。
 一緒にリンクが貼られているサンプルソースなんかを見てると

 NSUserDefaults standardUserDefaults

で取り出したインスタンスに対して

 integerForKey
 setInteger
 synchronize

メッセージを送る事で、初期設定データベースとやり取りできるみたい。チンパンジーゲームだと

 static NSString* kStartLevel = @"StartLevel";

 NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
 int level = [defaults integerForKey:kStartLevel];

で以前に保存したレベルを取り出し、

 NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
 [defaults setInteger:level forKey:kStartLevel];
 [defaults synchronize];

で、レベルを保存すればいいってことになる。
 あとは、この処理をどのタイミングでおこなうかだけど、まあ、アプリの起動時と終了時が妥当でしょう。なのでChimpanzeeGameAppDelegateの

 applicationDidFinishLaunching
 applicationWillTerminate

でおこなうことにします。applicationDidFinishLaunchingはChimpanzeeGameAppDelegate.cppが作られた時点で最初から入ってるけど、applicationWillTerminateは自分で追加しないといけない。
 調べるにはChimpanzeeGameAppDelegate.hの

@interface ChimpanzeeGameAppDelegate : NSObject <UIApplicationDelegate> {

をオプションキー押しながら"UIApplicationDelegate"をダブルクリックすることで、いつものリファレンスウィンドウが表示されるっす。リサーチアシスト使ってもいいよ。
 他にChimpanzeeGameViewController側に現在のレベルを設定したり、取り出したりするメソッドを追加してるっす。ただここらへん、やっぱObjective C 2.0のproperty機能を使うべきなんだろうな。これは宿題。

------------
サンプルプロジェクト:Chimpanzee-05.zip

 どうよ、ちゃんと記憶してる?
 ちなみに、iPhoneシミュレータではユーザー設定データベースの置き場として

~/ライブラリ/Application Support/iPhone Simulator/User/Applications//Library/Preferences

に保存とある。「~」は自分のホームディレクトリを指します。

Fig.7

えらい深いとこにあるが、この中の

com.yourcompany.ChimpanzeeGame.plist

ってファイルが目的のファイル。なぜにこの名前かというとプロジェクトのリソースファイルinfo.plistでそう設定してるから。

Fig.8

ここのBundle identififierてのでcom.yourcompanyとなってるのがそれ。

Fig.9

気に入らなければ、適当な文字列に直しましょう。

 jp.xcc.

とか、ここらへん実際にAppleStoreで公開する場合は、ちゃんとしたものが必要になるかも。
 あと、このファイル「com.yourcompany.ChimpanzeeGame.plist」はダブルクリックで開きます。でもって手動で設定可能。

Fig.10

 レベルあげすぎて、あのヌルいレベルが懐かしいとか思ったら値を戻しちゃいましょう。ただし9以上にすると、ハングすると思われ。

 今回のNSUserDefaultsのサンプルソースには、この他に

registerDefaults:

を使って、一番最初の起動時のデータベースが無い状態でも

int level = [defaults integerForKey:kStartLevel];

が有効であるようにする手法が使われていた。
 チンパンジーゲームだとintegerForKeyで返された値が0なら初期設定が無かったとみなして、初期値として3を入れているんで、特に必要とはしなかったけど、設定されている情報が複雑になれば有用ですな。
 ただし、設定にはNSDictionaryを使う必要があるみたいなんで、ちょっとめんどくさい。興味がある人は「NSDictionary Class Reference」を読むべし。

次回は、環境設定インターフェイス、Settingsバンドル経由で、今回の初期設定を変更する方法をお勉強。
AD
いいね!した人  |  コメント(4)  |  リブログ(0)

國居貴浩さんの読者になろう

ブログの更新情報が受け取れて、アクセスが簡単になります

SNSアカウント

最近の画像つき記事
 もっと見る >>

コメント

[コメントをする]

4 ■Re:Re:sleep入れるといいですよ

 sleepの引数は自分が眠る時間の秒数なんですが、あのタイミングでは値を10秒とかしてもすぐ終わっちゃうみたいです。
 終了Threadも別Threadなのかな~、謎。

 ま、音を鳴らすための別Threadに動作開始の機会を与えてやるレベルで使うということで。

3 ■Re:sleep入れるといいですよ

>りぼんさん
ありがとうございます!
無事に?アプリ終了してから鳴りました。
これでまわりの反応をうかがってみます。
お忙しいところ、ありがとうございます。
sleep(1);
てのも、勉強になりました。
またどこかで使えそうです。

2 ■sleep入れるといいですよ

そうですね。
サウンドは別Threadになるので、それがアクティブになる前に終了してるからでしょう。
強制的にsleep()いれてやれば音はなりますが…

例えばfinishSoundIDをインスタンス変数として

-(void)applicationWillTerminate:(UIApplication *)application {
AudioServicesCreateSystemSoundID(
(CFURLRef)[NSURL fileURLWithPath:
[[NSBundle mainBundle] pathForResource:
@"soundfilename" ofType:@"aif"]],&finishSoundID);
AudioServicesPlaySystemSound(finishSoundID);
sleep(1);
}

- (void)dealloc {
AudioServicesDisposeSystemSoundID(finishSoundID);


}

って感じで、でも、終わってから音がなるから変な感じです。

 本来終了時のビューが小さくなるトランジションにあわせて音ならしたいところですよね。
 そのタイミングの見つけ方は、わからないですね~。
 applicationWillResignActiveでは駄目みたいです。

1 ■applicationWillTerminate

お忙しいところすいません、
もしよければヒントください。

ホームボタンを押してアプリ終了させるときに、
音鳴らしたいなってなんとなく思いまして。
りぼんさんのこの記事を参考に
applicationWillTerminate
をAppDelegateに実装したんですね。
ビルドも通ったし、NSLogをかますと、
ちゃんと処理も通ってるんですが
音が鳴らないんですよ。
これは処理はできてるけど、音が鳴る前に
アプリが先に完全終了しちゃうってことなんですかね?

コメント投稿

AD

ブログをはじめる

たくさんの芸能人・有名人が
書いているAmebaブログを
無料で簡単にはじめることができます。

公式トップブロガーへ応募

多くの方にご紹介したいブログを
執筆する方を「公式トップブロガー」
として認定しております。

芸能人・有名人ブログを開設

Amebaブログでは、芸能人・有名人ブログを
ご希望される著名人の方/事務所様を
随時募集しております。