記事一覧

NSUserDefault @ iOS4

次回起動時にアプリの状態が再現するよう各種変数を保存するための方法としては、アプリ終了時に NSUserDefaults に書き込みを行うのが一番一般的かつ楽な方法でしょう。
iPhoneOS3.x系では、そのNSUserDefaults関係の操作を applicationWillTerminate に記述することで実現できるわけで、実際これで動いておりました。
が、iOS4ではどうやら applicationWillTerminate 自体が呼ばれておらず、かわりに applicationWillResignActive だけが呼ばれている様子。
なので結局、iOS 3&4 両方で状態保存を実現するためには、applicationWillTerminate と applicationWillResignActive の両方に NSUserDefaults 関係のコードを書かないといけない。
なんか腑に落ちないよなぁ・・・。

(10/6追記)
もっと確実にやるためには applicationDidEnterBackground にも同じことを書かないといけないみたいです。

The easiest way to save the application's state so that it can restore them on the next launch is writing NSUserDefaults when the application is terminating.
With iPhoneOS3.x it can be done by writing NSUserDefaults related codes on applicationWillTerminate and everything worked well.
But it seems iOS4 no longer calls applicationWillTerminate but only calls applicationWillResignActive instead.
Consequently, to let your app have the save state function both on iOS 3&4 you have to write NSUserDefaults related codes both in applicationWillTerminate and in applicationWillResignActive.

(Added on 10/6)
You also have to write the same thing in applicationDidEnterBackground to make it perfect.

ObjCOSC - sending MIDI notes to OSCulator

ObjCOSC で MIDIノートをOSCulatorに送るのは非常に簡単で、iPhone側は
[port sendTo:"/action" types:"f", 1.0f];
みたいに書いて、あとはOSCulatorの方で "/action" に希望のノートナンバーを割り当てればいい。

でも連続してノートを送ろうとすると、/action の値を一旦リセットしないといけないのがちょっと厄介。
というのは、OSCulatorは各アドレス(ここでは /action ですね)について前回送信した値を覚えていて、その値から10%以上変化した値を送らないと無視してしまうのであります。
とりあえずこんな感じで対策しました。
cocos2dベースのコードですが("schedule:" は CCNodeのセレクタなので)、NSTimerを使えば同じことができると思われます。


// どこかのメソッドの中
[port sendTo:"/action3" types:"f", 1.0f];
[self schedule:@selector(sendNoteOff:) interval:1.0f];

// セレクタをひとつ追加
-(void) sendNoteOff:(ccTime)dt
{
[self unschedule:@selector(sendNoteOff:)];
[port sendTo:"/action1" types:"f", 0.0f];
}


Basically it's pretty easy to send MIDI notes to OSCulator by ObjCOSC.
Just write like this on your code,
[port sendTo:"/action" types:"f", 1.0f];
and assign desired note No. to "/action" on OSCulator.

But if you want to repeat this action, you have to reset the value to 0.0f before sending the next one.
This is because OSCulator remembers your last value you have sent to the address (in this example "/action"),and ignores the input message unless the value differs over 10% from the last value.

I did like below to manage this issue.
It's cocos2d-based ("schedule:" is the selector of CCNode) but I believe you can do the same with NSTimer.


// In some method in the class
[port sendTo:"/action3" types:"f", 1.0f];
[self schedule:@selector(sendNoteOff:) interval:1.0f];

// Add this method to the class
-(void) sendNoteOff:(ccTime)dt
{
[self unschedule:@selector(sendNoteOff:)];
[port sendTo:"/action1" types:"f", 0.0f];
}