プログラマでありたい

おっさんになっても、プログラマでありつづけたい

カテゴリ別 App Storeのアプリ登録数

 暇な時に、日本のApp Storeで登録されているアプリ数をカテゴリ別に調べてみました。書きだして眺めてみると、色々な気づきがあったので共有します。ちょっと眺めて見てください。

カテゴリー名 iPhone無料 iPhone有料 iPad無料 iPad有料
Newsstand - - - -
エンターテイメント 25353 26990 6978 9128
カタログ 299 130 73 345
教育 18308 28843 9513 17710
ゲーム - - - -
仕事効率化 6007 7130 2308 3253
辞書/辞典/その他 6756 11578 2347 5568
写真/ビデオ 4856 6220 1692 2978
スポーツ 7493 7417 2006 2449
ソーシャルネットワーキング 7505 2680 1335 919
天気 1077 963 305 405
ナビゲーション 3177 5342 691 2184
ニュース 10088 2337 5656 827
ビジネス 17905 5507 7874 2668
ファイナンス 6558 3565 2016 1127
ブック 10058 40432 7118 21136
ヘルスケア/フィットネス 5487 7867 1375 2552
ミュージック 12352 8832 2300 4077
メディカル 4473 5112 1871 2520
ユーティリティ 16152 16272 3828 4541
ライフスタイル 25345 17075 8077 6031
旅行 11883 16154 2674 5029
合計 201132 220446 70037 95447


 売上/ダウンロード数は、スタート時では口コミや有名サイトでの紹介がモノを言いますが、長期的にみるとApp Storeでのランキングに載りつづけるかが勝負です。となると、必然的に競争が激しくない所の方が有利になります。例えば似たようなカテゴリのビジネスと仕事効率化。iPhoneの無料版だとビジネスカテゴリは18,000弱になります。これに対して仕事効率化は6,000程。逆に有料版だとビジネスは5,500程度なのに仕事効率化は7,100強と逆転します。どちらのカテゴリでもマッチする内容であるのならば、無料版で出す時は仕事効率化でだして、有料版ならばビジネスを選ぶのも一つの手でしょう。
 カテゴリは一度出すと変更出来ないので、慎重に選びましょう。また激戦区を除けば、ランキングに載ることはそこまで難しくありません。リストを見て頂ければ解ると思いますが、iPadアプリなどは特に難易度が低いです。この辺りもコツがあるので、どこかで一度まとめようと思います。


XcodeでMissing fileのWarningが発生した場合の対処法

 iPhoneアプリやiPadアプリの開発でXcode使っていて、大幅にソースの改廃やディレクトリの改変をすると、WarningでMissing fileが出る時があります。これは何かというと、svnやgitの管理ファイル上に残っているのが問題のようです。
 解決方法については色々議論されていますが、XCodeからではなくコンソールから消してしまう方が簡単じゃないかという結論のようです。
 だいぶ改善されたとはいえ、どうもXCodeとソース管理の連携はイマイチな部分が残っていますね。


SVNの場合

svn delete missingFile

Gitの場合

git rm missingFile


参考:
Missing file warnings showing up after upgrade to XCode 4

リリース済みのiPhone/iPadアプリのDBの変更の仕方 或いはCoreDataを使ってスキーマの自動マイグレーション

 リリース済みのiPhone/iPadアプリのDBのテーブル定義を変更したい。こんなことって、ありますよね?しかし、サーバサイドのアプリと違って、クライアントサイドで動くiPhone/iPadアプリはどうやってデータの移行をすれば良いのでしょうか?リリース後に気がついて、私は小一時間途方にくれました。
 でも、iPhoneなら出来るんです。簡単に!!
正確に言うとApple謹製のDBのフレームワーク、CoreDataを使っていた場合は簡単に移行(マイグレーション)が実現出来ます。


詳しい情報は、次のリンクをご参照ください。
Core Data Model Versioning and Data Migration
Lightweight Migration


 簡単な手順としては、次のような形になります。

  • 新しいバージョンのモデルを追加する。

  Editor -> Add Model Version
  

  • 追加したモデルに、属性(カラム)を追加する。

  必要なだけ、追加します。

  • マッピングファイルを作成する。

  File -> New File -> Core Data -> Mapping Model
  マッピングファイルは、Source Data Model(移行元)とTarget Data Model(移行先)を指定します。
  注意点としては、どのバージョンからどのバージョンに移行するのかする解るようにすることです。
  どういうことかというと、Version1 -> Version2 -> Version3とこちらの期待通りに移行してくれるとは
  限らないということです。 Version1 -> Version3といった人もいます。
  なので、Version3まである場合は、 ver1->ver3とver2->ver3と2ファイルの用意が必要です。
  ファイル名もV1toV2.xcmappingmodel等、一目でわかる形が良いのではないでしょうか?
  

  • 自動マイグレーションコードを追加する。

  詳細は、下の方に書いておきます。

  • 現在のバージョンを変更する

  該当の.xcdatamodeldを選択して、File InspecterのVersioned Core Data ModelのCurrentを変更します。

自動マイグレーションのコード記述

 自動マイグレーションで、変換(マイグレーション)が起きるタイミングは、NSpersistentCoordinatorでオプションで変換を付けた時になります。データアクセスクラスみたいなので一元化しておけば、そこの部分にオプション追加するだけで対応が可能になります。
 私の場合は、DataManagerという基底クラスを作って、そこで 永続ストアコーディネータの作成やDBファイルの作成を一手に行なっているので、ここだけの修正で済みました。CoreDataを使った開発の詳細は、こちらのエントリーで書いています。
DataManager.m

NSError *error = nil;
NSURL *storeURL = <#The URL of a persistent store#>;
NSPersistentStoreCoordinator *psc = <#The coordinator#>;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
 
BOOL success = [psc addPersistentStoreWithType:<#Store type#>
                    configuration:<#Configuration or nil#> URL:storeURL
                    options:options error:&error];
if (!success) {
    // Handle the error.
}

 ただ大量データの変換が必要な場合、注意が必要となります。数十件程度のデータであれば、すぐに終わります。が、それが数千件レベルのデータとなりますと、それ相応の時間が必要となります。その場合にアプリ起動時にいきなりマイグレーションが起こると、アプリの起動タイムアウトが発生する可能性があります。またそうではなくても、ユーザは壊れたかと思って中断することも考えられます。その点を考慮した上で、マイグレーションをどこで行うかの設計が必要になります。


 最初にiPhoneアプリでDB(SQLite)を使う時に、CoreDataを使うかサードパーティのFMDBを使うか悩みました。FMDBは慣れ親しんだSQL文で操作出来るし、記述量も少なめとかなり魅力的にみえました。一方、Appleのフレームワークの上という所でバージョンアップ時の対応等で継続性の懸念がありました。悩んだ末に、一度はちゃんとCoreDataを使ってみないとダメだろうと思い、CoreDataを採用した経緯があります。今となっては、良かったなぁと思います。正直、開発している段階ではここまで気が回らなかったので、助かりました。これから開発される方は、是非CoreDataをお使いください。


 あと、iPhone/iPadアプリを効率的にかつ保守性の高いコードで書くには、是非、木下さんのiOS開発におけるパターンによるオートマティズムをお読みください。CoreDataのサンプルコード等も入手出来て、本当に参考になります。


enjoy!!

XcodeでGitのリモートリポジトリ(remote repository)を追加する方法

 Xcode4.2系になって、文句なくよくなったのがバージョン管理ツールとの連携。今までが酷すぎたのですが、4.2になって随分と改善されています。まずデフォルトのバージョン管理ツールがGitになっています。GJ!! そして、それ以上に素晴らしいのが、Xcodeからリポジトリを自動で生成出来るようになっていることです。iOSアプリの開発者は、昔からバリバリやってましたという人以上にプログラミングってよく解らないけど挑戦してみましたという人の方が多いんじゃないかなと思います。そんな人達にじゃぁGitのサーバ用意してってのは酷な話です。でも、Appleなら大丈夫。ローカルリポジトリならすぐ作れてバージョン管理が出来ますよという形にXcodeはなっています。素晴らしい!!(ただ、バージョン管理の概念があるのかは難しいところですが。)
 ということで、Xcode4.2ならプロジェクト始めたその瞬間からローカルレポジトリを作成出来てバージョン管理が出来ます。ただ残念ながら、リモートリポジトリを作るところまではサポートしてくれていません。なので、同一PC内でリモートレポジトリを作る為のチップスを紹介します。ググッてみたら、一度リポジトリを作ってからcloneする例が多かったので、一助になればと思います。ちなみに今回の例は、既にgitのモジュールを入れていること前提です。


コマンドラインで、空のリポジトリを作成

$ mkdir REPOSITORY_NAME
$ cd REPOSITORY_NAME
$ sudo git init --bare --shared=true


こっからが肝です。
Xcodeでプロジェクトの作成
File -> Source Control-> Commit
File -> Soruce Control-> Repositoriesを選択。プロジェクト名を選んで、Remotesを選択状態でAdd Remote
Remote Nameを適当につける。 Masterとかが一般的。
次にLocationで先程作成したPathを指定します。(もちろん別サーバのURLも指定出来ます。)
そして、プロジェクトをアクティブにした上で、File -> Source Control -> Push
これだけです。


簡単ですよね。ちなみにリモートリポジトリの保管先をDropBoxやS3にすると更に便利です。
詳しくは、このあたりも読んでください。
-- 週末プログラマにお薦め!!Subversion+DropBoxで似非分散型バージョン管理
Enjoy!!


iPhone,MacBook Airで使えるマイク付きヘッドホン

 最近、打ち合わせにSkypeを使うことが多くなりました。MacBook Airだとマイクのインターフェースがなくヘッドホン用のインターフェースしかありません。MacBook Airだと本体マイクを使うしかないと諦めていたのですが、そんなことはなかったのです。iPhone用のマイク付きヘッドホンを使えば、マイクとヘッドホンが一つのジャックで使えます。また付属のボタンで電話の応答・切断の操作が出来て、何気に便利です。あと驚くことに、iPhoneでも使えます。iPhoneでSkypeする時も電話スタイルで使うより、このヘッドホンを使う方が楽でよかったりします。またiTunesの再生も付属のボタンで出来るので、かなり便利です。
 二千円台という値段を考えれば、かなりコスト・パフォーマンスが良いのではないでしょうか?中々満足度の高い一品でした。


See Also:
iPhoneのボイスメモが素晴らしすぎる件について 或はiPhoneのボイスメモをPCに転送する方法


Creative マイク付きヘッドホン EP-630i
クリエイティブ・メディア (2008-09-27)
売り上げランキング: 854

iPhoneでカレログを作ろう その3 地図の表示

 前回までのコーディングで、位置情報の取得ならびにDBへの格納が出来ました。今回はそのデータを使って地図を表示しようと思います。
 地図を使ったサンプルは沢山ありますが、DB連携というところでWeatherMap、経路の描画にKMLViewerを参考にします。ちなみにKMLというのは地図データのファイル形式の規格の一つですが、名前の由来はKeyhole Markup Language。Google Earthの元となったKeyholeから来ているようです。会社はGoogleに買収されましたが名前は規格として残り続けたんですね、Keyhole。横道にそれましたが。
Map Kit Framework Reference
KMLViewer
WeatherMap


 まずはMapKit.frameworkを追加しましょう。地図を表示するコントロールビューを作りましょう。今回はMapViewControllerとして作成しています。ヘッダーにMapKit/MapKit.hを追加し、IBOutletのMKMapViewの変数を宣言します。nibファイルのviewにMapViewを配置して、先ほどのmap変数と結びつけます。これだけで、ひとまず地図が表示出来るようになります。

@interface MapViewController : UIViewController<MKMapViewDelegate> {
    id  _delegate;
    IBOutlet MKMapView *map;
    
}
@property (nonatomic, assign) id delegate;
@property (nonatomic, retain) MKMapView *map;


 次は、現在の位置を元に地図を表示するように変更してみます。
MKCoordinateRegionのcenterで、中心地の経度・緯度を設定します。
縮尺度はspanで設定しますが、ちょっとややこしいです。
ここで設定する値は画面の上端と下端の緯度の差並びに、
画面左端と右端の経度の差になります。
 ということで、最大の緯度から最小の緯度を引いたものと
最大の経度から最小の経度を引いたものをセットしておけばよいでしょう。
画面に余裕を持たせたければ、それぞれ適当な値を掛けておけばよいと思います。

- (void)viewDidLoad
{
    [super viewDidLoad];
    MKCoordinateRegion region;
    region.center.latitude = 34.6760065320036; // 緯度
    region.center.longitude = 135.50026706781; // 経度
    region.span.latitudeDelta = 0.0042742764933;
    region.span.longitudeDelta = 0.0073050094;
    
    [self.map setRegion:region animated:NO];
}


 少し長くなったので、今回はこのあたりにします。
次回は地図の上に、移動した経路の表示を重ねあわせるようにします。
enjoy!!


目次
iPhoneでカレログを作ろう その1 位置情報の取得
iPhoneでカレログを作ろう その2 DBへのデータ格納
iPhoneでカレログを作ろう その3 地図の表示


Google Maps Hacks 第2版 ―地図検索サービスをもっと活用するテクニック
Rich Gibson Schuyler Erle
オライリー・ジャパン
売り上げランキング: 127779

iPhoneでカレログを作ろう その2 DBへのデータ格納

 前回のコーディングで、位置情報を取得することができました。続いて位置情報をDBに格納しましょう。DBに格納せずに直接サーバに送り続けるということも考えられますが、扱いやすさを考えて一旦DBにいれます。
 iOSではSQLiteを使うことが出来ます。使い方としては、Apple標準のCoreDataを使う方法の他に、SQLiteをラップしてくれるライブラリであるFMDBを使う方法もあります。どちらも一長一短があるので、自分の好みで選択すれば良いと思います。今回は勉強の意味も兼ねてCoreDataで書きます。


 CoreDataを使ったサンプルコードは色々ありますが、次の3つくらいが参考になりそうです。
CoreDataBooks
iPhoneCoreDataRecipes
Locations
 CoreDataBooksは、UITableViewをメインに書籍の登録・削除・一覧表示をするシンプルなアプリです。解りやすいので一度読んでおくと良いと思います。iPhoneCoreDataRecipesは結構複雑で、TableViewを使う上でのチップスが色々含まれています。Locationsは前回説明したもので、今回はデータ構造等はこれを参考にします。
 またMVCモデルで作る場合は、木下誠さんの"iOS開発におけるパターンによるオートマティズム"が超絶に参考になります。iPhoneアプリを作る人は一度は読んでおくべきでしょう。


 さて実際のコーディングです。今回はデータ操作はコントローラからではなく、モデルのマネージャークラスから行うようにします。まずフレームワークとして、CoreData.frameworkを追加します。次に2つのクラスを追加します。位置情報を定義するエンティティクラスであるLocationクラスを、NSManagedObjectのサブクラスとして作ります。CoreDataを扱うマネージャークラス。Modelsグループを追加して、その下に格納します。ついでにControllersグループを作って、前回作ったControllerもそちらに移動させます。またDataModelも追加しておきましょう。そうすると構成は次のようになります。


ソースは次のような感じです。

Location.h

#import <CoreData/CoreData.h>

@interface Location : NSManagedObject  {
    
}

@property (nonatomic, retain) NSDate *creationDate;
@property (nonatomic, retain) NSNumber *latitude;
@property (nonatomic, retain) NSNumber *longitude;


@end

Location.m

#import "Location.h"
@implementation Location

@dynamic creationDate;
@dynamic latitude;
@dynamic longitude;

@end

DareTokuDataManager.h

#import <CoreData/CoreData.h>

@class Location;

@interface DareTokuDataManager : NSObject {
    NSManagedObjectContext* _managedObjectContext;
}

@property (nonatomic, readonly) NSManagedObjectContext* managedObjectContext;
@property (nonatomic, readonly) NSArray* sortedLocations;


- (Location *)insertNewLocation;
- (void)save;

// 初期化
+ (DareTokuDataManager*)sharedManager;

@end

DareTokuDataManager.mについては、長いのでiOS開発におけるパターンによるオートマティズム片手にコーディングしてください。


 そして前回作ったViewControllerに、DB保存機能を追加します。

//位置情報取得
- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation {
    NSLog(@"didUpdateToLocation");
    Location *location;
    location = _location;

    CLLocationCoordinate2D coordinate = [newLocation coordinate];
    self.latitude.text = [[NSNumber numberWithDouble:coordinate.latitude] stringValue];
    self.longitude.text = [[NSNumber numberWithDouble:coordinate.longitude] stringValue];
    
    if (!location) {
        location = [[DareTokuDataManager sharedManager] insertNewLocation];
    }
    [location setLatitude:[NSNumber numberWithDouble:coordinate.latitude]];
    [location setLongitude:[NSNumber numberWithDouble:coordinate.longitude]];
    [location setCreationDate:[newLocation timestamp]];
    
    [[DareTokuDataManager sharedManager] save];
}


 取得したデータの確認用に、一時的なテーブルビューを作りました。


 またsqliteの実ファイルはDocumentsの部分に作られているので、info.plistで"Application supports iTunes file sharing"をYESにすれば、iTunesから扱えるようになります。


 次回は取得したデータから地図で表示出来るようにしたいと思います。
enjoy!!


目次
iPhoneでカレログを作ろう その1 位置情報の取得
iPhoneでカレログを作ろう その2 DBへのデータ格納
iPhoneでカレログを作ろう その3 地図の表示

iOS開発におけるパターンによるオートマティズム
木下 誠
ビー・エヌ・エヌ新社
売り上げランキング: 45392