2013年12月28日土曜日

iOSアプリ申請時に "This bundle is invalid. Apps that include an armv7s architecture are required to include an armv7 architecture" エラーが発生した時の対処法

XcodeのOrganizerでiOS申請した時に "This bundle is invalid. Apps that include an armv7s architecture are required to include an armv7 architecture" が発生した場合、PCにUSB接続しているiPhoneやiPadを全て外してXcodeで「iOS Devices」を選択してからArchiveすれば解決!するかもしれません。

2013年10月25日金曜日

Winter '14でのListView直接表示(Force.com)

たまにはForce.comネタを。 

タイトルの件ですが、Webタブに直接ViewのURLを指定して、
 オブジェクトのランディングページをすっ飛ばしたい!
という要望を客先から聞いた時に isdtp=vwなどのURLパラメータを設定して
実現していた方は多いかと思います。


Winter'14から、上記方法では実現できなくなっていました。
デバッグしてみると、どうやらシームレスなリンクをするためのsrcUpメソッドが
iframe内で使えなくなっていることが直接の原因のようです。
(クリックインジェクション対策のせいかな?)

なので試行錯誤した結果、

VFページで

<apex:page action="{!URLFOR('ViewのURL')}" />

の内容でページを作成し、
VFタブを作成して設定すれば実現できました。

実はこれ、AppExchangeで配布されていたパッケージで実装されていたやり方なんですが、
目から鱗でしたね。

ええ。
その前日私はsrcUpを全てhrefリンクに変更するjavascriptを書きましたから

上記方法でも一応は動きます。
が、面倒だしレンダリング仕様変更されたら一発アウトなのでやらない方がいいです。

というわけでちょこっとしたTipsでした。ではでは。

2013年10月19日土曜日

Xcode5からの新機能「Images.xcassets」の使い方について

Xcode5から画像リソースが管理しやすくなる機能「.xcassets」が追加されました。今回はこの機能の使い方について書きます。


2013年10月17日木曜日

Rubyの文字列リテラルのUnicodeエスケープがうまくいかない時

Ruby 2.0 にて確認した内容です。

Rubyの文字列リテラルはバックスラッシュ記法を用いてUnicode文字をコードポイントから表示することが出来ます。
(\uXXXXの形式)

>> puts "\u3042"
>> あ


しかし、コードポイントが5桁の場合、この書き方だとうまくエスケープされません。
(前半4桁と最後の1桁の2文字扱いになる)

>> puts "\u20e95"
>>  ⃩5


この場合、以下の様にコードポイント部分を{}で囲むと期待通りにエスケープされます。
(\u{XXXX}の形式)

>> puts "\u{20e95}"
>> 𠺕


また、この形式ならば、スペースで区切ることで複数コードを一度にエスケープできます

>> puts "\u{20e95 3042}"

2013年10月8日火曜日

Xcode5でQuickHelpを書く

Xcode5から実装したメソッドにQuickHelpを書く事が出来るようになったようです。ので、簡単に試してみました(公式ドキュメントほぼそのままですが...)。

メソッド

書き方は表示したいメソッドの上部へ記述に従って書くだけでOK。例えば以下のように。
/*! 社員の出社状況を設定
 * \param employeeNumber 社員番号
 * \param state 出社状況。YESなら出社で、NOならズル休み
 * \returns 出社状況がDBに保存されたかを返す
 */
- (BOOL)setEmployeeWork:(NSInteger)employeeNumber withState:(BOOL)state
{
    // 略
}
メソッドを呼び出している場所で、三点タップしてあげると以下のように表示される(これは公式メソッドのQuickHelp表示方法)。

メソッド上にカーソルが存在する際、Xcodeのプロパティに以下のように表示されもします。


クラス

メソッドと同じようにクラスに対してもQuick Help表示できます。例えば以下のように。
/*! ViewController
 * 存在価値のないクラス
 */
@interface ViewController : UIViewController
ViewControllerを三点タップすると以下のように表示されます。

ちなみにQuick Helpを追加しなかった場合、以下のように継承元クラスのQuick Helpが表示されます。

2013年9月19日木曜日

iOS6からiOS7への対応

社内で書き残していた内容をブログに書き写した内容となります。個人アプリをiOS7に対応させた時に書き残した内容なので掲載画像がアレですが気にしないでください。

①アイコンの追加対応

iPhoneで1種類、iPadで2種類増加されました。iPhoneが1種類しか必要ないのは対応バージョンに非Retinaが無いためです。
iPhone(120x120)
・Icon-60@2x.png

iPad(76x76/152x152)
・Icon-76.png
・Icon-76@2x.png

②storyboardで作成した箇所のレイアウトが崩れる対応方法

Xcode4.6以前で開発していたプロジェクトをXcode5で起動し、初めてstoryboardを開いた時にstoryboardで作成した全レイアウトを自動調整してくれる。もしくは警告にそれっぽいメッセージがあるのでクリックすると自動修正されます。それでも未だグチャグチャな場合は他に原因があり。

③UINavigationBarとStatusBarをUIViewに上被せで表示させたくない場合の対応方法

以下はUIViewControllerクラス等を継承したクラス上で使う想定のコード。もしTabBarだけは元の状態にしたいなら UIRectEdgeBottom を使う。
self.edgesForExtendedLayout = UIRectEdgeNone;

④StatusBarとUINavigationBar上の文字とが被る

StatusBarの上にUINavigationBarが被さる事が原因だが③の方法で解決しない。発生する原因はUINavigationController上にUINavigationBarが追加されていないからUIViewController側がUINavigationBarを一つのControllerと見なして自動調整してくれないからなので、対応方法は以下のようにUINavigationController側でStatusBarとTopBarを使うよう定義すれば良い。

⑤UIAlertViewがaddSubView出来なくなった問題への対応方法

TSAlertViewなどのUIViewを継承したカスタムAlertViewで代用。クラス名を置き換えるだけで対応出来るが、ダイアログの見た目はiOS6以前のものとなる。もしくはUIAlertView風に見せるのではなくUIViewControllerをモーダル表示する。
https://github.com/mindbrix/TSAlertView

⑥UI部品の背景色が変更されない問題への対応方法

色設定の仕様が以下のように変わりました。今まで背景色を変更するのに使っていたメソッドが文字色変更用となり、背景色を変えるメソッドが新たに追加されています。
// UI部品の文字色変更
setTintColor

// UI部品の背景色変更
setBackgroundColor
以下は具体的な背景色を変更する例。UISearchBarなどの特殊なUIに関してはメソッド名が違う点と色濃く表示される点に注意が必要、少し薄くするのがベターかもしれません。
UIColor color = [UIColor redColor];
// before
[self.navigationController.navigationBar setTintColor:color];
[self.navigationController.toolbar setTintColor:color];
[searchBar setTintColor:color];

// after1
[self.navigationController.navigationBar setBackgroundColor:color];
[self.navigationController.toolbar setBackgroundColor:color];
[searchBar setBarTintColor:color];

// after2(差分だけ)
[searchBar setBarTintColor:[color colorWithAlphaComponent:0.2f]];


⑦UI部品の一括色変更する対応方法

Window#対象メソッド で変更可能です。ただし、Window#setBackgroundColor で変更されるUIはUINavigationBarのみっぽく、UIToolBarなどは変更できませんでした。iOS7からデフォルト色が白から青に変更されているため注意が必要です。
// AppDelegateクラス上
UIColor color = [UIColor redColor];

[self.window setTintColor:color];
[self.window setBackgroundColor:color];


⑧ホーム上のアプリ名の省略されない最大文字数変更

iOS7からフォントが変更されたのに伴い、ホーム上のアプリ名の文字サイズが若干変わったようです。今までは半角13文字まで省略されずに表示されていましたが、iOS7では半角12文字までに変わっていました。
iOS6:半角MAX13文字
         :全角MAX6文字
iOS7:半角MAX12文字
         :全角MAX6文字

余談

この対応を入れたアプリを一週間以上前に申請したのですが未だにIn Reviewにすらステータスが変わらないので、今対応して申請してもしばらく待たされそうです。

2013年8月5日月曜日

LeapMotion と openFrameworks で シューティング macアプリ

前回(Three.js)前々回(box2dweb)につづいてLeapMotionネタです。

今回はmacアプリ。つくるのは前回みたいなシューティングゲームっぽいもの。
openFrameworksを使って
そこにLeapMotionを繋いでみます。
3次元に表示にするのでopenFrameworksアドオンのofxBt を使います。
そして初めてのC++。

2013年8月2日金曜日

LeapMotionとThree.jsでブラウザシューティングゲーム

先日の記事(Box2dWeb)に引き続きLeapMotionネタです。
シューティングゲームを作ってみます。

webGLのAPIを使いこなすことなど不可能です。
なので Three.js を使います。
Three.js はWebGLを使いやすくしてくれるライブラリで、初めて使いましたがすごーく使いやすいです。

デモはこちら

ソースコードはこちら

2013年7月31日水曜日

LeapMotion と box2dweb でブラウザアプリ

先日うちの会社にもやってきました。LeapMotion

leapjs (http://js.leapmotion.com/) を読み込むことでブラウザJSでも使えます。
サンプルもいくつか出てます。↓
http://js.leapmotion.com/examples

ということで、js物理演算ライブラリのbox2dWeb に reap motion を繋いでみます。
指二本で動かします。


デモはこちら (対応してないブラウザだったらごめんなさい)

ソースコードはこちら

2013年7月20日土曜日

cocos2dx JavaScript Bindings の websocket

cocos2dx に xhr と websocketが実装されました。
cocos2d-x ver 2.1.4 が神アップデートすぎる件について

javascriptでopenglのパフォーマンスが得られるのは素敵なのに
通信ができないんじゃ使えないじゃん。
って思ってましたが、実装されちゃったので早速使ってみます。

twitterのstreaming api を流してみます。
こんな感じ↓

2013年7月16日火曜日

作るものの妥当性

正解ではなく妥当。
ふわっとしてていい言葉ですね。

僕らが作るもの(アプリとかwebサービス)にはだいたい二つの妥当性があります。

一つは経済のレイヤーにある妥当性。
簡単にいうと仕様通りに動くかどうか。
妥当でなければお金がもらえません。
こちらはお客さんとともに詰めていくもので、いろんなトレードオフの上に成り立ちます。
職能別の作業単位(責任)に明確に分けて考えれるものです。

もう一つは質(クオリティ?)のレイヤーにある妥当性。
これは自分らが作ったものとして世に出していいのかという判断。
経済レイヤーの妥当性とはあまり関係がありません。
自分らと作るものとの関係です。
主に全体としての納まりという所なので
コンテンツ、挙動、デザイン、コンセプト等々をまるっと考えて仕上げていく必要があります。

経済レイヤーの妥当性と関係がないとはいえ質のレイヤーにある妥当性をちゃんとしようとすると
やはり時間やお金(工数とよばれるもの)はかかります。なので僕らはここで戦いますが、
それだと食ってけない論が正論すぎて、反論できません。
そんな日々に慣れすぎると質のレイヤーの妥当性を忘れてしまいます。

2013年5月31日金曜日

iphoneの課金処理を見通しよくする

objective-cには無名クラスが無い(たぶん)。
なのにだいたいインタフェースがオブザーバー。
その都度処理かえるのがめんどい。

ということでBlocksインタフェースをつけちゃいます。
今日はStoreKit。

目標

課金処理の見通しよくする

使う側をこんな感じに

課金処理で結局何がしたいかというと、
・課金をリクエストして成功したか失敗したか。
・リストアをリクエストして成功したか失敗したか

controller.m

// 購入処理
 SLSK* slsk = [SLSK getInstance];
 slsk.onFail = ^(NSError* error){
    NSLog(@"%@", error.debugDescription);
 };
 slsk.onPurchaseSuccess = ^(NSString* productIdentifier){
    NSLog(@"%@ 購入完了", productIdentifier);
 };
 [slsk puchase:@"com.subakolab.tyarintyariiiiiiin" /*productIdentifier*/];
// リストア
 SLSK* slsk = [SLSK getInstance];
 slsk.onFail = ^(NSError* error){
    NSLog(@"%@", error.debugDescription);
 };
 // リストア対象のアドオンの数だけ呼ばれる
 slsk.onRestoreSuccess = ^(NSString* productIdentifier){
    NSLog(@"リストアアドオン:%@", productIdentifier);
 };
 // リストアが全部終わったら呼ばれる
 slsk.onRestoreComplete = ^(){
    NSLog(@"リストア完了!");
 };

2013年5月29日水曜日

tail -f をブラウザで表示

tail -f /var/log/httpd/access_log 
tail -f /var/log/httpd/error_log

まーよく使いますね。

ディレクターとかお客さん(プログラムわかりませんの人)とかでもデバッグ中にログ流しながらできたら、デバッグしてますっぽい雰囲気出て楽しいんじゃないかと思ったけど、
sshつないでもらうの怖いしなー。
っていうことでブラウザにログを流してみましょう。

実際やるときはパーミッションとか認証とかちゃんとがんばってください。

データソースの抽象化

はじめまして、先週からスバコラボでお世話になっています。
好きなものはお酒、嫌いなものはプログラミングです。

手があいて暇なので
データソースの抽象化について書いてみます。

よくあるパターン

webAPIからデータを拾って表示するネイティブアプリ。
フォーマットもURLも決まってなくてモックが作れない
結合のときにやたらばたばたする。
APIがミスってるのかアプリがミスってるのか分かりにくい。
デザイン確認したいだけなのにAPIがバグっててアプリが落ちる

よくありますね。

このあたりをなんとかするために
モデルからデータソースを抽象化してみます。

目標

データソースの実装に引きずられないように

今回のサンプル

記事(Article)一覧をデータソースから読み込んで表示する

2013年5月23日木曜日

railsでの簡易遅延実行

※この記事の内容は、あくまで遅延実行を実装するための方法であり、マルチスレッドやバックグラウンドプロセスとは異なります。よって、herokuなどの30秒timeoutの壁はこの方法では破れません。諦めてdelayed_jobやcarrierwave_backgrounderを利用してください。

お久しぶりです ヾ(o・ω・)ノ

最近時間がないせいか記事がなくて寂しいので書いてみようと思います。
また、iOSネタしかなかったので、たまにはrailsネタで。

以下のソースコードで遅延実行が実装できます。

# Gemfile
gem "rack_after_reply"


# app/controllers/hogehoges_controller.rb
def hogemethod
  env["rack_after_reply.callbacks"] << lambda {
    # 時間のかかる処理
      
  }
  # 202 Accepted を返す
  format.html { render status: :accepted }
end

これだけ。

いやー、簡単ですねー。

仕組み的には代表的な Rack サーバー(Mongrel, Passenger, Thin, Unicorn, WEBrick )が各リクエストを処理するメソッドをフックして、コールバックを実行しているとのこと。

herokuはリクエストのタイムアウトが30秒に制限されているのでいくら遅延実行しても無理でしたが、AmazonEC2経由でS3に大容量ファイルをアップロードする機能はこれで実装出来ました。
(まあアップロードにcarrierwaveを使っているので最終的にcarrierwave_backgrounderに変更しましたが。)
サーバー側のプロセス的には結局アップロードが完了するまで掴みっぱなしなのであまり意味はないですが、使い方次第では簡単にユーザビリティを上げられるのでオススメです。
何よりロジックを変えなくていいのが良い!

ただしまあ問題もありまして。
エラーハンドリングが困難なのが一番の問題ですねえ (・ω・ ;)(; ・ω・)
上記のファイルアップロードなどの場合、先にレスポンスが返ってしまうので、画面上は正常にアップロードされたと表示されているにも関わらずサーバー側でコケている的なことが起こり得ます (´・ω・`)

なので、遅延実行に入る前に、可能な限りデータチェックはしておきましょう。

ではでは。

2013年5月20日月曜日

新しい仲間が増えました

お世話になっておりますスバコラボです。

スバコラボに新しい仲間が増えました。
お金大好きでプログラミング嫌いなK君。
まあ、うちの社員は一人除いて全員K君なんですけどね。

そろそろ、部屋が狭くなって来ましたがギリギリまで
このアパートで頑張りたいと思います。

それではごきげんよう。。

2013年2月26日火曜日

StoryBoardを使った場合のUIScrollView

Use AutoLayoutのチェックがついているとスクロール出来ません。









地味にハマったorz

2013年2月22日金曜日

OSのバージョンによるUIScrollViewの動きの違い

ちょっとハマったので備忘のため。

pagingEnabled=YES, bounces=YESのスクロールビューを使った時、
iOSの5と6でスクロールの動きが違ったので以下に内容を記載します。

例えば以下のようなコードを書いた場合。

scrollView.contentSize 
  = CGSizeMake(pageViewSize.width*maxCol, pageViewSize.height*maxRow);

この場合pageViewSizeのサイズ*グリッド数分の領域がcontentSizeとしてセットされます。
この時、pageViewSize.widthが1024、maxColが2だとすると
scrollViewのcontentSize.widthは2048になります。
この状態で、scrollViewのcontentOffset0,0から右フリックすると、
scrollViewDidEndDecelerating内でのcontentOffsetが
iOS6の場合は、1024で止まるのですが、
iOS5の場合は、1024を超えてoffsetが増加していきます、
(つまり、contentSizeを超えた領域までスクロールが到達してしまう。)

対策としては、scrollViewDidEndDecelerating内で位置を補正するコードを書くか
bounces=NOにして、バウンド処理を切れば、iOS5でも正常な位置でストップするようになります。

2013年1月23日水曜日

2つのModalViewを切り替えて表示する方法

ModalViewを起動している時に、一度ModalViewを閉じてすぐに他のModalViewを起動したい事があるかと思います。今回はその方法を書きます。
※iOS5以上での方法となります。

storyboard

まずstoryboardで起動元画面を1画面、ModalView用の2画面作成します。
左から以下の名前で進めていきます。
  • ViewController
  • ModalView1Controller
  • ModalView2Controller
ModalView2ControllerのStoryboardIDに「Modal2ViewController」と設定しておきます。

ModalView1Controller

1つ目のModalViewを実装していきます。
以下は ModalView1Controller.h
@protocol ModalView1ControllerDelegate
- (void)switchModalViewController:(UIViewController *)controller;
@end

@interface ModalView1Controller : UIViewController {
    id<ModalView1ControllerDelegate> myDelegate;
}

@property (nonatomic, retain) id myDelegate;
- (IBAction)showModalView2Controller:(id)sender; // storyboardに配置しているボタンのイベント
@end
次に ModalView1Controller.m
// 遷移するトリガー。ここではボタンクリックにしています
- (IBAction)showModalView2Controller:(id)sender
{
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil]; // MainStoryboard_iPhone.storyboard
    UINavigationController *nc = [storyboard instantiateViewControllerWithIdentifier:@"Modal2ViewController"]; // StoryboardIDを指定
    [myDelegate switchModalViewController:nc];
}
ここではDelegateを使って、遷移元に次に表示したいModalViewのControllerを渡している点がポイントです。

ViewController

次に1つ目の画面であるModalView起動画面を実装します。
以下は ViewController.m
// 遷移直前に呼ばれる
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    ModalViewController *controller = segue.destinationViewController;
    controller.myDelegate = self;

    // 上記はViewControllerに対して行う処理。Navigationとかは以下みたいにする
    // UINavigationController *navigationController = segue.destinationViewController;
    // MangaPageViewController *controller = (id)[[navigationController viewControllers] objectAtIndex:0];
}

#pragma mark - ModalView1ControllerDelegate
- (void)switchModalViewController:(UIViewController *)controller
{
    // 遷移先のModalViewを閉じて、次に表示させたいModalViewを起動
    [self dismissViewControllerAnimated:YES completion:^{
        [self presentViewController:controller animated:YES completion:NULL];
    }];
}
ポイント2つ。
  1. 遷移する時にModalView1Controllerで実装してるmyDelegateにselfを設定しておく。
  2. delegateメソッドが呼ばれたら表示中のModalView1Controllerを閉じ、閉じる処理が完了したらModalView2Controllerを起動させる。

完成

実装は終わりましたので確認してみてください。

2013年1月14日月曜日

iOS6以上でのstoryboard上のローカライズ対応


すっかりブログ書くことを忘れてたので初めての会社ブログへの投稿になります。鯱ブログだし休日に会社ブログ書くとらしい鯱れるね。

iOS6からstoryboard上のローカライズ対応が楽になりました!楽になった方法を書こうと思いますが、楽になったのは設定時であって前準備は非常にメンドウです。くじけぬ心を装備して臨みましょう。

Step1. プロジェクト作成

まずはXcodeでプロジェクトを作成してください。今回はiPhone/iPadのstoryboardを追加した状態で解説していきます。


Step2. Localizable.strings作成

Finderから「プロジェクト/en.lproj」ディレクトリに "Localizable.strings" ファイルを作成します。

今回の初期設定時に巻き込んで作ってしまうと楽なので含めている為、今回このファイルは使いません。不要ならこのStepは飛ばしてください。
コード上で以下のように記述する事で利用します。
NSLocalizedString(@"kye", @"comment");

Step3. Base.lproj作成

Xcodeで「Project > info> Localizations > + > Other > Base(Base)」を選択。
ローカライズ対象のファイルを選べというアナウンスがあるので、全てチェックが付いた状態で「Finish」を押します。


結果、Baseとenはこんな感じになります。

Step4. *.storyboard用の*.stringsファイル作成

ターミナルから「プロジェクト/Base.lproj」で以下のibtoolコマンドを実行します。それぞれstoryboardに対応したstringファイルなので、そのディレクトリにあるstoryboard名が異なれば内容変更して実施ください。
ibtool --export-strings-file MainStoryboard_iPhone.strings MainStoryboard_iPhone.storyboard 
ibtool --export-strings-file MainStoryboard_iPad.strings MainStoryboard_iPad.storyboard
こんな感じに*.storyboardに対し、*.stringファイルが増えていればOK。

Step5. *.stringsファイル移動

Base.lprojに作成した.*stringsファイルを、en.lprojディレクトリにFinder(実際のファイルをって事)で移動させます。
これでBase.lprojディレクトリに2ファイル、en.lprojディレクトリに4ファイルです。


Step6. Xcodeに今まで作成したファイルを追加

追加したLocalizable.stringsとstoryboardの*.stringファイルをXcode上に追加します。
Xcodeから「メニュー > Add Files to "プロジェクト名"」から"Base.lproj"と"en.lproj"を選択します。
Xcode上で*.storyboardとInfoPlist.stringsが重複して邪魔なので消します。

Step7. 対応言語の追加

英語以外の言語を追加していきます。今回は"Japanese(jp)"を選びます。

まローカライズ対象のファイルを選べというアナウンスがあるので、 *.storyboard以外の全てにチェックを付けた状態で「Finish」を押します。
"MainStoryboard_iPad.storyboard" や "MainStoryboard_iPhone.storyboard" ファイルにチェックを付けないのがポイントです。

これで、LanguageにJapaneseが増えます。

Xcode上で見ると "InfoPlist.strings", "Localizable.strings", "MainStoryboard_iPad.strings", "MainStoryboard_iPhone.strings" に▶印がついて、▼するとEnglishとJapaneseの2言語が設定出来る状態になりました。

これで前準備は終わりになります。慣れれば簡単なのかな?いあそんなことは...


Step8. storyboard上でUI作成

iPhoneのstoryboardを対応してみましょう。"MainStoryboard_iPhone.storyboard" を開いて適当にUI作成してください。
今回は以下のように作成してみました。

Step9. storyboardに表示するテキストをローカライズ対応

"MainStoryboard_iPhone.strings"ファイルの英語or日本語を開いて以下のようにkey-valueを設定していきます。
"key" = "value";
ここで重要なのはkeyの方です。keyは"MainStoryboard_iPhone.storyboard" を開いて、文字を表示させる対象の部品を選択し、storyboardの右Viewの左から3つ目にあるタブにある「Object ID」と値を設定したいプロパティ名になります。
もうひとつ大事なポイントとして、対象のプロパティには何かしらの文字を設定しておいてください。未設定だとkeyに対応したvalueが設定されません。


例えばUILabelの場合、私が作成したstoryboard上ではObject-IDが "udb-le-F0F" でした。これに表示させたい対象のプロパティ名 "title" を組み合わせた "udb-le-F0F.title" がkeyとなります。"MainStoryboard_iPhone.strings" 上には以下のように書きます。
"udb-le-F0F.title" = "Localize"; // 英語ファイル
"udb-le-F0F.title" = "ローカライズ"; // 日本語ファイル
なお、今回iPhoneだけstringファイルを弄りましたが、このままではiPad側のstringファイルに何も書かれていない為、エラーになってしまいます。たとえ未使用でも*.stringファイルには何か書いておく必要があるのでご注意を。
storyboard上に文字を挿入したい時はこのStepを毎回行う必要があります。


Step10. ローカライズされた事を確認

これでローカライズ対応は終わりました。言語表示が"英語"と"日本語"で検証してみてください。
切替方法は「Settingsアプリ > General > International > Language」となります。

もしうまく表示されない時はcleanするなり、アプリを一度削除する必要があります。


備考. 適当に試してみた

 

MainStoryboard_iPhone.strings(en.lproj)

/* UITabBarItemObject-IDUINavigationBar自体ではなく、Title部分のUIBarButtonItemな事に注意 */
"QxD-1d-LR4.title" = "Search";"hjG-GX-5Zj.title" = "Fav"; 
/* NavigationBar上のタイトル。Object-IDUINavigationBar自体ではなく、Title部分のUIBarButtonItemな事に注意 */
"udb-le-F0F.title" = "Localize"; 
/* UIBarButtonItem */
"HHM-r4-1XD.title" = "Push";
/* UILabel */
"3b5-Va-UMR.text" = "subakolab Inc."; 
/* UITextField */
"beM-F3-IQy.placeholder" = "hogehoge";"VKy-Ty-8Nf.text" = "input"; 
/* UIButton */
"Lrt-NR-GvK.normalTitle" = "tararara"; 

MainStoryboard_iPhone.strings(ja.lproj)

/* UITabBarItem */
"QxD-1d-LR4.title" = "検索";"hjG-GX-5Zj.title" = "お気に入り";
/* NavigationBar上のタイトル */
"udb-le-F0F.title" = "ローカライズ"; 
/* UIBarButtonItem */
"HHM-r4-1XD.title" = "押して"; 
/* UILabel */
"3b5-Va-UMR.text" = "株式会社スバコラボ"; 
/* UITextField */
"beM-F3-IQy.placeholder" = "ほげほげ";"VKy-Ty-8Nf.text" = "入力"; 
/* UIButton */
"Lrt-NR-GvK.normalTitle" = "たららら";


余談

 ブログに書くのが途中で面倒くさくなって投げそうになったのをグッと我慢して書いたのでゼヒゼヒお試しください。
何が面倒臭かったかと言うと今現在Bloggerのデザイン変更権限がアカウントに付与されてないせいで、ソースコードを綺麗にハイライトしてくれるjsを組み込めなかったせいで自分でハイライトさせた事ですね。そのままだと見難いし、でも面倒くさいしの間でたゆたってました。