Hatena::ブログ(Diary)

アルザえもんの手記

2015-04-03

StaticCellsのローカライズ

storyboardでStaticCellsのテーブル作ってたんだけど、ローカライズがめんどい。
とりあえず以下のようなコードで対応しているけど、もっとスマートな方法は無いかなぁ…。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSArray *titles = @[NSLocalizedString(@"TitleIndex_One", nil),
                        NSLocalzedString(@"TitleIndex_Two", nil)];
    UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
    cell.textLabel.text = titles[indexPath.row];
    return cell;
}

というかStaticCells使わずにDynamicPrototypesにしておけば良かった。

2013-08-16

Build Configuration毎でinfo.plistの内容を変更する

かんばんわ。
アルザです。

info.plistの内容をビルド毎に変更したい場面があったため調査してみました。
今回は「UIFileSharingEnabled (Application supports iTunes file sharing)」のtrue/falseをビルド毎に切り替えてみます。
試してないけど、URLスキーム等の文字列なんかも切り替える事ができると思う。

XcodeのProject設定の Build Setting を眺めていると「Info.plist Preprocessor Prefix File」という項目を発見。
ここにInfo.plist用のヘッダファイルを指定すればInfo.plist内でdefineを使う事ができそうです。

f:id:alza:20130816160346p:image

▼Info.plist Preprocessor Prefix Fileの作成
まずはInfo.plist用のヘッダファイルを作成。
ここではInfoDebugPreprocessor.hとします。

作成したらInfoDebugPreprocessor.hにdefineを定義しておきましょう。

#define DEBUG_FILE_SHARING_ENABLED true

今のところこんな感じ。

f:id:alza:20130816160349p:image

▼Build Settingsの変更
Build Settingsの「Info.plist Preprocessor Prefix File」に、作成したInfo.plist用ヘッダファイルを指定。
※プロジェクトからの相対パス指定になるので注意。

更に「Preprocess Info.plist File」をYESに設定しておきます。

f:id:alza:20130816160347p:image

▼Info.plistの編集
Info.plistに「Application supports iTunes file sharing」を追加します。
追加後、Info.plistの表示をSourceCodeにしてキーの値を以下のように変更しましょう。
※「Application supports iTunes file sharing」のキーは「UIFileSharingEnabled」になります

<key>UIFileSharingEnabled</key>
<false/>

<key>UIFileSharingEnabled</key>
<string>DEBUG_FILE_SHARING_ENABLED</string>

booleanってどうやって指定するのかと思ったら、普通に<string>で指定しても問題ないみたい。

▼動作の確認
実機で動作させてみて、PC側のiTunesを確認してみると、ファイル共有の箇所に自分のアプリが表示されている事が分かると思います。

f:id:alza:20130816160348p:image

これでマクロを使ってInfo.plistの値を指定できた事を確認できたので、だいたいこの時点で目的のほとんどは達成。
あとはビルド毎に値が切り替えられるようになれば完璧です。

プリプロセッサマクロでの切り替え (できなかった)
ところで、(メジャーな手法だと思うけど)私はNSLogによるデバッグログ出力有無を、Build Settings の「Preprocessor Macros」と#ifdef/#else/#endifの組み合わせで切り替えています。
そこで、info.plistの値もプリプロセッサマクロに合わせて切り替えできれば一番シンプルで分かりやすいかな、と安直に考えて調べてみました。

が、結論から言うと、出来ませんでした。。。

InfoDebugPreprocessor.hのdefineを #ifdef/#else/#endif で切り替わるようにしても必ず#elseの値が設定されるようで思うように動いてくれません。
Preprocessor Macros より Info.plist Preprocessor Prefix File の方が先にロードされてるように思えます。

ちなみにその際のInfoDebugPreprocessor.hのコードがコレ。

#ifdef DEBUG
  #define DEBUG_FILE_SHARING_ENABLED true
#else
  #define DEBUG_FILE_SHARING_ENABLED false
#endif

ぐぬぬ…。
※方法があればコメントくださると助かります。。。

▼Build Configuration毎に読み込むヘッダを切り替える
Build Settingsの「Info.plist Preprocessor Prefix File」の項目ですが、他項目と同じくConfiguration毎に分かれているます。
というわけで、プリプロセッサマクロでの切り替えは諦めて、DebugとReleaseで読み込むInfo.plist用のヘッダファイルを分けることにしました。

新しくReleaseビルド用のInfo.plist用ヘッダファイルを作成。
ここではInfoReleasePreprocessor.hとします。

InfoReleasePreprocessor.hにInfoDebugPreprocessor.hで宣言した同名のdefineをfalseで宣言しておきます。

#define DEBUG_FILE_SHARING_ENABLED false

あとはBuild Settingsの「Info.plist Preprocessor Prefix File」のReleaseに「InfoReleasePreprocessor.h」を指定すれば良いです。
Debugの方は「InfoDebugPreprocessor.h」のままね。

f:id:alza:20130816161901p:image

とりあえず、Build ConfigurationがDebugの状態で実行してみると、さっきと同様にiTunesのファイル共有にアプリが表示されていることが確認できました。

次はEdit SchemeからRunのBuild ConfigurationをReleaseに変更して実行してみると…
iTunesのファイル共有からアプリが消えました。

ドヤァ。

参考にしたページ。
▼stack overflow - Using preprocessor definitions in iOS App info.plist
http://stackoverflow.com/questions/14206621/using-preprocessor-definitions-in-ios-app-info-plist

2012-04-19

半角カナを全角カナに変換する。

かんばんわ。

NSMutableStringとCFMutableStringRefは相互に型変換できるので、CFStringTransformを使えば半角カタカナを全角カタカナに変換できます。

 // 半角カナを全角カナに変換 
 NSMutableString* string =[[NSMutableString alloc] initWithFormat:@"ヴァーパピガギグ"];
 CFStringTransform((CFMutableStringRef)string, NULL, kCFStringTransformFullwidthHalfwidth, true);
 [string release];

transformパラメータを変更することで様々な変換も可能です。カタカナをひらがなにすることも可能。すごいすごい。
上のコードではreverseパラメータをtrueにして逆変換していますが、falseにすると全角カナが半角カナになります。
また、 kCFStringTransformFullwidthHalfwidth はカタカナに限らず英字記号にも対応しています。

 // 全角記号を半角記号に変換 
 NSMutableString* string = [[NSMutableString alloc] initWithFormat:@"!”#$%&’()"];
 CFStringTransform((CFMutableStringRef)string, NULL, kCFStringTransformFullwidthHalfwidth, false);
 [string release];

2012-04-17

UIImagePickerControllerでカメラロール表示したらログにエラーが吐かれる

UIImagePickerController を表示する際に以下のエラーが吐かれる場合がある。

 <Error>: More than maximum 5 filtered album lists trying to register. This will fail.

よく分からないので調べてたら stackoverflowに同じトピックがあった。

回答には
「UIImagePickerControllerSourceTypeを設定する際には +[UIImagePickerController isSourceTypeAvailable:] を使ってsouceTypeが使用可能か確認すること」
みたいな形で書かれている。
それを実装したのが以下のコード。

    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
        sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    } else {
        // アラート出したりすればええんちゃう? 
    }

UIImagePickerControllerのクラスリファレンス、isSourceTypeAvailable:の項目にもしっかり書かれていたりする。

ただ、確かにエラーを吐かなくなったが、、、エラー吐いてた時のコードに戻したら今度はエラー吐かなくなってしまった。
何か釈然としない。
iOSのDeveloperForumを見てても何で発生しているのかイマイチわからないんですよね。
xcodeバグ?」みたいな流れになってるし。

今は諸事情からxcode4.2を使ってるのでxcode4.3.2では確認できてないけど、解消されてたりするんだろか。

2012-02-13

plistの改行文字

かんばんわ。

小ネタですが、ずいぶん前にハマってしまったので記載。

plistに改行文字(\n)を含む文字列を設定してたいのですが、
いざ読み出して表示してみると「\n」がそのまま表示されてしまいました。

設定した文字列
f:id:alza:20120214000451p:image
コードはこんな感じ。

    // info-plistのInfoStringに設定されているテキストを取得 
    NSString* str = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"InfoString"];
    label.text = str;

▼実行結果
改行されずに表示されてしまう。
f:id:alza:20120213235659p:image

NSStringをstringWithFormat:で初期化すればちゃんと改行されて表示されるので、plistからの読み込みで変になっているようです。
えぇー・・・。

続きを読む