プログラマでありたい

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

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

iPhoneでカレログを作ろう その1 位置情報の取得

 話題沸騰のAndroidアプリ、カレログ。初期に打ち出したコンセプトは確かにアレですが、彼氏の監視という利用方法から離れれば色々面白い製品になるのではないでしょうか?例えばモバイルデバイス管理(MDM)の製品は、似たような機能が搭載されています。例えば運送会社等で車に設置して、リアルタイムにどこに走っているかを一元管理して配車の最適化等でも使えるのではないかなと思います。
 ということで、技術的な検証の為にiPhoneでも似たような機能を作ってみようと思います。カレログの機能の構成要素としては、次の4点があります。(あとはサーバとの連携機能。)一部iOSでは許可されていないものもありそうですが、Appleのサンプルプログラムを元に順番に機能を実装していこうと思います。
・位置情報
・バッテリー残量の把握
・通信履歴の取得
・インストールされているアプリの一覧


 まずは、位置情報の取得からです。
サンプルコードを元に必要な機能を組み立てていきましょう。
Apple Developer Sample Code


 ざっと見て、LocateMeとLocationsが関係しそうです。
LocateMe
Locations
LocateMeはその名の通り、位置情報を使うアプリのサンプルコードです。Locationsは、位置情報をCoreData(DB)に格納してUITableViewで操作するサンプルコードです。2つのコードをみていると、CoreLocationフレームワークをインポートしてCLLocationManagerDelegateをデリゲートすることが解ります。ということで、まず位置情報を取得するところまで作ってみましょう。


 アプリ名は何でも良いですが、仮にDareTokuで作りました。
アプリのひな形は画面遷移等もシンプルなので、View-based Applicationでよいでしょう。
プロジェクトを作成したら、CoreLocation.frameworkを追加してください。
追加後に対象ソースにインポートして、CLLocationManagerを宣言しDelegateの設定も行います。

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>


@interface DareTokuViewController : UIViewController<CLLocationManagerDelegate> {
    CLLocationManager *locationManager;
}
@property (nonatomic, retain) CLLocationManager *locationManager;

@end


 CLLocationManagerの主なプロパティには測位の精度と取得間隔(時間ではなく、距離)があります。精度の要求を高くする程、バッテリーの減りも早いようです。メソッドとしては、GPSとコンパスの使用可否を判断するものと、開始・停止があります。今回はコンパスは関係ないので、GPSのスタートストップであるstartUpdatingLocation,stopUpdatingLocationを使います。またデリゲートメソッドとして、didUpdateToLocationというGPSから値を取得した時に発生するイベントがあります。このあたりを使えば、位置情報取得の一通りの機能が作れます。詳しくはiOS Developer Libraryで確認ください。
CLLocationManager Class Reference
CLLocationManagerDelegate Protocol Reference

#import "DareTokuViewController.h"

@implementation DareTokuViewController

@synthesize locationManager;
@synthesize startButton;
@synthesize stopButton;
@synthesize latitude;
@synthesize longitude;

...

#pragma mark -
#pragma mark Location manager

//Location Manager 設定
- (CLLocationManager *)locationManager {
	
    if (locationManager != nil) {
		return locationManager;
	}
	
	locationManager = [[CLLocationManager alloc] init];
	[locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
	[locationManager setDelegate:self];
	
	return locationManager;
}


//位置情報取得
- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation {
    NSLog(@"didUpdateToLocation");
    CLLocationCoordinate2D coordinate = [newLocation coordinate];
    self.latitude.text = [[NSNumber numberWithDouble:coordinate.latitude] stringValue];
    self.longitude.text = [[NSNumber numberWithDouble:coordinate.longitude] stringValue];
    
}

//位置情報取得失敗
- (void)locationManager:(CLLocationManager *)manager
       didFailWithError:(NSError *)error {
    NSLog(@"can't get location");
}

#pragma mark -
#pragma mark Buttion Action
- (IBAction) startButtonTapped {
    [[self locationManager] startUpdatingLocation];
}
- (IBAction) stopButtonTapped {
    [[self locationManager] stopUpdatingLocation];
}

@end


 アプリを起動してStartボタンを押すと無事に位置情報の取得が出来ました。
こんな感じで一つづつ機能を実装していこうかと思います。またある程度までいったら、
どこかにソースを全部公開しようと思います。


 次回は取得したデータをローカルのDBに保存しようと思います。
enjoy!!


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


iPhone SDKの教科書―Cocoa Touchプログラミング、最初の一歩
赤松 正行
秀和システム
売り上げランキング: 13153

あなたのiPhone/iPadアプリを5秒でiTunesとファイル共有する方法

 幾つかのiPhone/iPadアプリはiTunesのAppsからフィル共有が出来ます。アプリによっては、これがあるかないかで使い勝手が大きく変わる場合があります。自分が作ったアプリの機能を考えて、便利になるようであれば是非実装しましょう。実はこのファイル共有の機能を実装するのは、非常に簡単です。設定ファイルにチェックを一つ入れるだけです。plistの項目にApplication supports iTunes file sharingを追加して、YESを付けるだけです。

 共有されるファイルのディレクトリは、Documents以下です。共有したいファイルはそこに保存するようにしてください。逆に言うと、ユーザに見られると困るファイルはDocumentsの下においてはいけません。またユーザが自由にファイルの出し入れが出来る場合は、アプリが想定しているファイル以外がくる可能性も出てきます。このあたりのチェックもしっかりする必要がありますね。


 ビルドして確認すると、次のようにファイルが見えるはずです。
何はともあれ、是非お試しください!!


See Also:
iOS: About File Sharing - Apple Support