今回からは、新しいアプリとしてロギングアプリを取り上げよう。「ロギング」とは記録を残すという意味で、いろんなロギングが考えられるが、ここでは位置情報のログを取る事にする。iPhoneを持ってあちらこちらに移動して、いく先々でちょっとしたつぶやきを残す、というアプリを作ってみよう。

iPhoneでの位置情報の取得

iPhone OSでは、現在地情報を取得する事ができる。これは、モバイル機器では非常に魅力的な機能になる。位置情報を取得するための技術は、以下の3つの複合となっている。

  • GPS
  • 3Gネットワーク
  • Wi-Fi

デバイスによって利用できる技術に差が出てくる。iPhoneではすべての技術が利用できるし、iPod touchではWi-Fiしか利用する事ができない。従って、屋外で十分な精度で位置情報を取得するには、iPhoneが必須と言えるだろう。

iPhoneで位置情報を取得するアプリを作るときは、いくつか気をつけなくてはいけない事がある。まず、バッテリーの問題だ。位置情報の取得にはGPSや3Gネットワークを利用するのだが、これらのチップはバッテリーを大きく消費する。

また、これはiPhone OSの制限なのだが、アプリケーションをバックグラウンドで動かす事ができない。従って、長時間のログを取りたいアプリケーションはその間常に前面で起動しており、他のアプリケーションは使えない事になる。

このようなことから、ユーザの移動を常に追跡するようなトレイル系のアプリケーションは、ユーザにある種の覚悟を求める事になるだろう。つまり、バッテリーの持ちは悪くなるし、その間他のアプリケーションは使えない、のだ。もちろん、このような前提であっても使いたいアプリケーションもあるだろう。

この連載で作成するアプリは、もう少しユーザに優しい仕様にしてみよう。機能としては、あちこちの場所に移動して、「つぶやき」をログするアプリだ。使い方としては、ある場所に移動したら、そこでつぶやきを入力する。入力さえしてしまえば、アプリケーションは終了してしまってかまわない。入力したつぶやきは、地図上に表示されて確認する事ができる。

これを「Spot Log」と名付けよう。このようなアプリケーションの作り方を紹介しよう。

Core Locationの使い方

位置情報を取得するには、Core Locationというフレームワークを利用する。このフレームワークの中心となるのは、CLLocationManagerというクラスだ。

CLLocationManagerクラスの使い方は、とても簡単である。まず、クラスをインスタンス化する。そして、デリゲートを設定する。後は、現在地の更新を開始するstartUpdatingLocationメソッドを呼べばいい。

List 1.

    // ロケーションマネージャを作成する
    _locationManager = [[CLLocationManager alloc] init];
    _locationManager.delegate = self;

    // 現在地の更新を開始する
    [_locationManager startUpdatingLocation];

これで、現在地の更新が行われると、デリゲートに通知が送られてくる。呼び出されるのは、locationManager:didUpdateToLocation:fromLocation:というメソッドだ。

List 2.

- (void)locationManager:(CLLocationManager*)manager
        didUpdateToLocation:(CLLocation*)newLocation
        fromLocation:(CLLocation*)oldLocation
{
    // 現在地情報が更新された
}

簡単ではあるが、逆に言うとこれしか操作を行う事ができない。GPSや3Gネットワークからどのような情報を取得できているのか、それらをどのように用いて座標を決定しているのか、といった部分には触る事ができない。

現在地座標は、CLLocationManagerのlocationプロパティから取得する事もできる。これは、CLLocationというクラスで表されている。このクラスにはcoordinateというプロパティがあり、これが緯度経度を表す。

List 3.

    // 緯度経度情報を取得する
    CLLocationCoordinate2D  coordinate;
    coordinate = location.coordinate;

    NSLog(@"latitude=%f, longitude=%f", coordinate.latitude, cooridnate.longitude);

coordinateプロパティは、CLLocationCoordinate2Dという構造体であり、latitudeとlongitudeというフィールドで緯度経度を表している。

これで、現在地情報を知る事ができる。

Spot Logの作成

では、Spot Logアプリケーションを作ってみよう。Xcodeを立ち上げて、新規プロジェクトを作成する。そして、xibファイルを開いて、ユーザインタフェースのレイアウトから行おう。

ユーザインタフェースとして、つぶやきを入力するためのテキストフィールドとボタンを用意する。次のように配置しよう。

コントローラクラスに、アウトレットとアクションを適切に追加して、それぞれ接続しよう。

このアプリケーションでは、現在地情報が取得可能なときに、つぶやきを行えるようにする。つぶやけるかどうかは、ボタンの有効/無効で表す事にしよう。CLLocationManagerのデリゲートメソッドで、この処理を行う。

List 4.

- (void)locationManager:(CLLocationManager*)manager
        didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation*)oldLocation
{
    // ログボタンを有効化する
    _logButton.enabled = _locationManager.location != nil;
}

ログボタンを押したら、つぶやきを行う。つぶやきはテキストとして表すが、これを緯度経度情報と、時刻情報とともに保存しておこう。これを行うのが、次のメソッドである。

List 5.

- (IBAction)logAction
{
    // ログを取得する
    NSString*   log;
    log = _textField.text;
    if ([log length] == 0) {
        return;
    }

    // 現在地を取得する
    CLLocation* location;
    location = _locationManager.location;

    // ログを追加する
    [_logs addObject:[NSDictionary dictionaryWithObjectsAndKeys:
            [NSNumber numberWithDouble:location.coordinate.latitude], @"latitude",
            [NSNumber numberWithDouble:location.coordinate.longitude], @"longitute",
            [NSDate date], @"date",
            log, @"log",
            nil]];

    // ログを保存する
    [self saveLogs];

    // キーボードを隠す
    [_textField resignFirstResponder];
}

ログは、NSDictionaryの形にまとめて、配列に挿入して管理してみた。

これで、位置情報を取得して、それにひもづける形でつぶやきを保存する事ができた。次回は、これを地図上に表示してみよう。

ここまでのソースコード: SpotLog-1.zip