• 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

既存のiPhoneアプリをiPhone/iPad両対応の universal バイナリ化した場合、 iTunes Connect上でのstatusが"Missing Screenshot"になってしまうことがあるようです。

これはどうやら、全てのローカライゼーションに対してiPad用のscreenshotを少なくともひとつ設定すると解決する模様。 universal化した場合は、デフォルトの画像を自動的に全てのローカライゼーションに適用してくれないようなので、ローカライゼーションが多い場合は大変です。

posted by Png genki on Thu 30 Dec 2010 at 06:44

アプリをアップロードしようとしたのですが、Xcode 3.2.5+SDK4.2のbuildで、Application Loader.app(Version 1.4 (92))でもdwarfdumpエラーが出ます:

The dwarfdump binary must exist and must be executable: /usr/bin/dwarfdump (-19036)

ネットを色々見たところ、Xcodeを再インストールなんていう解決策も見たのですが、それはちょっと…と思ったので、

iTunes ConnectのManage Your Applicationsの一番下段にあるドキュメント
Using Application Loader内に、Application Loader1.3へのdmgリンクがあったのでそれをインストール

https://itunesconnect.apple.com/apploader/ApplicationLoader_1.3.dmg

Application Loader
Version 1.3 (89)

Upload & 更新申請うまく行きました!
ちなみに、Xcode3.2.5についてくるApplication Loader.appのバージョンは下記でした:

Application Loader
Version 1.4 (92)

posted by Png satoko on Mon 13 Dec 2010 at 03:16 with 1 comment

assertが失敗した場合に任意のコードを実行してからabortを行うようにする方法の簡単な実装です。

   1  #define ASSERT(cond) \
   2      for (; !(cond); assert(#cond == false))

  • レポートは素のassertに任せています
  • condを文字列化してcondが1度だけ評価されるようにします
  • falseとの比較でassertが失敗するようにし、レポートの見た目がそれっぽくなるようにします。

使用例:

   1  ASSERT(a>0 && a%3 == 0){
   2      printf("Invalid a: %d\n", a);
   3  }

出力例:

   1  Invalid a: 1
   2  Assertion failed: ("a>0 && a%3 == 0" == false), function fooBar, file baz.c, line 123

posted by Png genki on Sun 12 Dec 2010 at 19:53

UITabBarController を使っていて、タブが6個以上になると自動的に「more」(plist の Localization native development region の値により文言は変化)というタブが現れ、そのテーブルビュー経由で5番目以降のビューはアクセスされる。

すなわち5番目以降のビューは UINavigationView aware でなくてはならない。

で、more に戻る backBarButtomItem をカスタマイズの仕方。

self が UITabBarController だとして

方法1、文言だけの変更

   1  	self.moreNavigationController.rootViewController.title = @"HOKA";
   2  

方法2、イメージを貼る

   1  	self.moreNavigationController.rootViewController.navigationItem.backBarButtonItem = [ [ [ UIBarButtonItem alloc ] initWithImage:[ UIImage imageNamed:@"0.png" ] style:UIBarButtonItemStyleBordered target:nil action:nil ] autorelease ];
   2  

posted by Face Saturn on Wed 8 Dec 2010 at 06:09

結末に驚いたのでメモ。

XcodeでBuild & Analyzeすると、下記のようなメッセージが出て困っていました。UILabelのインスタンスを返すような関数なのですが、ちゃんとautoreleaseして返しているのにも関わらず、です。

Object with +0 retain counts returned to caller where a +1 (owning) retaincount is expected

メモリ管理周りをググったり、stackoverflowをうろつくなりして色々調べること数時間、原因を突き止めました:

Object with +0 retain counts returned to caller where a +1 (owning) retaincount is expected - Stack Overflow
http://stackoverflow.com/questions/3553401/object-with-0-retain-counts-returned-to-caller-where-a-1-owning-retaincount-i

結局、コード自体は間違っていなくて、「関数名が良くない」ということでした。AppleのMemory Management Programming Guideには下記のような記述があります:

You “create” an object using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy).

http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/MemoryMgmt/Articles/mmObjectOwnership.html#//apple_ref/doc/uid/20000043-SW1

[意訳] Objectを作成する際にはalloc, new, copyなどで始まる関数名を使う(例、alloc, newObject, mutableCopy)

コード内の関数名を書き換えて、解決!
(newで始まるだけではダメなのですね…)

   1  //NG
   2  (UILabel *)newLabelWithPrimaryColor:(UIColor *)primaryColor;
   3  
   4  //OK
   5  (UILabel *)createLabelWithPrimaryColor:(UIColor *)primaryColor;

posted by Png satoko on Wed 8 Dec 2010 at 00:21

Fast App Switch周りをガリガリやっていたら、@hkato193さんからメモリ警告絡みでアドバイスを頂きました。大変参考になったのでメモ。

http://twitter.com/hkato193/status/7972941820067840

@satoko ですので、メモリ警告が出てもデータ送信が継続できるようになっているか(ビューとかが捨てられるのは普通通りの対処でOK)、willTermiate(や時間切れハンドラ)で通信遮断やデータ送信失敗への対処が出来ているかがポイントです。Fri Nov 26 01:44:32 via YoruFukurou

つまり、Background突入時、ファイル送信などの処理をTask Completionでやる際に、

  1. メモリ警告で送信処理を中止しない
  2. 一方で、willTerminateやTask CompletionのExpirationHandler内で正しくキャンセル処理を行うこと:
    • 通信遮断
    • データ送信失敗への対処(送信データの保存など)
    • ユーザへの通知

Task Completionとは

Task Completion APIを使えば、Expiration handlerを使ってBackgroundで処理を行える:

   1  // WWDC 2010 Session 109 
   2  // Adopting Multitasking on iPhone OS, Part2 より引用
   3  self.bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 
   4  	[self prepareForSuspend];
   5  	[self pauseUpload];
   6  }];
   7  
   8  // returns after upload finishes or pauses 
   9  [self uploadPhotos];
  10  
  11  [app endBackgroundTask:self.bgTask];

詳細の書き方については、BlockやらGrand Central Dispatchを理解する必要がありそうなのですが、なんとなく次が見えた感じです。

posted by Png satoko on Thu 2 Dec 2010 at 15:39