ラベル 開発 の投稿を表示しています。 すべての投稿を表示
ラベル 開発 の投稿を表示しています。 すべての投稿を表示

2011年2月4日金曜日

TestFlight 経由のアプリのダウンロード速度を調べてみた




最近 iOS 界隈を賑わせている TestFlight というWebサービスがあります。詳細についてはまぁ TechCrunch さんでも読んでいただくとしまして、この TestFlight が非常に便利そうなので私のほうでも早速試してます。登録も簡単、アプリのマネジメントも良くできていますし、チームを複数用意して管理できるというのも良いです。なんで Apple がデフォルトでこれを用意してくれないのかというぐらい便利です。

が、一つだけ気になったことがあって、まぁタイトル通りなのですが、TestFlight経由だとアプリのダウンロードが遅いのではないか?ということです。ということで実際にやってみました。


■条件

対象のアプリのサイズは17.7MB。
以下の2カ所の回線で計測しました。
  • 会社の回線(確かバッファロー, IEEE 802.11g, だいたい300KB/s程度)
  • 自宅の回線(AirMac Extreme, IEEE 802.11n, だいたい1MB/s程度)

■結果

会社の回線・・・ダウンロードに12分~15分程度
自宅の回線・・・ダウンロードに1分前後、インストール完了まで2分ちょっと

それぞれ別の日に計測したので何とも言えませんし、会社の回線は自分以外の人も使うので遅いときがあるのですが、およそ

遅いとき・・・20KB/s程度
早いとき・・・300KB/s程度

とまぁずいぶん幅がある結果になってしまいました。どうやら時間帯や相手のサーバー側の混雑具合によっても速度が違ってくるようです。いずれにせよそんな猛烈に速いわけではないので注意が必要そうです。たとえば100MBぐらいあるゲームアプリをテストしたいときなどは、今まで通りの地味な配布のほうがよい・・・ということもあるかも。


■余談:TestFlightってどれぐらいのファイルサイズまでアップロードできるのか?

と思って調べてみたらありました。500MBだそうです。400MBのファイルを実際にアップした人がいるみたいです。
http://support.testflightapp.com/discussions/questions/60-max-file-size-on-build-upload

2010年12月29日水曜日

はじめての iPhone 開発時にお勧めの本 3 冊

2010/12/29追加: 本を追加したり中身を最新のものにしたりしました。

@monjudoh に社内チャットで
[10/09/17 17:18:12] 文 殊堂: heyあきすて
[10/09/17 17:18:32] 文 殊堂: iPhoneアプリ開発でいい本とかある?
[10/09/17 17:19:42] akisute: yoじゅどうもん
[10/09/17 17:19:43] akisute: たくさんあるぜ
[10/09/17 17:19:52] wozozo ☿: yo
[10/09/17 17:19:53] akisute: なんかみんなから同じ質問されるからブログに書くわ
とか言われたので、お勧め本をまとめてみることにしました。2年前にも似たようなものを書いたような気がしますけど、2年が経過していますから、いろいろと状況も変化していますしね。

4797361786詳解 Objective-C 2.0 改訂版
荻原 剛志
ソフトバンククリエイティブ 2010-12-17

by G-Tools


2年前にも詳解しましたがこいつはバイブルです。改訂版になってBlockがらみの記述が増えたり、iOSについての言及が増えて、さらに良書になりました。四の五の言わずに買っておくと良いです。ただし、どちらかというとObjective-Cに焦点を置いている本であり、iOSで何ができるか、ということについてはほとんど記載がないので注意してください。

4797358106はじめてのiPhone3プログラミング
Dave Mark Jeff LaMarche 鮎川 不二雄
ソフトバンククリエイティブ 2009-12-17

by G-Tools


こちらは iOS のバイブルです。初めて挑戦する人に最適ですが、ある程度熟練した人が見ても発見がある良書です。およそ必要なことはすべて得られると思います。

4897978440iPhoneプログラミングUIKit詳解リファレンス
所 友太 京セラコミュニケーションシステム株式会社
リックテレコム 2010-01-12

by G-Tools


UIKitに焦点を置いて書かれている本です。図解が多く、全くiOS開発をしたことがない人でもどのようなUI要素が使えるのか見て学べるため大変おすすめです。

2010年11月16日火曜日

iOS で正規表現を使う (3.0, 3.1, 3.2, 4.0)

iPhone / iPad アプリで正規表現を使いたいときはどうするのか調べてみました。


■iOS 4.0以上

NSRegularExpression があるのでそれを使えば万事解決です。


■iOS 3.2

http://blog.livedoor.jp/pnfhy316/archives/277806.html
こちらのブログでご紹介されているとおり、NSString rangeOfString:options: で NSRegularExpressionSearch を指定するのが楽です。

正規表現のグループ参照はできませんけれど、まぁしょうがないですかね。


■iOS 3.1, 3.0

http://d.hatena.ne.jp/KishikawaKatsumi/20081031/1225463896
こちらのブログでご紹介されているとおり、ライブラリを使うのがよいようです。

または最近調べてわかったのですが、 NSPredicate を以下のように使うと正規表現によるマッチングが可能になる模様です。
NSString *path = @"/path/to/img/img10001.png";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ matches '.*/img[0-9]{5}\\.png'", path];
BOOL matched = [predicate evaluateWithObject:nil];
キモは NSPredicate の format として matches という構文が使えることと、その中で正規表現が使用できるところですかね。実機の iOS 3.X で試したわけではないのですが、 NSPredicate 自体が iOS3.0 から使用可能になっていることと、 NSPredicate format 関連のドキュメントを見ても特に利用制限とかは書いていなかったので、普通に3.0から使えるんじゃないかと思ってます。もしよろしければ動作報告いただけるとうれしいです。


■iOS 2.X

iOS界のIEだと思って忘れましょう。お客さんに「頼むから対応してくれ」と言われても突っぱねる(すでに全体の1%以下ぐらいのはず)のがベストです。

2010年9月12日日曜日

iPhone 開発規約まとめ

あんまり iOS 上での開発規約とか見かけないので、試しに私が今個人/会社で使っている開発規約を公開してみることにしました。


■設計

設計は所謂 MVC と呼ばれる設計モデルを採用します。ただし、厳密な MVC というわけではなく、以下のような区分になっています。
  • Model
    Core Data を使用します。通常 MVC での Model というと業務ロジック等を含めた業務モデル一般すべてを含むのですが、私の場合は特に Core Data の NSManagedObject を Model として扱い、 Model 単体のみで完結するロジックのみを Model に記述します。たとえば、
    • Core Data から対象の Model とその関連 Model 取得
    • Model の新規作成
    • 新規作成時、更新時に自動的に Model のプロパティを更新する
    • Model のプロパティの値を元に幾何学計算をしたり、一時的に使うキャッシュを用意したりする
    などです。実際のコードのサンプル (ニュースサイトのニュースを表す News モデルの実装) はこんな感じになります:
    #import "News.h"

    @implementation News

    @dynamic body;
    @dynamic title;
    @dynamic imageURL;
    @dynamic objectId;
    @dynamic dateCreated;
    @dynamic dateUpdated;
    @dynamic sortOrder;

    @end

    //----------------------------------------------------------------------------------------
    // ここから上は .xcdatamodel ファイルから自動生成されたコードなので触れないようにします。
    //----------------------------------------------------------------------------------------

    #import "AppDelegate.h"

    @implementation News (NSManagedObject)
    - (void)awakeFromInsert {
    [super awakeFromInsert];
    // Insert
    self.dateCreated = [NSDate date];
    }
    - (void)willSave {
    [super willSave];
    // Update
    // DO NOT DO THIS in here because updating self.dateUpdated will call -willSave method recursively until this application crashes!
    // Use NSManagedObjectContextWillSaveNotification / NSManagedObjectContextObjectsDidChangeNotification and watch the time delta of previous change
    // If the time delta is small enough to ignore, do not update dateUpdated property to avoid infinite loop
    //self.dateUpdated = [NSDate date];
    }
    - (void)awakeFromFetch {
    [super awakeFromFetch];
    // Select
    }
    @end

    @implementation News (DBAccessors)
    + (NSArray *)all {
    AppDelegate *appDelegate = [AppDelegate appDelegate];
    NSFetchRequest *request = [appDelegate.managedObjectModel fetchRequestTemplateForName:@"allNews"];

    // Sort by sortOrder, ASC
    NSArray *sortDescriptors = [NSArray arrayWithObjects:
    [[[NSSortDescriptor alloc] initWithKey:@"sortOrder" ascending:YES] autorelease],
    nil];
    [request setSortDescriptors:sortDescriptors];

    NSError *error = nil;
    NSArray *resultArray = nil;
    if (!(resultArray = [appDelegate.managedObjectContext executeFetchRequest:request error:&error])) {
    // handle the error;
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    return nil;
    }
    return resultArray;
    }
    + (id)get:(NSString *)targetId {
    AppDelegate *appDelegate = [AppDelegate appDelegate];
    NSDictionary *substitutionVariables = [NSDictionary dictionaryWithObject:targetId
    forKey:@"objectId"];
    NSFetchRequest *request = [appDelegate.managedObjectModel fetchRequestFromTemplateWithName:@"getNews"
    substitutionVariables:substitutionVariables];

    NSError *error = nil;
    NSArray *resultArray = nil;
    if (!(resultArray = [appDelegate.managedObjectContext executeFetchRequest:request error:&error])) {
    // handle the error;
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    return nil;
    }
    return [resultArray lastObject];
    }
    + (void)deleteAll {
    AppDelegate *appDelegate = [AppDelegate appDelegate];
    NSFetchRequest *request = [appDelegate.managedObjectModel fetchRequestTemplateForName:@"allNews"];

    NSError *error = nil;
    NSArray *resultArray = nil;
    if (!(resultArray = [appDelegate.managedObjectContext executeFetchRequest:request error:&error])) {
    // handle the error;
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    return;
    }

    // Delete all objects fetched
    for (NSManagedObject *obj in resultArray) {
    [appDelegate.managedObjectContext deleteObject:obj];
    }
    }
    @end
  • Operation
    本来の MVC モデルには存在しませんが、私は特別に Operation という区分をもうけています。定義は以下の通り。
    • 一つの業務モデル、業務ロジックを完結させるひとまとまりのロジックであること。要するに本来の MVC モデルの業務ロジック的要素であること。 もっと言うなら Operation だけを切り出して単体テストできること。
    • それなりに重要でかつ量があり、 Controller や Model から共有的に呼びだされること。
    • 非同期で処理ができること。
    • NSOperation クラスのサブクラスにすること。
    たとえばインターネット経由で API を実行して結果を Model に突っ込む処理などは Operation として実装しています。 NSOperation として実装することで、非同期処理が簡単にできるようになるだけではなく、 タスクの依存関係を決めて先に親タスクが実行されるのを待つようにしたり、現在の状態を厳密に判定したり、タスクをキャンセルしたりするのが容易になります。また、将来的に iPhone / iPad のCPUがマルチコアになった場合、 NSOperation を継承しておけばほとんど何もしなくてもその恩恵を受けることができるはずです。
  • View
    ビューです。主に UIKit および Three20 を用いて構築し、必要に応じてその他のビューライブラリを組み込みます。個人的には UIView のサブクラス一般をすべて View として扱っています。 View には描画ロジックと幾何学計算などの補助ロジック、およびそれに必要な最小限のデータのみを持たせるようにします。状態を持ってもかまいませんが、状態のコントロールを View 自身が行うのはできる限り避けます。タッチイベントのハンドリングは必要に応じて View で touchesBegin: などを実装して行いますが、基本的には Controller 側で UIGestureRecognizer を用いて行います。
  • Controller
    コントローラーです。私の中での定義は UIViewController のサブクラスです。アプリの内容に応じて UIKit と Three20 を使い分けます。 本来 Controller は全体の流れのみを管理し実際の処理を行ってはならないということになっていますが、 UIViewController の性質を鑑みて、私は次のように Controller の役割を定義しています。
    • View の管理。
    • 画面遷移, 要するに Controller 間の遷移の管理。
    • タッチイベント、ジェスチャイベント、加速度計などからの入力の受付と処理。
    • 各種 UI コンポーネントの Delegate 処理。 UITextView, UIPopoverController, UIActionSheet, などなどなど多岐にわたります。
    • Operation 完了時の処理など、各種 Notification を受け付けて処理。
    • 上記に必要になるデータ/メソッドの定義。 View に持たせるぐらいならこちらに持たせる。他に持たせるところがないなら Controller にすべて持たせる。
    ということで、 Controller を名乗っていますが実際にはかなり自分で処理をします。こんなのいちいち分けていたら大変ですし・・・といういいわけです。実際のコードサンプルはお見せできないのですが、実装の概要はこんな感じです



  • Application Delegate
    これも本来の MVC モデルには存在せず、本来は Controller として扱うべき物だと思いますが、私は特別に分けています。 Application Delegate は所謂アプリケーショングローバルなデータや設定、オブジェクト、ユーティリティメソッドを管理するものとして扱います。たとえば、
    • Operation 駆動用の NSOperationQueue
    • Model のための NSManagedObjectContext / NSManagedObjectModel / NSPersistentCoordinator
    • 現在通信可能か否かを判定するためのユーティリティメソッド
    • アプリケーショングローバルな Notification を受け取って Application Delegate のプロパティとしてセットする
    などです。これらはほぼすべてのアプリで絶対に必要になるのでテンプレ化しています。


■Xcodeプロジェクト

プロジェクトのグループはこんな感じで分けます。



ビルド設定については、プロジェクト全体のビルド設定は可能な限り使わないようにして、ターゲットごとのビルド設定 ( Cmd+Option+E ) を主に使います。ターゲットが例え複数に分かれても常に同じ物を使うところはプロジェクト全体の設定を変更します。


■命名規則

大体以下のような方針でやっています。
  • Foundation や UIKit など Apple の使っている命名規則に似せること。似てないシグネチャは即リファクタリング対象。
  • ミススペル、Typo、意味のわからない英単語 ( registとか ) は一文字一単語であろうとも発見した瞬間即リファクタリング対象。英語辞書のソースは http://www.alc.co.jp/ とする。
  • 名前はどれだけ長くなろうとも絶対に省略しないこと。 updUniqUsr とか発見したら即リファクタリング対象。逆に BPSuperDuperViewControllerDidFinishedUberTaskNotification とかは表彰モノ。
    • これを BPSDVCDFUTN とか略した奴が現れたら即 SATSUGAI モノです


■まとめ

ここまで書いておいて何ですが、要するに 一貫した基準があるなら 自分らの好きなようにするのが一番いい のかなと思います。

2010年8月29日日曜日

自分なりの iPhone アプリ開発手法とかこだわりとか書いてみた

Twitter で vの人こと @voluntas さんに されたので、自分なりのポリシーとかこだわりとか開発手法とかをまとめてみることにしました。今仕事で iPhone アプリの開発を主にやっているので、 iPhone アプリに関する内容が多いですが、それ以外の開発でも使えると思います。

あまり技術的な内容やツールに関する内容はありません。それらは別エントリーにまとめようと思います。


■大前提: 自分を知る
まず何はなくともこっからです。なんだか開発とか全然関係ないじゃないか、怪しい自己啓発じゃねえかと思われるかもしれませんが、敵を知り己をを知れば百戦危うからずと昔のエライ人も言ってます。それにそもそも私がどのような人間なのかを理解しないと、せっかくの開発手法もそのまま真似してはうまく合わない・上手く回らない・賛成できないということになりますので、非常に大事だと思います。ということでさっそくまとめてみました。
  • 恐ろしく几帳面である
    A型人間です。
    Java とか大好きです。逆にカオスなコードが苦手で、 PHP とかは敵です。
    掃除してない @feiz@shin_no_suke の机とか見てると勝手にゴミを捨てたり掃除したくなります。
    Typo とか見つけたら人のコードでも勝手に直します。 Typo するのが嫌なので毎回変数名を決める前に英語辞書を引きます。
  • ゆとりである
    一日の労働時間は八時間までよねー(キリッ
    なのでとにかく楽をしたがりです。
    そもそも体力が小学生並なので徹夜仕事とかできません。そのような事態に陥らないような仕事の進め方が必要になります。
  • やたらこだわる
    好きなモノは徹底的に好きで嫌いなモノは徹底的に嫌いです。なので評価が極端で言動が偉そうです。すみません><
    一歩間違えるとただの頑固者になるので気をつけています。
  • 言動は偉そうだけれども中身は非常に臆病者で弱い
    なのでゆとりを失うと一気に迷走します。余裕を常に持てるようにする必要があります。
    また周りの皆さんの支援ないと生きていけないと思っていますので、「生意気だけれどもイイ奴」ぐらいのポジションに落ち着きたいと思ってます。
  • iPhone は俺の嫁、 Cocoa Touch は神環境
    もう二度と iPhone の無い世界には戻れません。
    10年後ぐらいにはまた別の面白いものがあると思いますが、今のところは iPhone が一番面白いです。
似たような方は私と同じやり方を真似してもいいし、真逆な方は私のやり方と真反対をやればうまくいくのではないかと思います。


■三つの大戦略
私がどういう人間か分かったところで、次は今の仕事のやり方に関して最も根底にある三つの大戦略をまとめてみました。この大戦略にはほとんどツールや言語の話が登場しません。それらは時代が変われば変化してしまうからです。それよりもむしろ、どういう考え方やポリシーで仕事をすれば最も開発生産性が上がるか、というところに着目しています。
  • 徹底的に几帳面にやる
  • 楽をする・楽しむ・楽をさせる・楽しませる
  • 二度とガラケーには戻らないと決心しその通りに行動する
徹底的に几帳面にやる
几帳面なのが武器なので、それを徹底的に生かす方針で開発を進めます。また几帳面さは Objective-C と非常に相性がよいです。たとえばメモリリークが発生してから調査すると非常に大変ですが、発生する前に防ぐことができれば生産性がそれだけ高まるはずです。また KVC/KVO や Core Data など動的言語のような処理を行う箇所では一文字のスペルミスが発見しづらいバグにつながるため、スペルミスチェックを行ったり、命名規則の策定をしたりする必要がありますが、このとき几帳面さが効果的に働きます。
また、余りつまらないところでミスを連発するとテンションも下がるしリズムも崩れ、余裕が無くなってしまい結果として悪いモノができあがってしまうので、それを防ぐためにも几帳面にやるのが効果的だと思ってます。
なにより、これが一番大事だと思うのですが、几帳面にコードを書くのが自分にとって一番楽しく、モチベーションが上がります。つまり逆に言えば、リズミカルにどんどん細かいところを気にしないでガーッとたくさん作るほうが楽しくリズムに乗れてモチベーションも上がる人でしたら、そのようにする方が良いと思います。

楽をする・楽しむ・楽をさせる・楽しませる
四楽運動です(何それ
要するに、
自分が楽したい、仕事量は減らして簡単にしたい
仕事は楽しんでやりたい、面白い技術を使ってやりたい
でも自分ばっかり楽したら申し訳ないし楽した分だけしっかりやって楽をさせてあげよう
それにせっかく作るなら楽しいモノを作った方がいいに決まってるからそうしよ
ということです。
この方針に従うと、私の場合、楽ができて楽しいだけではなく、「このようなすばらしい環境で開発させて貰ってありがとう」という感謝の気持ちと「それなりの成果を出さなくてはならない」という責任感が自然と発生するため、非常に開発効率が高まるようです。

二度とガラケーには戻らないと決心しその通りに行動する
うちの会社でもガラケー向けのWebアプリの開発をやっていて、その際の苦労話を聞く機会があります。また、企画やお仕事の提案などでGREEやモバゲーなどのガラケーアプリを見せて貰うことがあります。そのような経験から思うのは、
ガラケーはIE6とか比較にならないほど苦労するくせにどうしようもないユーザー体験しか提案できない最悪の開発環境
だということです。たとえばメールの文字コードの扱いとか、特定の機種だけ動かないとかで50台以上の実機でテストしないと駄目とか、Flash lite 1.1はまともに使えないからサーバー側でバイナリ操作してSWFを生成して送り返しているとか、そんなネタを聞くたびにこう、ふつふつとしたものが沸いてきます。
その上お金になるからかバッドノウハウだからか知りませんが、驚くほど情報が出回っていない。調べてもなかなか分からない。とにかく開発者に優しくありません。なによりバッドノウハウを運用しても楽しくない上にイライラして嫌なムードになってしまいます。
確かにガラケーの環境はお客さんからお金を取りやすく儲かりやすいため、会社で取り組むには非常に好都合であるとは思うのですが、やはり私は開発者の身である以上、素直に開発者に優しく、さらには素晴らしいユーザー体験を提供できる環境を選びたいのです。さらに思うだけでは駄目で、実際に iPhone の開発で仕事を取って継続的にお金を稼げるようにしなくてはならないので、そうなれるよう実際に行動する必要があります。


■「徹底的に几帳面にやる」を達成するための戦略
  • 面倒くさがらずにリファクタリングする
    リファクタリングは大事です。納得いくまでリファクタリングします。一文字Typoしたら名前変更、名前が後から気に入らなくなったら変更、クラスの構造を変更、メソッドをパブリックに変更、エトセトラエトセトラ。リファクタリングは他の人がコードを読んだ時の理解を助けてくれるだけではなく、自分自身がリファクタリングのためにコードを理解することになり、今後の設計に役立ちます。自分の考えを整理するという意味でも大事だと思います。
  • 細かくスタートして、ちょっと作って確認し、またちょっと作って確認して繰り返す
    特に iPhone での開発は小規模で変更や追加が多く、アップデートも頻繁。必然的にアジャイルな開発が要求されます。そしてなにより、テストケースを書いてテストドリブンで開発するだけの時間的余裕がありません。そんな贅沢なやり方ができるのは長期でずーっとやっていくWebサービスや大規模なシステムだけで、作ってすぐ放棄される事が多い iPhone の開発にはテストドリブンは全く向いていないと思っています。
    しかしながら、品質は当然担保しなければなりません。そこで私は小さく作ってすぐに作った箇所を確認し、また少し作って確認・・・という手法をとっています。正しく作る単位をモジュール化することができれば、一端テストしてその部分の品質が保証されればその後の開発ではテスト済みのモジュール内の事は考えなくて済むからです。テスト自体が大変でコストがかかるので、やはりコーディングの段階で几帳面にバグを出さないようにするというのが一番に思えます。
  • 一番面倒で難しそうなところからスタートする
    ほとんどの技術者の方はこのような手法を取られていると思うのでわざわざ書くほどのものでもないのですが、それでも一番面倒で難しそうなところからスタートする手法は非常に有効です。上記の手法とも合わせ、一番難しそうなところ一番最初に小さくスタートしてすぐにテストし、品質を保証してしまうのが最も有効です。全体の2割のコードに全体の5割ぐらいの時間をかけて作り、残りの半分はコピペしてプロパティをちょっと書き換えるだけでざざーっと作れるようなところにしてしまう、というのが理想だと思ってます。
■「楽をする・楽しむ・楽をさせる・楽しませる」を達成するための戦略
  • 取捨選択をする
    ソフトウェア開発で楽をするための一番よい方法は、作らないことです。取捨選択を適切に行ない、不要な枝を切り捨て、必要な枝・競争力のある枝にすべてのエネルギーを集約することで、個性的なアプリを作り出すことが出来ます。個性的でないアプリは供給過多の市場に埋没します。さらに取捨選択は作業をすすめる最中でも大いに役立ちます。たまにお客さんから「あれもなる早、これもなる早、全部最優先で」とかいうお前日本語間違ってるだろといわんばかりの指示が飛んできたりしますが、これは全く話になりません。「最たるもの」とは常にひとつしか存在しないもので、だからこそまずそれから仕事にとりかかることができ、余計な仕事の順序選択思考を避けることができるのです。私自身が優先順位をつけたり指示を出したりする際にも、最優先がひとつ、次に優先がふたつ、それ以下はすべて後回しか切り落としです。そもそも、三つよりたくさんを記憶して同時に処理できる人はまれです。
  • 偉い人の作ったフレームワークとかライブラリをどんどん使わせていただく
    ソフトウェア開発で楽をするための二番目に良い方法は、すでに完成しているものを取り込むことです。ということで、フレームワークやライブラリなどは積極的に活用します。ライセンスには気をつけないと大変なことになりますので注意ですが、これらのフレームワークやライブラリは私よりも遥かにすごい人達が時間と手間をかけて作り上げられ、テストもしっかり行った上で公開されているものが多いので、私自身が実装するよりも遥かに信頼できると思っています。もちろん人が作ったものなのでバグや合わない仕様はたくさんありますが、ソースコードを読んで修正すればよいのです。ゼロから自分が作るよりは断然良いです。
  • とにかく自動化する
    とかく人間というのは、単純作業をミスすることにかけては超一流です。頻度の差こそあれ誰しも必ず単純作業をミスします。さらに単純作業は集中力という貴重なリソースを消費します。
    二回以上繰り返す単調作業は自動化する。それがたとえ、ソースコードをzipで圧縮してメールでお客さんに送るといった簡単な作業であったとしても、自動化しておくのは非常に役に立ちます。単純作業を避けることで生まれた余剰集中力を、別のところに振り分けることができます。
    自動化する手法がわからなかったら調べて勉強します。ここでちょっとわからなくて面倒だからと避けると後から地獄を見ますし、成長できないので、意地でも調べます。
  • 自分に要求されている責任範囲以上の仕事を引き受けて楽をさせてあげる
    私は最初の会社の新人教育の際に、「自分が要求されている以上の仕事をしろ」と繰り返し教えられました。実際最初の会社はどちらかというとブラックに属する部類だと思いますし、こういう教えは社畜だの何だのと言われているようですが、私はこの「自分が要求されている以上の仕事をしろ」という考えが好きです。
    確かに前の会社で仕事をしている間はこの考えは嫌いでした。なぜなら仕事がつまらない上に余計なことをすると怒られる職場だったからです。バグだらけの共通ライブラリを修正したら余計なことをするなと怒られ、酷い出来栄えのJavaScriptを救済するためにjQueryを突っ込んでみたらこれまた余計なことをするなと言われ。まったくどうしろと・・・。
    しかし今は違います。仕事の内容は全部任せていただいていますし、効率化も推奨されています。画像リソースがお客さんからやってこなければ自分で作り、画面の仕様が決まらなければ私が決めて作ってお渡しし、セールスのためにアプリレビューを行ってくれるブログ一覧をまとめてお渡しするなど、とにかく仕事が円滑に進むと思えばなんでもやります。面倒なときもありますが、それより相手の仕事が遅くってイライラして「あいつが悪い、あいつのせいでプロジェクトが失敗した」とか考える方が嫌です。それにちょっと勝手にやりすぎたかと思っても、意外なほど喜んでもらえます。
    ただし、何でもかんでもこの方法で一人で引き受けていると私の仕事量が破綻するので、この方法で引き受けるのは一過性の仕事だけにしています。定期的にやらなくてはいけない仕事は自動化するか、やり方を教えてあげてやってもらいます。
  • 細部にこだわれるだけのスケジュール上の余裕を常に持つ
    リファクタリングしたり、自分に要求されている範囲以上の仕事をすると、どうしても当初見積りより遥かにたくさんの時間がかかることになります。それにプロジェクトには絶対にトラブルが付きものです。ということで、時間的なゆとりが必要です。私は見積りを提出する際に、自分で余裕を持ってできる見積りに、さらに1.5をかけて提出したりします。提出するときにはこれ時間がかかりすぎじゃないかと言われないかヒヤヒヤしますが、バグを取ったりクオリティを上げたり、突然湧いたトラブルに対処しているうちに、最終的にはそれで大体丁度良くなるので不思議です。お客さんにとっても納期遅延が発生しないため、今のところ大変ご満足頂いております。
    特に iPhone アプリはこの余裕を持ってアプリのクオリティを上げる方針が有効に働きやすい気がします。修正が比較的簡単ですぐに行えるWebアプリに比べ、リリースを急いだとしても、ひとたびバグが原因でリジェクトされるとリリースが一週間遅れ、醜いアプリをリリースするとレビューで酷評されと、ろくなことがありません。
■「二度とガラケーには戻らないと決心しその通りに行動する」を達成するための戦略
  • ガラケーの仕事は意地でも断る
    「ガラケーは嫌いだけれど、仕事だからしょうがないし・・・」冗談じゃありません。幸いにして iPhone 開発で人材募集をしている会社さんも増えましたし、フリーで出来るお仕事の量も増えています。口だけでなくて行動でやらなければなりませんので、まずガラケーの仕事をお断りです。
  • せっかく無理言って iPhone のお仕事をやらせてもらっているので、とにかく全力でやる
    とまぁこんな具合で無理わがままを通しまして何とか iPhone のお仕事を頂きましたので、その分きっちりお仕事して成果を出して次があるようにしなければなりません。こうして後ろを断つとやっぱりやる気が出ます。また、損益にも気が向くようになります。なにせ赤字垂れ流しではあっという間にガラケーに逆戻りです。利益を出さなくては話になりません。
  • 自分に要求されている責任範囲以上の仕事をやる
    一番信用できて一番自分の思い通りに動くのは自分です。まず自分がやることで成功が近づくと考えています。と同時に一番信用できないのも自分なので、人におまかせしたり既存のライブラリなどを活用したりというのも必要になります。なんかすごい矛盾してますが、とにかく自分が一番信用できるけど一番信用できないのです。
  • 次の仕事を持ってきてもらえるように売上とかまで気にする
    「開発は物つくるまでが仕事、売るのは営業の仕事・・・」ガラケーでやってください。 iPhone 開発者の人は少人数かフリーの人が多いため、みなさん作ったものを売るところまで考えてらっしゃるようです。ただし、あくまで開発者の立場として売上を気にすることです。本職の営業や企画の方がいらっしゃるときに、私が営業や企画の真似事を始めると破綻します。
  • 以上のようなわがままを聞いてくれる環境に身を置く
    「んなもんお前に言われなくてもわかってるわ!そんな理想的な環境あるわけねえ!」すみません、ごもっともです><
    結局良い環境で仕事するのが一番で、良い環境は良い人脈と人付き合いがあれば勝手にやってくるみたいなので、まずは勉強会とかに参加しまして良い人付き合いをするのが一番の近道かなぁと思います。
  • 成果はきっちりアピールする
    成果はアピールしないと次につながりませんので、きちんとアピールします。幸いにして私は口から先に生まれてきた人間なので、大声で騒ぐのは得意です!しかしアピールというのはやり方を間違えると単なるスパムや嫌がらせに成り下がってしまいます。TPOをわきまえて正しく成果を大声でアピールしましょう。
    たとえば @iphone_dev_jp に「新作アプリをリリースしました!」なんて大声で流してもイラッとされるばかりですが、リリースして培った経験や技術情報、お役立ち情報を流せば「あいつはできる」と思ってもらえるわけです。
■チームで作業する際の戦略
ここまでは主に自分自身に関する内容の戦略でした。が、実際の仕事はもちろん自分ひとりだけではなく複数の関係者やチームのみなさんと進めることになります。ということで最後にチームで作業する際に私の考える戦略をまとめてみました。
  • 大前提: 人数は少なければ少ないほど良い 能力は高ければ高いほど良い 距離は近ければ近いほど良い
    これが大前提です。とにかくコストを最小限に保ちつつ、時間あたりの開発能力を最大にする必要があります。大規模開発等では当てはまらないかもしれませんが、仕事の総量が比較的少なめで予算が少なく納期が極めて短い iPhone 開発では、開発・デザイナーあわせて殆どの場合3人以内で足ります。その分各個人の責任範囲が非常に広くなるため、すべてのチームメンバーにそれらの責任を全うできるだけのスキルが必要です。誰しも限界があるので最終的には人に聞いたり頼ったりすることになると思うのですが、どこまで個々人が自分自身で調べて解決できるかというところが大事だと思います。何かあったらすぐ頼るような状態では生産性が落ちます。
    「距離は近ければ近いほど良い」というのは物理的にも精神的にもです。物理的に近いほうがやりやすいというのは、極端な例で言えばお客さんが隣のフロアにいるとかです。何か困ったことが発生したときに、メールのやり取りや電話口でのやりとりで解決するより、走って行ってその場で手取り足取り説明したほうが断然早いしうまくいきます。精神的に近いほうがやりやすいというのは、仲がいい方がチームのムードも良くなるし対立が発生しづらいからです。個人的には、良いチームにはデルタフォースとかSASのような特殊部隊のイメージがあります。あのへんの特殊部隊の人が語るチームマネジメント本とか講演会とかあればいいなぁとか思います。
  • 少数・精鋭・見知った仲でチームを結成する
    • 少数になるようにする - 必要最小限の人以外を入れない
    • 精鋭になるようにする - 可能であればそうするのがよいが、できる範囲でやるのであれば、同じ程度の実力の人を集めてチームにする
    • 見知った仲になるようにする - まず知り合う、勉強会とかに行く、一緒に遊ぶ、共通の趣味嗜好を持つ、距離の近いお客さんを選ぶ
    人を増やすのは比較的簡単ですが、減らすのは恐ろしく難しいです。人が増えると責任が薄まります。「俺がいなくてもどうにかなる」と気づいてしまうとヤル気が極端に下がりますし楽しくありません。もちろん、人が足りなくて毎日徹夜しないと追いつかないような状態になっているのはダメで、バランスが重要ですが、基本ほんの少しだけ足りない側に倒すほうが良いかと思ってます。
    チーム全体が精鋭になるようにするというのは、できるのであればそれが最も素晴らしいことだと思いますが、まぁ現実的に考えて難しいと思います。そんな手段があれば私がまず知りたいです>< で、現実的な作戦としては、チーム全体の実力をできる限り均一化すると言うことが挙げられます。チームメンバーの実力にほとんど差がない状態が、一番チームメンバー個々の能力を最大限に発揮させ、責任感を最大限に発揮させることができると思うからです。一人だけ精鋭がいてもその人に負荷と責任が集中し、他の人はアイツがいるからと思ってしまいます。逆に一人だけおちこぼれるとみんながその一人のせいにして責任を放棄します。
    見知った仲になるようにするために、例えば社内で月一ピザでも食べながら勉強会をやるとか、 誰か の家に飲みに行くとか、お昼ごはんを一緒に食べるとか。ここが一番難しい気がしますが、一番大事なところだと思います。仲がよければちょっとやそっとのミスや負荷があっても許してあげられるようになります。逆に険悪になるとほんの少しのミスや負荷が許せなくなり、さらに事態が悪化します。
    ただし、仲が良いのと馴れ合うのは絶対に違うと思います。馴れ合い始めると新しい人が入ってこれなくなり、仕事に張りがなくなります。これもバランスですね。
  • 開発チームとステークスホルダーが直接コミュニケーションできるようにする
    いくつかプロジェクトをやって気づいたことがこれで、開発チームとステークスホルダー(最終決定権保持者、各種画像リソースなどのリソース提供者)の距離が遠いとプロジェクトが失敗しやすくなります。距離が遠いというのは、間に仲介役 - たとえば営業の人だとか - が入るということです。人ほど信用ならない情報伝送経路はありません。必ず情報の劣化・嘘の混入・膨大な遅延が発生します。このような伝送経路を使うのをやめて、直接ステークスホルダーの人とSkypeでやり取りできるようになると、効率が格段によくなります。ミスも発生しません。
  • それでもどうしても何ともならないとき
    • 人数が増えてしまった - チーム/責任範囲を分割して可能な限り少数にする、または別の仕事を取ってきてそちらにチームを分割する
    • スキルが低い人と一緒に仕事をする必要がある - 低い人の理解に全員が合わせる。
    • 顔も名前も知らない人がチームに入ってきた、どうしてもウマが合わない人がいる - そこでどう仲良くなるかというのが本当にカッコイイ大人のやることではないか(キリッ
    • 物理的に距離が遠い - ツールを最大限に活用する。ツールを導入できるように先方をうまく説得する。
    • ステークスホルダーと直接話しにくい - 無理矢理にでも直接話すのを試みる
    すみません、かなり無茶苦茶です>< というのも私自身ここに書かれているような事態にうまく対処できないからです。実際これらの問題をうまく乗り切られる人は、人間力があるといいますか、磨かれた大人であるといいますか、優れたマネージャーさんであると思います。現実問題、こういった問題は数限りなく存在しますので、具体的な対処策は私自身学び取りたいところです。ですが、絶対に勘違いしてはならないのが、これらはあくまで「対処療法」であって、「根本的な治療」ではないということです。最初から対処療法が必要でないような環境を作るために尽力し、そのような環境で仕事をしていれば、これらの問題はそもそも発生せず、そのため余力を生むことができます。発生した余力はさらに理想的な環境を整備するために使ったり、自分自身のスキル向上のために使えます。
    これを体の健康にたとえるならば、毎日暴飲暴食せず野菜を取り適度な運動を行ない十分な睡眠をとることで病気にならない様にするのが一番であって、自堕落な生活を送った結果重い病気にかかったので医者に行って治してもらうというのを繰り返すようでは体がどんどんぼろぼろになっていきます。体の健康に例えると、前者を行う人が尊敬され後者は笑いものにされるのですが、チーム運営となると前者は魔法か理想論と馬鹿にされ後者の出来る人が大人だと尊敬されているようで、どうも私はしっくりきません。何事も予防する、予防できる環境を作るのが一番です。発生してから耐えるのは美徳ではなくやむを得ないことです。
  • 課題: どうしても合わない人をどう追放するか
    これは世界全国、人とチームがある限りの永遠の課題だと思います。本当はこんなことをしないでよいのであれば理想なのですが、それでもどうしても人が余ったりチームに合わないからという理由で人を外さなければならないことがあります。アメリカ人みたいに非情にズバズバ首を斬ると、後から衝突が発生したりチームの財産を平気で奪って逃げたりされます。かといって日本人みたいに何時までも何時までも衝突を恐れて首を切れないと、チーム全体の死活に関わります。まったく、どうするのがいいんでしょう・・・><
■まとめ

3行でまとめると、楽しく生産性の高い仕事をするには、
責任感を持つ/持たせるのが大事
ゆとり大事
バランス大事
こんなところですかね。

2009年12月11日金曜日

Django の Template Filter には任意の変数を使用することができる

公式ドキュメントに記載がなかったので、自分用メモ。

たとえばDjangoのフィルターで、
{{ some_value|floatformat:1 }}
としているところを、viewから変数を渡して
{{ some_value|floatformat:floatpoint }}
のように書くことができます。他にも
{{ now "%Y %m %d" }}
{{ now date_format }}
みたいに書くとか。・・・常識?

2009年11月23日月曜日

Mac OS Xには最初から/usr/share以下にmaven2やantが付いてくる

先日のScala Hackathon #1にて初めて気づいた驚愕の事実。なんとMac OS Xには最初からJavaの開発ツールが付いてきていたのでした。
akisute ~$ mvn --version
Maven version: 2.0.9
Java version: 1.6.0_15
OS name: "mac os x" version: "10.6.2" arch: "x86_64" Family: "mac"
akisute ~$ ant -version
Apache Ant version 1.7.0 compiled on July 20 2009
akisute ~$ which mvn
/usr/bin/mvn
akisute ~$ which ant
/usr/bin/ant
ちょっとmaven2のバージョンが古いですが、普通に使う分にはたぶん問題なさそうです。ちなみにこれらのツールは/usr/share以下に用意されています。
akisute ~$ cd /usr/share
akisute share$ ls
NotificationServer/ distcc_compilers info/ sandbox/
Ssh.bin doc/ java/ screen/
TargetConfigs/ emacs/ junit/ sdef/
aclocal/ enscript/ langid/ servermgrd/
aclocal-1.10/ examples/ libiodbc/ skel/
ant/ file/ libtool/ snmp/
apr-1/ ftpd/ locale/ statsCollector/
autoconf/ gdb/ man/ swig/
automake-1.10/ germantok/ maven@ tabset/
bakefile/ gprof.callg mecab/ tcsh/
bison/ gprof.flat misc/ terminfo/
caldavd/ groff/ mk/ texi2html/
calendar/ gtk-doc/ openmpi/ texinfo/
cracklib/ gutenprint/ openmpi-default-hostfile uucp/
cups/ heapdiff/ openmpi-mca-params.conf vim/
cvs/ hiutil/ openmpi-totalview.tcl xcode-select/
derby/ httpd/ podcastproducer/ zoneinfo/
dict/ icu/ ri@ zsh/
おお、他にもderbyとかありますね。TomcatやJettyのようなサーブレットコンテナがないので、そのまますぐにWebアプリ開発とはいきませんが、なかなか面白そうです。

・・・む、ひょっとしてこれ常識ですか? ><

2009年10月11日日曜日

UIViewControllerのtouchesBeganとかtouchesEndedが上手く機能しなかったと思ったら・・・

ひさっびさに普通のUIKitを使ったiPhoneアプリを作ったりし始めたらかなりの範囲を忘れてしまっていて大ハマりしてます。中でも一番困ったのがこれ。
@implementation AbesiViewController

- (void)viewDidLoad
{
[super viewDidLoad];
self.wantsFullScreenLayout = YES;
}

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

- (void)dealloc
{
[super dealloc];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// なぜか出力されない
NSLog(@"touchesBegan");
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// なぜか出力されない
NSLog(@"touchesMoved");
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// なぜか出力されない
NSLog(@"touchesEnded");
}

@end
とまぁ、なんの変哲もないUIViewControllerにタッチを扱うためのイベントハンドラを搭載してみただけなのですが、コレがまぁ動かない動かない!

こういうときに考えられる原因は、だいたいがInterface BuilderでInteraction Enabledのチェックを入れ忘れているとか、ViewControllerとViewをつなぎ忘れているとかそんなのばっかりなので真っ先に調べてみました。が、やはり問題は見つかりません。

試しにUIViewControllerではなくUIViewにtouchesBeganを載せてみるとコレが動くんです。ああ、OS 3.1.2ぐらいから挙動が変わったのかなとか思っていたら、

http://stackoverflow.com/questions/1025574/uiviewcontroller-not-receiving-touchesbegan-message
OK, I'm a dummy. It works fine. The problem was, I didn't realize I was sending a release message to the UIViewController without having retained it elsewhere first. So that was causing the problem.
あーーー!そうだ!!!UIViewControllerをretainしてない!!!orz

retainしたら解決しました。ほんと腕がなまってる・・・

2008年11月30日日曜日

CS193P Cocoa Programming - 7日目 UINavigationViewControllerを使う

  • UIViewControllerのawakeFromNibは動作しないときがある。UIViewControllerの初期化には 必ずviewDidLoadを使うこと
  • UINavigationViewControllerはxibファイルに含めずに、ソースコード中で初期化したり管理する方がうまくいく
  • UINavigationViewControllerの上に表示されるバーを編集したいとき(ボタンを追加したりするとき)は、UINavigationViewControllerにpushされるUIViewControllerのnavigationItemプロパティを編集する。Interface Builderから操作できるかどうかはわからない
  • UIAlertViewがポップアップ表示、UIActionSheetが下からにょきっと出てくるボタンのリストを表示
  • ボタンにソースコード中からアクションを追加することが可能(UIButton, UIBarButtonなどのドキュメントを参照のこと)


さて、ナビゲーションがついてようやくiPhoneアプリらしくなってきました。
画面はナビゲーション時にUIViewControllerのインスタンスがどのように管理されているかをログに吐いてみたところです。viewDidDisappearの後にdeallocが毎回流されているのがわかります。
要するに、一つのviewを毎回毎回alloc->initしないでインスタンスを再利用してやろうと思うときはUINavigtionViewControllerにpushするだけではなくて、どこか別のところでUIViewControllerのインスタンスを保持しておく必要があるようです。2tchの作者さん曰くalloc->initは相当重い動作らしいので、できるかぎり使い回しができるようにしたいです。



ポップアップも出るようになりました。


※いい加減開発ペースと学習ペースをあげようと思っているので、しばらくの間はブログの更新がこんな感じで適当になりそうです。

2008年11月26日水曜日

CS193P Cocoa Programming - 6日目おまけ、多角形をくるくる回せるようにしてみた

  • CS193P(http://www.stanford.edu/class/cs193p/cgi-bin/index.php)のチュートリアルで作っているHelloPolyプロジェクトを自分なりにアレンジしてみた
  • 自分なりにアレンジしてみた=ニコニコ動画だと駄作フラグ
  • UIViewはhiddenプロパティをYESにした瞬間に消えてしまうので、アニメーションでフェードアウトさせたいときは、まずアニメーションだけ実行>アニメーション終了時のデリゲータ(- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag)で実際にUIViewをhiddenにする
  • タッチ動作を取得するには、UIView(正確にはUIResponder)のtouchBeganメソッドやtouchMovedメソッドをオーバーライドする
  • デフォルトではマルチタッチ不可能(最初の1タッチのみ感知する)、マルチタッチしたければ設定を変えること
  • UITouch.tapCountでタップした数を取得できる。これを使ってダブルタップを検出できるが、連打すると3とか4とか2より大きい数が取得されてしまうので注意
  • CGPointはクラスではなくて構造体、頭にCGがつくCore Graphics系はすべて純粋C言語であるところに注意!
  • CGPointなどを作成するときはCGPointMake()関数を使う
  • CGPointやCGRectなどをObjective-Cのクラスとして扱いたいときはNSValueクラスを使う、たとえば[NSValue valueWithCGPoint:(CGPoint)point]など
  • CGRectGetMidX()関数とか地味に超便利
  • C言語の変数の有効範囲について:http://www.cis1.c.dendai.ac.jp/c_master/C_14.htm
    CGPointMake()で作ったCGPointなどは自動変数なので、別のメソッドに渡すときはポインタ渡しではなくてそのまま値で渡す

ただ単にカリキュラムにそって進めていくだけでは面白くないので、この辺りでちょっとチャレンジングなことをしてみることにしました


まずは新しくサブビューを追加。


ON OFFスイッチでビューを出したり消したり。出したり消したりするときはアニメーションします。


UISliderを使って、線の太さを変えてみましたよ。
UISliderのvalueプロパティはdouble型なので注意です。ずっとNSString型だと思ってました。
それから、タップした向きに多角形を回転できるようにしました。赤線は中心からタップした点への線分です。
タップしてドラッグするとスムー(?)ズに回転しますよ。


破線への切り替えもできるようにしました。
UISegmentedControlを使っています。このUISegmentedControl、取得できる値が選択されているセグメントのインデックス番号(selectedSegmentIndex)だけなのでちょっと厄介です。HTMLのラジオボタンみたいに好きな値をセグメントごとに持たせられればいいのに。


今回作成したアプリのプロジェクトファイルを公開してみました。
面白いことをやっている点は何一つないのですが、まぁ一応。
http://sites.google.com/site/akisutesama/files/HelloPoly-06b.zip?attredirects=0

今後はgithubとかで公開できるようにします。

2008年11月22日土曜日

CS193P - ここまでの進捗をアップしてみた

ここまでのCS193Pの進捗をアップしてみました。

http://sites.google.com/site/akisutesama/files/HelloPoly-06.zip?attredirects=0

Xcode3.1用のプロジェクトファイルと、ソース一式が入っています。
Max OS Xで解凍してXcodeで読み込んでコンパイルできると思います。たいした内容ではありませんが一応。

CS193P Cocoa Programming - 5日目、いよいよView自作

  • Interface Builderを使ったらとにかくWrite Class Files...を押すのを忘れないように
  • 描画はJavaのSwingなどとほぼ同じ
  • drawRectメソッドをオーバーライドして描画する
ViewとかAnimationとか、いよいよ実践が近くなってきたようです。
だんだんと難易度も上がってきました。



まずは自作Viewを作成。
Interface BuilderからUIViewを引っ張ってきて画面上に配置。
クラス名を適当に(ここではPolygonView)に変更。
ControllerクラスやらModelクラスなど、必要に応じてOutletを追加します。
最後に(一番忘れやすいんだけれども)メニューからFile > Write Class Files... この書き出しを行わないとXcode上に実際のソースが出てきません。

書き出しを行ったらXcodeを開いて、以下の2つの仕事を行います。
・先ほど追加したPolygonViewのスーパークラスを定義する
・ControllerにIBOutlet PolygonView *polygonViewを追加する

新しいオブジェクトはWrite Class Filesで一発だと思うけれども、既存のクラス(例えば前回実装したController)なんかは、書き出ししちゃうと上書きしてしまいそう。怖いので今回はXcodeから書くことにしました。でもこれ非常に非効率的。hファイルだけ上書きしてほしいんですけど・・・



勇気を振り絞って上書きWrite Class Files...にチャレンジしたら、なんだかこんなFileMergeとかいうアプリが立ち上がって、きれいにマージすることができましたとさ。よかったよかった。


では早速Viewに描画処理を追加します。
描画を行うのはUIViewの-(void)drawRect:(CGRect)rectメソッドですので、こいつをオーバーライド。
あとは再描画したいタイミングでUIViewのsetNeedsDisplayをコールすれば適切なタイミングでシステムが再描画してくれるというしくみ。Swingに似てますね。



実際に描画してみました。簡単簡単!!



描画のやり方さえわかってしまえばこっちのものです。
ポリゴンの点の位置を計算するメソッドは例題の中で用意されていたので、それを丸コピーして点の位置に線を引くだけ。線の太さを調節する関数はCGContextSetLineWidthというのが見つかったのでそれを使うだけ。リファレンスが使いやすい!すてき!



カスタムビューの中にUILabelを追加して、ラベルにポリゴンの名称を表示できるようにしてみました。UILabel.textプロパティを書き換えるタイミングはカスタムビューのdrawRectの中で。ほかに良いタイミングが見当たらず。


ひとまずこんなところですかね。次は・・・
  • スライダーで線の太さを変える
  • 線の種類を何らかのスイッチで変える
  • ビューの上でフリックしたらポリゴンがくるくる回るようにする(アニメーション処理の勉強が必要)
これらを試してみたいですね。

2008年11月17日月曜日

CS193P Cocoa Programming - 現在4日目

  • メモリの管理についてお勉強
  • allocで領域確保(オーバーライドしない)
  • initで初期化(オーバーライドして使う)
  • 同一オブジェクトを参照するときはretain(オーバーライドしない)
  • コピーするときはcopy(オーバーライドしない、copyWithZoneをオーバーライドするべき)
  • 解放するときはrelease(オーバーライドしない)
  • 実際にメモリから削除されるのはdealloc(オーバーライドして使う)
  • NSAutoReleasePoolとautoreleaseメソッド・・・事前にautoreleaseしておいたオブジェクトは[NSAutoReleasePool releaseまたはdrain]呼び出し時に一斉に解放される

1日に二日分前進。iPhone発売から既に4ヶ月経過、既に無数の超優良アプリがわんさかと出回っています。果たして私は遅れを取り戻せるでしょうか。


これはNSURLから文字列を取得する方法を模索していたときです。
結局、absoluteStringかrelativeStringが正解ということがわかりました。


クラスの作成とメモリ管理。ようやくCらしくなってきたかな?
Objective-Cではガベージコレクションもできるらしいのですが、iPhone開発ではガベージコレクタをぶん回せるだけのリソースはないため昔ながらのメモリ管理でやる必要があります。



いろんなイニシャライザをためしてみました。
リストにオブジェクトを突っ込んだときは、突っ込んでいるNSArray自身もリリースしないと、個々のオブジェクトがリリースされません。おそらく内部でretainされてるんでしょうね。



introspection(Javaでいうところのrefrection)にチャレンジ。instanceof演算子みたいなのはなくて、すべてNSObjectのメソッドとして提供されています。java.lang.refrectionパッケージみたいな面倒さはないです。あとセレクタはSEL型とかいう専用の型があって便利。いわゆる関数へのポインタとして使えます。Javaの何が不満ってこの関数ポインタがないところですよ。



続けてもう一つの宿題のほう(Assignment2B)に突入。いよいよ実際に動作するiPhoneアプリを作ることになるのですが、その前に一つ宿題にバグ?があったのでご報告。
上の画像のカーソルで選択している部分(PolygonShape.h)、Assignment2Aで作成したときにはCocoa/Cocoa.hをインポートしていますが、2BではCocoaが使えない(iPhoneアプリになるため)ので、Foundation/Foundation.hに書き換える必要がありました。



で、これが完成品です。
SwingやWin32API開発並みの苦行を覚悟していたのですが、あまりに簡単で逆に拍子抜け。はまりそうな点といえば、プロジェクトに新しくクラスをインポートしたり作成した後はInterface Builderからアプリケーションに登録しなければならないというところぐらいでしょうか。あと、awakeFromNibはコントローラに実装しないとだめ(間違えてPolygonShapeに一生懸命実装して、ビルド直前にこの過ちに気づきました)。


今のところは楽勝。問題はOpen GL ESに手を出すあたりからでしょうかね。

2008年11月9日日曜日

CS193P Cocoa Programming - 1日目の宿題Bをやってみた

  • Objective-Cは、見た目とは裏腹に非常に簡単
  • Xcodeのリファレンスはきわめて優秀
  • Xcodeのコード補完はControl + , またはOption + Escだが使いづらいのでCommand + Spaceに変更する
  • Xcodeのコンソール表示(NSLogの内容を確認)はShift + Command + R
引き続き宿題B。こっちの宿題はiPhoneから完全に離れてObjective-Cの基礎基本について学ぶようになっています。
それにしてもこの宿題、問題の出し方がうまいです。全く調べないで解けるほど優しくないですが、何処を調べればよいかはきちんと示されています。リファレンスの引き方と自分で調べる力が養えるのがうれしいです(あたりまえなんですけど・・・自分の大学では調べてもさっぱりわからないか、調べ方がそもそもわからないか、調べる必要がまったくないか、というような宿題が多かったので)。

閑話休題。Objective-Cは何一つわかりませんが、とにかく見よう見まねでコードを書いてみます。


おおー動いた!最初このコンソールの出し方がわからず困りました。Shift + Control + Rでした。


調子に乗ってさらに数行記述。リファレンスを引いてNSString同士の結合およびフォーマットのやり方を調べてみました。+で結合できないのが少々面倒(確かC++だとできたはず)。


なれてきたらもう簡単。
それにしてもメソッド名がいい感じに長いです。私はこういうやたら説明的で長いメソッド名が大好きです。


NSArrayのループもこの通り。Javaっぽい。
あとNSDictionaryも調べてみましたけど、Javaと同レベル・・・これはいまいち・・・
JavaScriptやPythonみたいなスクリプト言語らしい使い勝手のいいDictと比べる方が悪いですけどね。


Xcodeの設定。これでコード補完をCommand + Spaceに割り振ることができます。



同じ項目がもう一カ所ありましたが、こちらは変えなくても特に問題ないらしいです。メニューから呼び出しているかそれともテキストエディタの中で直接呼び出しているかの違いのようです。

それでは引き続き残りの宿題をやってしまいますか!

CS193P Cocoa Programming - 1日目の宿題Aをやってみた

  • http://www.stanford.edu/class/cs193p/cgi-bin/index.php
  • これはわかりやすい
  • 宿題があるのが実にうれしい
  • Interface Builderで配置したクラスの属性(位置とか表示するイメージとか)を操作するときは、Command + Shift + I またはCommand + 1から4
  • Labelの文字の大きさとフォントは変えられたが色とか太字はなぜかうまくいかず
  • vertical centerな配置やholizonal centerな配置を行うには、メニューのLayout > Align
今日からスタンフォード大学の学生になった気分でさくさくっと勉強。
手始めに1日目の宿題から。・・・こんなに宿題を嬉々としながらこなす私の姿を学生時代の自分に見せてやりたいものだ。
一つ目の宿題は、コーディングはいっさいなく、interface builderからCocoa Touchが用意しているviewやclassを配置して画面をデザインしてビルドして走らせるだけというもの。


こんな感じでinterface builderにパーツを配置して・・・


できた!初日の宿題だけあって実に簡単。

こういったグラフィカルなGUI作成機能は別に目新しいものではない(Microsoft Visual Studio 2005などでもできる)が、これまで使ったことがあるツールよりは使いやすかった気がする。まぁVS2005はマイクロソフト語で書かれているので読めない=論外だし、Eclipse GEFはそもそもSwing自体があまりよいフレームワークでなかったため使いづらかった。
なによりiPhoneの場合はデバイスの画面サイズが決まっているから絶対座標指定がしやすい。

2008年11月8日土曜日

iPhone開発をこれから始めるときに参考にする資料

  • スタンフォード大学の授業が一番わかりやすい
  • iPhone Dev Centerのビデオは全体像をつかむために使える
  • 良い書籍がないか探索中
  • Core Animation, Core Audio, Quartz(Core Graphics), OpenGL ESあたりの使い方に詳しい資料が欲しい
つい最近までAndroidの開発に浮気していましたが、とあることがきっかけで、iPhoneの開発に本格的に戻ってくることにしました。
ところが私自身、Mac OS Xでの開発もやったことがないし、XCodeも使ったことがないので、そういう人向けの初めてのiPhoneアプリ開発用資料を集めてみました。


CS193P - Cocoa Programming | Announcements
スタンフォード大学のCocoa Programmingの授業。英語が読めるなら断然これがオススメですね。タダだし。本当にタダでいいんですかこれ?

iPhone Dev Center
Appleの総本山。ここのビデオをiPhoneに突っ込んで通勤中に見るのがオススメです。詳しいところは全く分かりませんが、全体像をつかむには適しています。


それから書籍。正直iPhone開発向けの本はこれ!と言うものがまだ見つかっておらず、Objective-Cの本のみを調査中。

詳解 Objective-C 2.0詳解 Objective-C 2.0
荻原 剛志

by G-Tools

4000円以上しますが、一番評価が高かったのがこれ。


あとはiPhoneのメディア系(アニメーション、画像描画、オーディオなど)の使い方の詳しい解説資料が欲しいのです。こちらは目下捜索中。使うのはHello Worldレベルから脱却してから。