スポンサーサイト

--/--/--
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
comment (-) @ スポンサー広告

[XCODE 7 & iOS9] iOS9でのリジェクトと、XCODE7&iOS9対応

2015/09/17
9/16
まだiOS9が公開されてもいないのに、
「iOS9で動かないから」という理由で、
アップデート申請中だったゲームがリジェクトされた。
ひどい話だ・・・。

しかしAPPLEとはそういう会社だと割り切って、
仕方なくiOS9と、XCODE7をいれる。

以前のプロジェクトを開くと、
Swiftコードを修正しますか、と聞かれるのでOKとすると、
10分くらい修正されるが、
ようやく終わってコンパイルしてみると、
修正とやらが全く無意味だったのではと思うくらいエラーと警告が吐き出される。

とりあえずXCODE7のswift2.0で大きく変わったのは、
個人的には、

1、Varによる宣言が厳しく取り締まられるようになったこと。
 変更のない変数宣言はLetにしろと怒られる。

2、optionalの仕様が少しかわったらしいこと。
 さらに面倒になった

ことが嫌だ。

他にも、
一部のメソッドが使用不可になっていたり、型が変わっていたりと、
もうたくさんありすぎて、おぼえていないが、とにかく一個一個地道に修正していく。

あとXCODE7になって、スナップショットが消えたのが
個人的には一番つらい。


そしてようやくコンパイルが通り、実機で動かせるようになると、
今度は画面がけっこう崩れていることに気づく。


どうも、SpriteKitのzPositionの初期値や、SKLabelNodeのVertical初期値などが若干変わっているようだ。
なんでそんなところを変えてくるのか意味不明だが、仕方ないので修正する。

HTTPSに関してはすでにネット上で色々いわれているので、Plistに例外を指定。

Info.plist
 > NSAppTransportSecurity(Dictionary型)
  > NSExceptionDomains(Dictionary型)
   > test.com (Dictionary型) ← ドメイン
    > NSTemporaryExceptionAllowsInsecureHTTPLoads (Boolean型) → YES


これでHTTPでもアクセス可能になる。


ようやくひと段落ついたかなと思った頃に、
なにやらずっとLogに吐き出されている文字にようやく意識がむく。
気づいてはいたが、見て見ぬふりをしていたんだけど、そろそろ見てみる。

_BSMachError
とか
CAMetaLayerうんたら
とか、
warning
とか
かつてはなかったようなログが大量に吐き出されている。

どうも実機で動かした時だけ吐き出されるログのようだ。

ネットで検索しても、英語圏の記事が5件ほどしか出てこない

この世にXode7やSwift2.0を実戦的に使っている人間はほとんどいないんじゃないかと不安になるレベル。

その5件の記事を翻訳しながら読んでみても、
どうも解決できないと外人さんも言っているようなので、
私もあきらめて放置することにした。

そしていよいよアーカイブ化しようとした時、
ちょっと気になってStoryBoardを見てみると、
StoryBoardを開いた途端、
警告が50個くらい出現する。


なにやらAutoLayoutが微妙にくずれている。

なんで・・・???

全く意味不明だが、仕方ないので、全部手作業で修正。

しかし、iAdのad bunnar のサイズだけが
Frame for "iad main" will be different at run time.
と出て、消えない。

中を展開すると、
Height will be 32 at run time but is 66 in the canvas.

何度見ても、ボード上のサイズも指定も32なんだが・・・
当然、レイアウトを配置しなおしても消えない。
というかiADのバナーのサイズは2種類限定のはずで、
なぜ66などという数字が出てくるのか意味不明。

もういやになって、これも放置してやった
シミュレーターで見る限りは見た目に問題はない。


そして、いよいよ
アーカイブ化。

ところが、

The resulting API analysis file is too large. We were unable to validate your API usage prior to delivery. This is just an informational message

という警告が
アーカイブ時に出現。

初めて見た。

どうもアーカイブのサイズがでか過ぎるらしい。

色々調べてみると、
たしかにアーカイブのサイズが160MBを超えている。
なんでや!!!!
元来は51MBくらいのサイズのはず・・・。

XCODE6アップデートの際もにたようなことがあった、という記事を発見。

警告を無視してそのままsubmitしたら、App Storeでは正常なサイズになっていた、と書かれていた。

不安ながらも、きっと無視して大丈夫・・・と信じつつアップロード。

はい、ビルドに表示されません。


今日は早朝から夜の11時までずっと奮闘していたので、
そろそろ精神的にも限界。

しかしそれでももう少しねばって、
プロジェクトやフォルダの中を調べたり、無駄なフォルダを削除してみたり、
色々消してみたり、
それでもやっぱり何度やってもアーカイブのサイズは161MBのまま。
へんな警告は残り続けてるし・・・。

Snap shotがないせいで、元に戻るのが難しいし・・・。

もういやじゃぁあああああああ

ちなみに、同じverでアーカイブ化したものをアップロードすると、
すでにアップロードされています、とエラーが出る。

すなわち、警告はでているものの、アップロードは成功しているということになる。
しかし、ビルドにはなぜか表示されない。

これはもはやAPPLEのいじめに違いない。


そして3、4回目くらいのアーカイブアップロードの時、
iTunes connectのビルドに、
1番最初にアップロードしたアーカイブが表示される。

・・・・・・


要するに、すごいラグがあるということなのだろうか。
ちなみに、そのアップロードからはすでに2時間くらいが経過している。

ネットには、5分くらい待たないとビルドに表示されないことがあるから注意してね♪
とはあったが、
2時間などという数字はどこにも書かれていない。

しかし実際、2時間待ってようやく表示されている始末。


ということは、最後にアーカイブ化してアップロードしたものは、いまから
2時間くらい経過すれば、表示されるのかもしれない。

あるいは、このXCODEのver跨ぎによって発生するアーカイブのサイズの巨大化は、
巨大化したアーカイブをアップロード後にitunes connect側で何か、適正なサイズに作成しなおしているのかもしれない。
そのせいで、ビルドへの更新がこれほどに遅れているのでは。

だとすると、XCODEからitunes connectまで含めてお粗末な構成だとしか言いようがない。
というか全てを振り返ってみて、
なんとも稚拙で乱暴なアップデートである。

ネット上の過去の記事などをみれば、こうしたアップデートが今までに何度も行われていることかわかる。
そのたびに、デベロッパー達はくるしんできたようだ。

Micrsoftならこれくらいでも当たり前という感じはするが、
これがクールさを売りにするAPPLEの実態とはなんとも哀れな感がある。

しかし
今回のことで、
android開発にも触手を伸ばすモチベーションが大いに高まったので良しとする。


追記

このブログを書いていると、
最後にアップしたアーカイブがビルドに表示された。
アップしてから1時間くらいだろうか。
そして、無事、ようやく審査待ちに。

しかし、今後もこんなしょうもないことに付き合わされなければならないと思うと、iPhoneアプリ開発は本当に割りに合わない。
もっといい加減に向き合った方がいいのかもしれない。
スポンサーサイト
comment (0) @ エラー

今作っているゲームがようやくひと区切り

2015/08/11
今作っているゲームがようやくひと区切りつこうとしています。

まるまる一ヶ月かかりましたが、おもえば、まるまる一ヶ月ほぼずっとゲームを作ったのは、
大学生時代以来かもしれません。

こんなにも時間を要したのは、分からないことでつまづくのは仕方ないとして、
それを除けば、とにもかくにもmacと、XCODEが重いせいです。

私はwindowsの方では、未だに15年以上前のDELPHIを使っていますが、
数万行のコードを書いても、1秒かからずコンパイルしてくれます。

しかしXCODEは、1000行も超えれば、あくびが出るくらいには遅くなります。

そして今回も、前回に続いて解決できなかったことが残りました。


・まず、アプリ名のローカライズが今回もうまくいかなかったこと。

 これだけやって上手くいかないのは、きっと私が大きな見落としをしているからでしょう。
 しかし、上手くいかないので諦めました。
 info.Plistで直接bundle display nameに日本語で書いて、英語は無視しています。


・コンパイルが遅い。

 今回はいくつにもファイルを分散することで、少しでも軽さを維持しようと努めてみました。
 分散は結構効果があったと思います。
 コーディング中の重さも軽減されるようです。
 しかし、それでもやっぱり遅いです。
 あと思いつく対策と言えば、コンパイルせずにコードを書く時間を長くさせることでしょうか。
 それはあんまり性に合わないので、無理かもしれません。
 これがAPPLEの限界なんだろうと思って、諦めるしかないかもしれません。


・また、今回はiPhoneアプリ2作目でしたが、今回で初めて挑戦したことと、
 それに併せて、その中で解決できずに残った問題点を羅列しておきます。


・アプリ内課金

 実装には苦労しました。
 ネットに、Swiftによる分かりやすい情報がほとんどないのが辛かったです。
 多くの書籍も頼りましたが、ネットとあまり変わりません。
 そして、sandboxでのテストは最後まで上手くいきませんでした。
 今回、リジェクト可能性が一番高いのがここだと思います。

・横向き

 横向きは、縦向きよりずっとゲームの幅が広がるような印象でした。
 今の時代の人間は、縦の空間認識より、横の空間認識の方が得意であることに起因するかもしれません。
 しかし、横向きだと、HOMEボタンを押した時に、画面のアスペクトが一瞬変になります。
 これはSpriteKitの何かの設定のせいだと思うのですが、これに関する情報はネットでは見つかりませんでした。
 大した問題ではないのですが、ちょっと気になります。

・ネットランキング

 意外に簡単に実装できた方だとは思います。
 しかし、一番悩んだのは、エンコードタイプです。
 どうも、アプリ側は、ネットから受け取るHTMLを、自分なりにそのコードを解析して、エンコードタイプを判別しているような節が見受けられ、それに悩まされました。
 というのも、HTMLの一番上の数行の文字列を変えるだけで、UTF-8と判断されたり、ASCIIコードでしかデコードできなかったりと、不安定だったからです。
 まあこれは普通のブラウザも似たような挙動をするので、仕方ないかもしれませんが。

・フリックやスクロール

 全て自前で作りましたが、絶妙な感覚を得るまでに微調整が大変でした。
 フレームワークを利用した方が早いのでしょうが。

・UIはほとんど自作

 UIKitの一番面倒そうなのは、個人的にはリストです。
 デリゲートを使うセル更新とか大嫌いです。
 だから今回は自分でSpriteKitだけで作りました。

 しかし、まあ重い重い。
 数百行のリストを作るだけで、単純に数千nodeを作成するわけですが、とにかく重くなります。
 特に作成時が重いです。
 表示に関しては、一画面内に表示されるnodeが少なければ軽くなるようなので、
 一画面内に収まるリスト項目が少なければ、そこそこ軽くなります。
 しかし、作成は重いので、頻繁に全体を更新するのは苦しいです。
 けれど、UIでやるより多分ずっと楽にいろんなことを実装できたと思います。

・ビットマップフォント

 結構悩まされました。
 ビットマップフォントで作った「 」スペースのせいで、レイアウトが崩れたりして、それに悩みました。
 「 」スペースの指定は、自分でfntファイルを開き、その大きさを自分で手打ちして調節することで解決させました。


・サウンド関連

 前回同様にSpriteKitで鳴らしましたが、
 どうもSpriteKitで鳴らすと、重い時などに音が鳴らないことがあるようです。

 ここは絶対に重くなるというような所で、鳴るタイミングは少々ずれてもいいという場面では、
断片的にAVAudioを使用しました。


・タッチノードに困らされた。
 タッチの検出は、TouchBeganを用いて、タッチされたNodeを検索することで行っていましたが、
 ここに一つの問題が。

 どうもタッチされたNodeを検索するやり方では、
 当然かもしれませんが、Nodeが重なっている場合だと、最前面のNodeのみが検出されます。
 普段はそれでも問題ないかもしれませんが、
 例えば、半透明の煙のエフェクトなんかを手前に描画していたりすると、問題が露呈します。
 その時検出されるのは、煙の向こう側のキャラクターではなく、煙だからです。

 タッチ位置だけを取得して、あとは自分で処理するのがよいでしょうね。


・配列

 今回一番エラーが出たのが、配列でした。
 indexがオーバーしている、というやつです。
 最近の言語の多くは、可変配列のようですが、それがこの問題の根本です。

 最初に配列の最大値を決めて、そのあとは、その中で自分でやりくりする、というやり方なら、この問題は発生しにくくなりますが、可変配列は、最大値が可変するので、それで何度もつまづかされました。

 もちろんこれは人間側のミスですし、想定外の問題がエラーとなって見つけやすいという利点もあるので、悪いというわけではありません。 
 悪いのはそのたびに必要なコンパイルの遅さです。


・クラス

 今回はクラスをたくさん使いました。
 きっと多くの人には当たり前のようなクラスですが、
 私の場合、クラスを使わないと、ファイルを分散しづらかった、というのが動機でした。

 でもやはり、クラスを多様することで、不可解な挙動の温床が多々生まれ、その原因究明に
 頻繁に時間を割かれました。
 
 前回作ったゲームは、ほとんどの動作を一本化した自分のルーチンの中だけで回して作りましたが、
 他人から見たら大変見づらいコードではあると思いますが、このやり方だと、何か新たしいことをやる際に、
 すぐに導入できるのが利点です。
 全ての挙動と変数は、一つの中で保持・管理しているので、自分の頭のメモリはたくさん使いますが、
 コードの中では自由度がたかいです。
 クラスをまたぐことはないので、そういった境界を気にせずにすむのが良いです。

 逆にクラスを多様すると、クラスをまたぐための処理のせいで、そこで問題が発生することが私の場合はよくあります。
 これは私がクラスを完全に理解していないからだとは思いますが。
 今後はもう少しこの変を改善したいところではあります。


・リアルタイム描画

 SpriteKitは、その名のとおりスプライトを使用しますが、
 私はこのスプライトというのが、あまり好きではありません。
 重いし、一度描画してしまうと、描画レベルでの変更が利きづらいからです。
 ドット単位で描画を制御したい人にとっては、そういう描画を想定するメソッドが不在だと、悲しくなります。
 ただSpriteKitでも、
 SpriteをaddChildし、1フレーム後には、再びremoveして新たに描画したものをaddChildという風に繰り返せば、
 リアルタイム描画のようにはなりますが、
 なんかすごい、無駄なことをしているような気になります。

 結局、コードもルーチンも描画も、全て自分で一元化して把握管理したいのが、私の性格のようなので、
 そこが単に時代にあっていないだけなのでしょうけども。


comment (0) @ エラー

[Swift] シーン変更によるクラスの持続と破棄・インスタンスの持続と破棄

2015/07/23
まず、クラスの概念について、私はまだ完全に理解していません。
というか、ほとんど分かっていません。

というかクラスをどんな風に利用するのが適切なのかが、
分かっていないんだと思います。

しかし、それでも手探りに利用しているわけですが、
そのせいで、様々な不具合のような現象に出くわします。

1、SpriteKitのSKシーン切り替え時に、クラスやインスタンスはどのように残ったり、自動破棄されたりするのか。

現在のSwiftでは、クラスは参照元がなくなると自動破棄されるようです。
そのため、SKシーンを切り替えたりすれば、SKシーンのインスタンスが破棄されるため、
それによってクラスは自動消滅し、データ等を自分で破棄したりする必要がないとのことらしいのですが、
しかし、実際にはものすごくクラスが残っていたりするかもしれません。

たとえばSpriteKitにあるSKNodeですが、
シーン表示させているクラス内で作成したNodeを、
異なる二つの別クラスに、それぞれのインスタンス時に受け渡したケースで、

このNodeは、シーン切り替え3回目あたりで、突然表示されなくなるという
怪奇現象に出くわしました。

私がクラスを理解していないので、完全にあてずっぽうですが、
多分、二つ以上の別クラスに、メインクラスのnode等を受け渡した場合、
メインクラスのシーンを切り替えても、
その二つの別クラスのインスタンスは破棄されずに残っているんだと予想します。

この二つの別クラスは、メインクラスからインスタンス化しているので、
メインクラスが破棄されれば、自動的に参照元を失うはずなのですが、なぜか残り続けます。

こういうのは、多分そうじゃないかなーと警戒していても、
扱うクラスやインスタンスやnodeが膨大になればなるほど、
絶対に知らないうちに発生することだと思うのですが・・・。

なので、偶然発見できればいいのですが、もし発見できなかった場合は、
致命的なクラッシュバグ等として残ることになる非常に危険なものだと思います。


2、クラス内タイマーは残る。

NSTimer というタイマーがありますが、
これをクラス内で使用すると、個別に稼働するタイマーとなり非常に便利になります。
しかしこのタイマー、SKシーンが切り替わろうが、インスタンス元を破棄しようが、ずっと動き続けているようです。

なのでクラス内でタイマーを走らせる場合、
シーン切り替え時などには、
インスタンスしたクラス全てに対し、タイマーを止めるメソッドを実行してやらねばなりません。


・・・とまあ、今の所気づいただけでこのような重大な要素があるので、
きっとまだまだありそうです。

そして、これらのインスタンスがずっと残り続けると、
SKシーンの切り替えを行うたびに、それらが不要に重複し、思わぬ不具合を引き起こす原因となりそうです。


■ 対策 ■

SKシーン切り替え時には、SKシーンや各クラスに、

Dinit{
   println (" class名 end!! ")
}

の一文を挿入する。

これで、一応そのクラスのインスタンスが完全に破棄されたかどうかが判明します。

破棄されていないとしたら、私の場合の多くは、

・そのクラス内で使用しているNSTimerが破棄できていない。
  or
・そのクラス内で宣言したSKNodeを、2つ以上の別クラスに参照させている。

の2つが多いです。
前者は、シーン切り替え前に、NSTimerを終了させればOKですが、
後者は見落とす可能性が高いです。
対策としては、なるべくSKNodeを参照させる場合、個別にSKNodeを作って参照させ、
共有を避けるということくらいでしょうか。


最後に、
これらを一切考慮せずに済む方法は、
私の思いつく限りだと、SKシーンの切り替えはせずに、
表示させるシーンは常に1つに固定するという手法でしょうか。

そして画面遷移は、自分で全ての描画を管理することで、
シーン切り替えを利用せずに、自前で行えば、
シーンのクラスを呼び出すのは一度だけとなり、
再インスタンス化するというケースを排除できます。
そうなれば、クラスやインスタンスの不要な持続や破棄をいちいち考えずに済むではと予想します。


クラスを使用すると、
様々なものを個別に管理でき、
また再利用もできるのでとても便利です。

でも、予期しないことがあまりに多すぎて、
そういう対処に、大半の時間を持って行かれている感じです。

こんなことなら、
クラスは最低限の使用にとどめ、
その他全てを自分で構築した一つのループの中で回す方が、
何倍も開発速度が上がりそうです。

インスタンスが破棄されずに残っていることが一目でわかるようなシステムや、
そういうケースが発生した場合には警告で教えてくれたりすれば、まだいいのですが、
そんなことも一切ないし・・。

とまあ、時代に逆行したようなことを言ってみましたが、
個人で全てをやっているので、他人との共有管理を予定する必要がないし、
また一方、予期しない問題が発生すると個人では対応できない可能性が高いという点からも、
ひとりでゲーム開発なんかをやっている人には、
この辺、本当にめんどうな問題だと思います。


UIKitをSpriteKitと一緒に導入した時に、あまりにUIKitの仕様に手こずった時にも思いましたが、
UIにしても、こういう便利だと提示されがちなプログラム要素にしても、
私の場合は、0から自分で作った方が、結局早いし便利だったりするのが、
なんだか個人的に時代とマッチしていない感じがして、いつもちょっと寂しいです。
comment (0) @ エラー

linker command failed with exit code 1 / file too small (length=0) エラー

2015/07/08
再申請時に、初めてReleaseビルドの存在を知りました。
ビルドにはデバッグ用のDebugビルドが通常行われ、配信時用のReleaseビルドとは結果が異なることがあるというもの。
だから、アーカイブ提出時には、Releaseビルドのものを提出した方がいいらしい。

そこで[Product]の、[Scheme]から[Edit Scheme]を選び、Releaseビルドを選択して、
アーカイブを提出した。

しかし、そのあと少し気になって、もう一度ビルドして見ると、
いきなり、

Apple Mach-O Linker Error
linker command failed with exit code 1 (use -v to see invocation)
file too small (length=0)

という見たこともないエラーが。

はうあ!?

まさかDebugビルドでは発見できなかったエラーか!?と焦り、
色々調べたが、
よく考えれば、アーカイブ提出用のReleaseビルド時にはなんのエラーも出なかったわけで・・・

調べると、

「command + shift + k しろ!!!」という記事を発見。

つまり、クリーンのことだが、
どうやら何かのはずみでビルドが中断された時に、一部のファイルが0bytesのまま出力されてしまったことなどが原因のようだ。

クリーンしてみると、あっさりビルド成功。

なんなんだ・・・

Apple相手だと、こういう開発環境やツール側の不出来な部分のせいで時間を食うことが9割のような気がしてきた。
comment (0) @ エラー

[UIKit] UIRectのcornerRadiusのエラー iPadのみ

2015/07/08
エラー

Assertion failed: (corner_height >= 0 && 2 * corner_height <= CGRectGetHeight(rect)),

申請していたアプリのリジェクトの理由の一つのiPadで動作しないというものについて、
シミュレーターで試してみたら、iPad Airだけでクラッシュが起きた。
他のiPadでは正常に作動。

エラー箇所は上記の通り。

何やら、コーナリングの大きさの問題だったようだ。
要約すると、コーナリングの高さが、シェイプの高さの半分より大きくなってしまって困った、というものだろう。

そりゃ困るだろうが、他の実機でもシミュレーターでも、その辺はうまくやっているのに・・・なぜおまえだけ・・・

とある実機だけ例外みたいな、こういうのやめてくれませんか・・・。
全部エラーにするか、全部OKにするかしてほしい・・・・。

というわけで、ここを直して終了。

再申請してきます・・・。

なんか、拍子抜けするほど簡単なリジェクト内容でした。
一瞬、リジェクトメっセージをみたときは、その英語の淡々とした内容に、パニックになりかけましたが、
そうならそうとなぜひとこと言ってくれないのか、と思いたくなるような簡単なことでした。
comment (0) @ エラー
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。