Androidでの位置情報の取得方法を紹介したので、合わせてiOSでの位置情報の取得方法も紹介します。

両方使ってみて、iOSの方が簡単かなという印象がありました。

では使用方法を書いていきます。

CoreLocation.frameworkの追加

iOSで位置情報を取得、使用するためにはCoreLocation.frameworkを使用します。

以前、ライブラリの追加方法の記事を書いたので、これを参考にCoreLocation.frameworkを追加してください。

【Xcode】ライブラリの追加方法

ソースコード

Androidと同じ流れでまずはソースコードを紹介してから解説していきます。

CLLocationManager

以下のところでCLLocationManagerを生成しています。

1
2
3
4
5
6
7
8
- (void)getCurrentLocation
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
}

distanceFilter

This distance is measured relative to the previously delivered location. Use the value kCLDistanceFilterNone to be notified of all movements. The default value of this property is kCLDistanceFilterNone.
This property is used only in conjunction with the standard location services and is not used when monitoring significant location changes.

意訳すると、

「このdistance(距離)は以前の配信場所を基準に測られます。すべての動きを通知するkCLDistanceFilterNoneを使用してください。このプロパティのデフォルト値はkCLDistanceFilterNoneです。」

という意味です。

つまり、移動距離を正確に取りたいならkCLDistanceFilterNoneを使ってくださいということです。

ちなみに公式リファレンスをあさってみましたが、kCLDistaceFilterNone以外の値を見つけられませんでした。

誰か教えてください。

desiredAccuracy

The receiver does its best to achieve the requested accuracy; however, the actual accuracy is not guaranteed.
You should assign a value to this property that is appropriate for your usage scenario.
Determining a location with greater accuracy requires more time and more power.
The default value of this property is kCLLocationAccuracyBest.

これも意訳すると

「receiver(受信機)は要求された精度を達成するために最善を尽くすが、実際の精度は保証されません。あなたの使用状況に応じて、適切な値をこのプロパティに割り当てる必要があります。より高い精度での位置情報を取得する為に、より多くの時間とより多くの電力を必要とします。このプロパティのデフォルト値はkCLLocationAccuracyBestです。」

という意味です。

このプロパティはどれくらいの精度(位置情報の誤差を許すか)を指します。

デフォルト値(kCLLocationAccuracyBest)以外には以下の値があります。

  • kCLLocationAccuracyBestForNavigation;
  • kCLLocationAccuracyBest;
  • kCLLocationAccuracyNearestTenMeters;
  • kCLLocationAccuracyHundredMeters;
  • kCLLocationAccuracyKilometer;
  • kCLLocationAccuracyThreeKilometers;

大体値の名前を読めばわかると思いますが、より正確な情報が欲しい場合はCoreLocation Constants Reference | Mac Developer Libraryをお読みください。

delegate

これはCLLocationManagerDelegateを指定します。

Objective-CにおけるDelegateについては省略させて頂きます。

次はこのCLLocationManagerDelegateについて説明します。

CLLocationManagerDelegate

The CLLocationManagerDelegate protocol defines the methods used to receive location and heading updates from a CLLocationManager object.

「CLLocationManagerオブジェクトから場所とheadingの更新を受信する為に使用するメソッドを定義しています。」

という意味でしょうか。

ということで、CLLocationManagerが位置情報などを更新したときにCLLocationManagerDelegateを実装しているクラスに通知します。

delegateの指定は当たり前だと思いますが

1
self.locationManager.delegate = self;

でしています。

CLLocationManagerDelegateを実装した場合、以下のメソッドを実装します。(位置情報の更新に必要なメソッドのみを挙げています)

1
2
3
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
- (void)locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error

他にどのようなメソッドがあるか知りたい人は公式リファレンスを見てください。

CLLocationManagerDelegate Class Reference | iOS Developer Library

では一つずつ簡単に説明していきます。

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations

新しい位置情報を取得した時にこのメソッドが呼ばれます。

位置情報は(NSArray *)locationsに入っています。

この(NSArray *)locationsについてちょっと補足します。

なぜNSArrayCLLocationが渡されるのかについてです。

An array of CLLocation objects containing the location data. This array always contains at least one object representing the current location. If updates were deferred or if multiple locations arrived before they could be delivered, the array may contain additional entries. The objects in the array are organized in the order in which they occurred. Therefore, the most recent location update is at the end of the array.

という説明をしています。

意訳しながら進めていきます。

まず、(NSArray *)locationsには常に現在位置を表すCLLocationオブジェクトが少なくても1つ含まれているとのことです。

位置情報の更新が延期されたり再開された場合、その位置情報が配信される前に複数の場所に到着した場合にNSArrayにその位置情報が含まれるようになっています。

また配列内のオブジェクトの順番は、位置情報が配信された順(古い順)ということになります。

なので、最新の位置情報(CLLocationオブジェクト)は常に配列の最後にあります。

なので最新の位置情報を取得する場合は

1
2
3
4
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *newLocation = [locations lastObject];
}

で取得することができます。

位置情報の更新を追いたい場合は(NSArray *)locationsを同期的に処理すれば大丈夫です。

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error

Tells the delegate that the location manager was unable to retrieve a location value.

ということで、位置情報の取得に関するエラーが発生した場合に呼ばれるメソッドとなります。

引数に渡されるNSError *errorの中に含まれるErrorCodeは以下のページで確認してください。

Core Location Constants Reference | iOS Developer Library

- (void)locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error

Tells the delegate that updates will no longer be deferred.

なにかのエラーで位置情報の更新がされなくなった時に呼び出されるメソッドです。

エラー情報は引数に渡されるNSError *errorが保持しています。

このメソッドはタイムアウトが起きた時や距離パラメーターが超えたときなどに呼ばれます。

CLLocationManagerDelegateのまとめ

位置情報を取得する場合は

1
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations

を実装すれば問題ないです。

エラーに関しては

1
2
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
- (void)locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error

を実装してその度に対処するようにしましょう。

終わりに

iOSにおける位置情報の取得方法を紹介しました。

今回作ったサンプルはNinjaAdMax/SampleLocationiOSにアップしたので、参考になれば幸いです。

他にも、今流行のiBeaconなどもCoreLocation.frameworkに含まれていますので、触ってみる事をおすすめします。

長くなってしまいましたが、以上でおわります。

参考

CLLocationManager Class Reference | iOS Developer Library

CLLocationManagerDelegate Class Reference | iOS Developer Library

Core Location Constants Reference | iOS Developer Library