2月
5

Xcode4.6でアプリの新バージョンをアップロードする手順

Author msota    Category 作業記録     Tags

拙作Swim Noteの新バージョンをアップロードしたので、その手順のメモ。前のバージョンと何も変わっていなかった。

0. 事前準備

  • スクリーンショットを取り終えておく
  • Xcodeでアプリのバージョン番号を設定しておく
  • (当たり前だけど)不要なログ出力等の余計な処理をしないようにする
  • (これも当たり前だけど)使わなくなったファイル等は消しておく

1. iTunes Connectでの作業(目的:新バージョン情報の登録)

  • SafariでiTunes Connectにログイン
  • 右側にあるManage Your Applicationをクリック
  • アップデートしたいアプリをクリック
  • 右下にある青いボタン「Add Version」をクリック
  • 表示された画面で、バージョン番号(このバージョン番号は、Xcodeで設定した番号と同じであること)と、アプリの更新内容を入力する。複数言語をサポートしている場合は全て記入する
  • 入力が完了したら、右下の「Save」をクリック→アプリ情報の画面になる
  • アプリ情報に表示されているメタデータやスクリーンショットを修正する場合は、画面中段の「Metadata and Uploads」のところにある「edit」をクリックする
  • スクリーンショットを入れ替える場合は、表示された画面の削除したいスクリーンショットのところで×ボタンを押して、一旦削除した後に「Choose File」をクリックしてアップロードする。表示する順番はドラッグ&ドロップで入れ替える
  • 修正が完了したら、画面右上の「Ready to Upload Binary」をクリック
  • Export Complianceという画面になり、ラジオボタンが2つ並ぶ。ここに書いてあるようなことをしていなければ「No」を選択し、右下の「Continue」を押す
  • Version Release Controlという画面になる。承認されたら自動リリースするか(上)、自分でリリースするか(下)を選択し、右下の「Save」を押す
  • アプリ情報の画面に戻る。Statusが「Waiting For Upload」になっていることを確認する

2. アプリのアップロード(Xcodeでの作業)

  • iOSデバイスをMacに接続し、Xcodeが正しく認識している状態にする
  • Productメニューから Archive を実行
  • Archiveが終了すると、自動的にOrganizer画面が開き、Archivesリストが表示される
  • リストにて作成したバージョンを選択した状態で右側の「Validate…」ボタンをクリック
  • iTunes Connectのユーザ名、パスワードを聞かれるので入力し「Next」ボタンをクリック
  • 表示されたApplication, Code Signing Identityが正しいことを確認して「Next」ボタンをクリック(検証処理をするため時間がかかる)
  • 検証で問題なければ「No issues were found in “アプリ名”」と表示されるので「Finish」ボタンをクリック→Organizerに戻る
  • そのまま「Distribute…」ボタンをクリック
  • Submit to the iOS App Storeを選択して「Next」ボタンをクリック
  • iTunes Connectのユーザ名、パスワードを聞かれるので入力し「Next」ボタンをクリック
  • 表示されたApplication, Code Signing Identityが正しいことを確認して「Next」ボタンをクリック(アップロードをするため時間がかかる)
  • アップロードで問題なければ「No issues were found in “アプリ名”」と表示されるので「Finish」ボタンをクリック→Organizerに戻る

3. 確認

Appleから「Your app status is Waiting For Review」というメールが来ているはず。iPhoneにiTC Mobileを入れていたらそちらにも。

7月
13

TapkuLibraryをXCode4に組み込む

Author msota    Category 逆引き備忘録     Tags

CoverFlowやカレンダーが使えるライブラリTapkuLibraryをXCode4で組み込んだ。

まず、ライブラリをgithubから取得する。

  • どこか適当にライブラリの置き場を決める(とりあえず~/Documents/dev/tapku にした)
  • ターミナルを開き、cdで置き場に移動
  • git clone git://github.com/devinross/tapkulibrary.git
  • ~/Documents/dev/tapku/tapkuLibrary ができる

続いて、プロジェクトに導入する。

  • XCodeで、TapkuLibraryを導入するプロジェクトを開く
  • 左側のツリーからFrameworksを選び、マウス右ボタンメニュー「Add files to project」を実行
  • 画面から ~/Documents/dev/tapku/tapkuLibrary/src/TapkuLibrary.xcodeproj を追加
  • 同様に ~/Documents/dev/tapku/tapkuLibrary/src/TapkuLibrary.bundle を追加

続いてBuild Phasesの設定をする。

  • PROJECTのTARGETSを選び、Build PhasesタブからTarget Dependenciesを選ぶ
  • +ボタンから、TapkuLibraryを追加する
  • 同じタブにある Link Binary With Libraries を選ぶ
  • +ボタンから、libTapkuLibrary.aを追加する
  • 同様に、MapKit、QuartzCoreを追加する

最後にBuild Settingsに追加する。

  • Build Settingsタブを選択する
  • タブの下にあるツールバーからAllを選択する
  • Header Search Pathsに、~/Documents/dev/tapku/tapkuLibrary/src/ を追加する
  • Other Linker Flagsに、-all_load -ObjC を追加する

アプリケーションへの組み込みは、当然ながらXCode3の時と同じ。

7月
12

カスタムキーボードを作成する

Author msota    Category 逆引き備忘録     Tags

iPhoneで文字入力する際のキーボードを、カスタムキーボードに変更した。目的としては、定型文しか入力しないフィールドに対して選択肢を用意し、入力を簡単にすることである。

それだけを目的とするならピッカーでも同じことはできるのだが、現在作っているアプリケーションでは、ピッカーをグルグル回して選択するよりも並んでいるボタン状のものから選ぶ方が好ましいと思われたので、カスタムキーボードにした。

さらに言うと、単に選ぶだけならUIAccessoryViewを使っても同じようなことが出来そうだが、本来のキーボードも併用して切り替えられるようにしたかったので、カスタムキーボードにしてみた次第である。

大雑把な手順は以下の通り。

  1. UITextFieldクラスを継承して、カスタムテキストフィールドクラスを作る(CustomTextFieldとする)
  2. Interface BuilderでCustomTextFieldをビューに配置する
  3. カスタムキーボードに相当する新しいxibファイルを、UIViewベースで作成する(CustomKeyboardInputViewとする)
  4. xibファイルをInterface Builderで起動し、入力選択肢(キーボードのキー)に相当するボタン(UIButon)を配置する
  5. 3. で作成したカスタムキーボードに対するビューコントローラクラスを作成する(CustomKeyboardInputViewControllerとする)
  6. 5. で作成したビューコントローラを、4. で作成したxibでFile’s Ownerに対するビューコントローラに設定する
  7. 1. で作成したCustomTextField.mを編集し、inputViewメソッドをオーバーライドする。このメソッドで、3.で作成したxibを使ってビューコントローラ(4.で作成したCustomKeyboardInputViewController)を生成し、そのビューコントローラに対するビューを戻す
  8. CustomKeyboardInputViewController.mを編集し、ビュー上のボタンが押された際のメソッドを記述し、呼び出し元となったカスタムテキストフィールド(CustomTextField)に適切な値をセットする

当然ながら、Interface Builderではなくプログラムでガリガリ書いても同じ(はず)。

この手法の考え方としては、UITextFieldやUITextView(を継承したサブクラス)のinputViewメソッドをオーバーライドして、新たに定義したキーボード(のUIView)を返すようにすれば、カスタムキーボードを表示できる、というものである。

一旦キーボードを表示してしまえば、あとは通常のビュー間でのデータのやりとりと同じ手法で、カスタムキーボードの呼び出し元になったテキストフィールドに、カスタムキーボードで選択したボタンに相当する値をセットしてやればよい。

サンプルソースは以下の通り。
本筋とは関係ない処理は全て削ってある。
本来は、本来のキーボードと切り替えるためのAccessoryViewを作ったり、その切り替え処理を組み込んだり、キーボードで選択したボタンに対する処理など、色々とやることはあるのだが、それらは除外した。

CustomTextField.h

#import 

@interface CustomTextField : UITextField {

}

@end

CustomTextField.m

#import "CustomTextField.h"
#import "CustomKeyboardInputViewController.h"

@implementation CustomTextField

- (UIView *)inputView {
	CustomKeyboardInputViewController *vc = [[CustomKeyboardInputViewController alloc] initWithNibName:@"CustomKeyboardInputView" bundle:nil];

	return vc.view;
}

- (void)dealloc {
    [super dealloc];
}

@end

カスタムキーボード呼び出し元になるxibの設定

カスタムキーボード表示対象のテキストフィールド(上で作成したCustomTextField)をビューに配置する。

カスタムキーボード自体のxib

実行結果

ビュー上のテキストフィールドを選択すると、カスタムキーボードが表示される。

キーボード選択値をテキストフィールドに設定

キーボードでのボタン選択で、テキストフィールドに値をセットするためには、カスタムキーボードのビューコントローラでボタンの処理を実装する。例えばこのようになる(テキストフィールドのプロパティをキーボードのビューコントローラ側に持たせるのはあまり良いやり方ではない気がするが、とりあえずそこは無視)。

まず、CustomKeyboardInputViewController.h で、対象テキストフィールドとボタンの処理を宣言。

#import 

@interface CustomKeyboardInputViewController : UIViewController {
	UITextField *tf;
}

@property (nonatomic, retain) UITextField *tf;

-(IBAction) btPressed:(id) sender;

@end

CustomKeyboardInputViewController.m で、ボタンの文字列をテキストフィールドにセットする。

#import "CustomKeyboardInputViewController.h"
#import "CustomKeyboardTestViewController.h"

@implementation CustomKeyboardInputViewController

@synthesize tf;

-(IBAction) btPressed:(id)sender {
	// キーボード上のボタン選択値をテキストフィールドにセット
	UIButton *bt = (UIButton *) sender;
	[self.tf setText:bt.titleLabel.text];
	
	// キーボードを隠す
	[self.tf resignFirstResponder];
}

@end

カスタムテキストフィールドのメソッドを少し変えておく。

#import "CustomTextField.h"
#import "CustomKeyboardInputViewController.h"

@implementation CustomTextField

- (UIView *)inputView {
	CustomKeyboardInputViewController *vc = [[CustomKeyboardInputViewController alloc] initWithNibName:@"CustomKeyboardInputView" bundle:nil];
	
	vc.tf = self; // これを追加
	
	return vc.view;
}

- (void)dealloc {
    [super dealloc];
}

@end

キーボードのxibを編集して、各ボタンからの処理を呼出すようにする。

7月
6

PIAZZA Database for iPhone リリース

Author msota    Category PIAZZA Database     Tags

自分にとって初めてのiPhoneアプリケーション「PIAZZA Database」がリリースされた。クルマ全体の写真がほとんど無いとか、Webの内容を単にアプリケーションにしただけじゃないかとか、言い出したらきりがないほどショボいアプリケーションだ。しかし、そんなものではあっても、Apple製品利用歴17年目にして、自分が作ったものがAppStoreに並ぶというのは、なかなか感慨深いものがある。

自分が初めて作成したWebサイトもPIAZZA関連だったが、その約15年後に初めて公開したiPhoneアプリケーションもまたPIAZZAモノだったというのは、何かの縁だろうか。単なる腐れ縁か。

開発の経緯は以下の通り。何となく作ったアプリケーションだったが、Rejectされることなく、すんなりリリースされた。

  • 2009年の夏頃、何となくiPhoneアプリを作ろうと思い立つ
  • とりあえず本を買ったりしてシミュレータで動かしたりしてみたが、いろいろと多忙で自然消滅する
  • そのまま約2年が経過する。折角買ったMacBook Proは、単なる省スペースデスクトップ機になる
  • 2011年の5月頃、何故か再度思い立つ
  • 6月頃、ちょっとしたGUI操作やCoreDataのハンドリングでいちいちひっかかるので、考えを改める。とりあえずもっと簡単な、参照系だけのアプリケーションを作ってリリースまでのプロセスを体験しよう、という方針とし、PIAZZAのサイトデータをアプリケーション化することにしてみる
  • 6月中旬、それらしいものが出来たので、実機で試すべく、Developer Programに登録する(10,800円)
  • 6/28 AppStoreに申請する
  • 6/30 In Reviewになる
  • 7/5 Ready for Saleになる

結果的にはスムースにリリースされたが、一部特殊な事情があり、つまらないところに色々と気を遣った。何か一つでも見逃していたらRejectされていたかもしれない(されなかったかもしれない)。

  • 商標関係で勇み足をするとRejectされるため、いすゞ自動車の商品名である「PIAZZA」をアプリケーション名に使うことがまず課題だった。しかしCAMAROやCORVETTEを冠したアプリケーションで、どうみても個人作のものが実在するので、おそらく車名だけなら問題ないと考えた
  • とりあえず、アプリケーションおよびAppStoreの説明に「いすゞ」「ISUZU」は入れないようにした
  • 元データは、自分が管理するサイト「JR EAST JAPAN」のものだが、JR EAST JAPANというサイト名自体が特定の企業名との関係で問題になる可能性があるため、アプリケーションのInfo画面やAppStoreの説明にも一切記載しないことにした
  • サポートサイトの説明からも、とりあえず危ない用語は省いた(そしてリリース後に戻した)
  • そもそも、こんなアプリケーションをAppleは認可するのか(→出してみなけりゃわからないので、出してみた)

こうして、いわば習作的なアプリケーションがそのまま世に出てしまった。元サイトが変わらない限りこのアプリケーションも変えようがないので、当面はこれ以上進化する予定はない。気が向いたら何かするかもしれないが、リリース手続き以降は他のアプリケーション開発に入ってしまったので、正直言ってマインドがこのアプリケーションに向いていない。それほど、このリリース待ち期間は長い。噂には聞いていたが、長い。

とはいえ、車種別のiPhoneアプリケーションが存在する車種もそうそう無いはずだから、車名(アプリケーション名)の名を汚さないように、恥ずかしくない程度にはメンテナンスするつもり。

7月
6

iOS4以降でのビュー切り替えとアニメーション

Author msota    Category 逆引き備忘録     Tags

ビューを切り替える場合(に限らないが)のアニメーション記述方法がiOS4から変更になった。ネットで探してみても、iOS4以降の記述方法があまり見つからなかったのでメモしておく。

結果的にはかなりシンプルになっている。
長いので改行しているが、ビューの切り替えも含めて、1文で終わってしまう。

ちなみに以下のoldVC、newVCは、変更前後のビューに対するビューコントローラ。

iOS4以降の場合

	[UIView transitionFromView: oldVC.view
		toView: newVC.view
		duration:0.5 
		options:UIViewAnimationOptionTransitionCurlDown
			completion:^(BOOL finished){
				/* do something on animation completion */
	} ];

(参考)iOS3.xまでの場合

	// アニメーション
	[UIView beginAnimations:@"flipping view" context:nil];
	[UIView setAnimationDuration:1];
	[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
	[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown 
							   forView:self.view cache:YES];

	// Change View
	[oldVC.view removeFromSuperview];
	[self.view addSubview:newVC.view];
	
	[UIView commitAnimations];