記事一覧

Migrating to cocos2d 0.99

cocos2d 0.99.4 を導入してそれをベースにプロジェクト全体を構築し直したんですが、まぁわりと大仕事でした;
そもそもそんな必要あるのか疑問なのだけど、なにしろAppleが報告してくるクラッシュの理由がもうそこぐらいしか思いつかない。

それはさておき、移行自体はだいたいcocos2dクラス名の頭に "CC" を付ければ良い。
AtlasSprite と AtlasAnimation だけはちょっと複雑だったけど、公式ドキュメントがかなり詳しくフォローしてくれてたので2時間強でなんとか移行完了(たぶん)。
http://www.cocos2d-iphone.org/wiki/doku.php/release_notes:0_99_0

It was a bit tough work to rebuild the project for newly installed cocos2d 0.99.4.
I believe it's unnecessary to do this, but I cannot think of any other possibility of having caused the crash in Apple's review.

Anyway, in migrating, most of the part is OK with adding "CC" to the cocos2d class names.
Only AtlasSprite and AtlasAnimation are a bit complex, but this official document is perfect and I was (seemingly) able to finish migrating in a couple of hours or so.
http://www.cocos2d-iphone.org/wiki/doku.php/release_notes:0_99_0

App still crashes?

コードを完全iOS4ベースにしまして、いくつかのデバイスで動作確認できたんですが、まだ Apple側が "iOS4でクラッシュしますぜ" と言ってくる。
自分のデバイス1つで確認してるんなら、互換性の問題という可能性が高いなと思えるのだけど、デバイスもOSバージョンも異なる複数の環境でOKだったのだからコードの問題とは思えない。
テスト用と提出用のビルドの違いと言えばコード署名だけなのだけど、これも前の審査では通ってた。
ちょっともう手の打ちようがないぞ・・・・どうする・・?


I revised my code to full-iOS4 based and made sure it's working on several devices.
But Apple still reports that it crashes on iOS4.
If I had tested only on my single device there still might be possibility of compatibility problem, but I have tested on different generations of device and different versions on OS so I believe it's not the problem of the code itself.
The only difference between the test build and the submission build is code signing, but it didn't caused any problem in previous reviews.
I'm completely at a loss.

Scene transision doesn't work on iOS4?

前のポストにも書いた通り、iPhoneOS3.x 系のappを iOS4 対応するのは、まずビルドを通すのにすったもんだあるわけですが、さらにビルド通ったあともいろいろあったり。
ひとまず動いてるように見えたのだけど、シーンのトランジションがブツ切りになってしまってて、指定してあったスライドインが反映されてない。

ちょっと調べてみたらこれを見つけた。
http://www.cocos2d-iphone.org/forum/topic/7338
これは cocos2d 0.7.x の話なんだけど 0.8.2 でもおおよそ同じ。
ただ、変える場所は162行目の1行で大丈夫だった。

split = [(IntervalAction*)[actions objectAtIndex:0] duration] / duration;

As I said in my last two posts, Building iPhoneOS3.x-based app on iOS4 SDK causes lots of troubles, and now I've got another trouble even after the build's got a pass.

It seems to be working well at a first glance, but when a scene make a transition it ignores my code to let it slide in.

I searched around a bit and found this:
http://www.cocos2d-iphone.org/forum/topic/7338
This is a cocos2d 0.7.x issue but it goes about the same on cocos2d 0.8.2, too.
I only modified single line at 162 and worked fine.

split = [(IntervalAction*)[actions objectAtIndex:0] duration] / duration;

iPhoneOS Deployment Target

I knew that to let the iOS4-based binary work on iPhoneOS3.x just open the Build Settings to set "Base SDK" to iPhone Device 4.0 and "iPhoneOS Deployment Target" to iPhoneOS3.x.
But I was a bit confused because "iPhoneOS Deployment Target" cell doesn't appear unless you set Base SDK to iPhone Device 4.0 beforehand.
It almost gave me a heart attack because my deadline was about to come.


iOS4 SDKでビルドしたものをiPhoneOS3.xで動くようにするには
"ベースSDK" をiPhone Device 4.0 にして "iPhoneOS Deployment Target" を iPhoneOS3.x にすればいい、ということなのだけど、ちょっと戸惑ったのが、ビルド設定画面で まず先にベースSDKを iPhone Device 4.0 に設定してからでないと、iPhoneOS Deployment Target の項目自体が出て来ないという点。
分かればなんてことないんだけど急いでたからかなり焦った。

Upgrading SDK (continued)

iOS4 SDK でビルドが通らない理由は2つあった模様。
1) オブジェクト名が iOS4 で新たに導入された API とかぶっていた
2) cocos2d libraries のビルドターゲット設定を変えるのを忘れていた

理由 1) は細かく言うと2つあって、
一つは単純で、 AVPlayer という名前を普通の変数として使っていたというもの。これは納得。
もう一つはなんか不可解で、セレクタの名前に "player" というものを使っていて、これが何か悪さした風。
セレクタの名前だけ引っかかるってどういう状況??
他の名前にしたら通ったからいいけど・・。


I've found there were two reasons of build failure on iOS4 SDK.
1) Object name conflicts with newly introduced iOS API
2) Forgot to change the Target Setting of Cocos2d Libraries

Reason 1) had two sub-reasons:
One is pretty simple, I was using the name "AVPlayer" as a variable. This is reasonable and I can understand.
The other is pretty incomprehensible, I used the name "player" as a selector, which seems to have caused some confusion.
How can a single selector name cause such confusion???
Fix the name to other one and succeeded to build, anyway...

Upgrading SDK

Build fails since I've upgraded SDK to iOS4 SDK.
Resetting Base SDK to iPhoneOS 3.2 in the Build Setting it worked well as before, so I guess there are some conflict with new API in iOS4.
I want to see what's wrong from the error messages, but what it says is too indirect to understand....


iOS4 SDKにしたらビルド通らなくなった・・・
ビルド設定でベースSDKを iPhoneOS 3.2 に戻したら動いたので、やはり iOS4 の新しい API との兼ね合いか!?
しかし、エラーメッセージがトンチンカンなこと言っててさっぱり原因が分からない・・・・困った

Get number of fingers touching

現在タッチされてる指の数を
[[event allTouches] count]
で取得できるってのを知りませんでした;

[touches allObjects]
でそのイベントをトリガーしたタッチを取得できるのは知ってたんですが;


I didn't know that I can get the number of fingers that are currently touching by doing this:
[[event allTouches] count]

I only knew this
[touches allObjects]
which retrieves only the touches that triggered the event.

Restore the state of MPMediaPickerController??

MPMediaPickerController の状態を復帰させる方法ってないのかしら?
とりあえずそういうメソッドは見あたらないんだが・・・

毎回 picker を開くたびに「すべての曲」リストの一番上に戻されちゃうから不便なんですよね。少なくとも曲/アルバム/アーティストのカテゴリ選択くらいは復帰してほしい;


Are there any ways to restore the state of MPMediaPickerController??
MPMediaPickerController class doesn't seem to have the method to change the state of the picker.

Every time my app opens the picker it shows the top of the list of "all songs" regardless of your last operation on the picker. At least I want it to restore the category(songs/albums/artists) selection....

MPMusicPlayer : Rewind and standby at song's end

自分のアプリはいちどに一つの曲しか扱わないのだけど、MPMusicPlayerは基本的に複数の曲を扱う仕様になってる。
これがちょっと面倒なんだな;

再生してる曲が終わると MPMusicPlayerController は次の曲に行こうとする。次の曲がキューにあれば nowPlayingItem に次の曲の mediaItem がセットされるのだけど、次の曲が無い場合は nowPlayingItem は nil になる。
queueに1曲しか無い場合、曲が最後まで行ったまま放っておくと必ず nil になってしまうわけで、そのままだともう一度その曲をプレイすることができなくなってしまう。

解決策は簡単っちゃあ簡単で、曲が終わったのを検知して nowPlayingItem をセットし直せば良い。ただ、そのためには
MPMusicPlayerControllerNowPlayingItemDidChangeNotification を扱うセレクタを記述して、あと通知センター登録とかごにょごにょしなきゃいけないし、あと mediaItem をインスタンス変数として保持したりしなきゃいけない。
こういうのって Bad Access の原因になるからイヤなんだよなぁ・・・

MPMusicRepeatMode に MPMusicRepeatModeOne_RewindAndStop みたいのがありさえすればすごく楽なんだけどな・・・

My app deals with only one song at a time, while MPMusicPlayer is designed for playing multiple songs;
This mismatch makes my app slightly more complex.

When the currently playing song comes to its end MPMusicPlayerController tries to move to the next song.
If there is the next song in the queue nowPlayingItem will be set to its mediaItem variable, but if there is none nowPlayingItem will be set to nil.
The problem here is, my queue always contains only one song, so nowPlayingItem will be reset to nil everytime you play a song to the end, and you cannot replay the song.

The solution is pretty simple to say : reset the nowPlayingItem when the player has finished playing, but to do this you have to write the selector to receive MPMusicPlayerControllerNowPlayingItemDidChangeNotification and some other codes to make it work.
And you also have to retain the mediaItem variable of the song as the instance variable.
I don't like this kind of thing because it often causes the Bad Access error...

It will be much easier only if MPMusicRepeatMode had something like MPMusicRepeatModeOne_RewindAndStop.

AVAudioPlayer's currentTime problem

自分のアプリでは、AVAudioPlayerの現在の再生時間を利用して動作を変えたりしてるんですが、どうもその辺りの動作がちょっとおかしい。

で、グーグル先生で調べてみるとこういうのありました。
http://stackoverflow.com/questions/882753/avaudioplayer-currenttime-problem

AVAudioPlayerの再生時間setterはint値しか取らないらしい;
さらに、再生中に値を変更すると不安定になることがあるらしい;
なんじゃそら;
とりあえず上のリンクのように変えてみたらおかしな挙動はなくなりました。

In my app I let it read the current time of AVAudioPlayer and vary the behavior according to its value.
But sometimes its behavior seems to be a bit strange.

I google'd about it and have found this:
http://stackoverflow.com/questions/882753/avaudioplayer-currenttime-problem

AVAudioPlayer's current playing time setter can take only int value.
And what's more, it will be a bit unstable when you set the value while it's playing.
I modified my app like the link above and now it's working well.