Xcode
Swift
WatchKit
WatchKitDay 16

WatchKitで現在位置の地図を表示する

More than 3 years have passed since last update.

WatchKitでは静的な地図を表示することができます。

残念ながら、スワイプやピンチなどで移動拡縮ができるような動的な地図はありません。

ここではGPSを使って現在地の地図を表示する方法を説明します。

なお、WatchにはGPSはついていないのでiPhoneのGPSを利用することになります。(ここ大事です)

位置情報を取得するのに使用するCoreLocationの詳細については、

リファレンスか別の記事を参照してください。


とりあえず地図を表示してみる

WKInterfaceMapクラスを使用して下記の手順で地図を表示することができます。


  1. ストーリーボードでViewにMapを追加

  2. Mapのアウトレットを作成

  3. 緯度経度を指定

@IBOutlet weak var map: WKInterfaceMap!

override init() {
super.init()
// 座標の指定
let coordinate = CLLocationCoordinate2DMake(37.331667, -122.030833)
let span = MKCoordinateSpanMake(1.0, 1.0)
let region = MKCoordinateRegionMake(coordinate, span)
map.setRegion(region)
}

ここではApple本社の場所を指定してみました。


現在地の地図を表示してみる

GPSから位置情報を取得して設定するだけなんですが、

iOS App側で位置情報を使用する設定をしてあげないといけません。

この設定をするのはWatch Extensionではなく、iOS App側です。


iOS App側の設定

位置情報を使用する設定を行います。


Info.plistに位置情報を使用する目的を設定

NSLocationDescription.png

こんな感じで下記2項目をInfo.plistに追加します。


  • NSLocationWhenInUseUsageDescription

  • NSLocationAlwaysUsageDescription

なお、今回の例だと2番目の項目だけでも動くかと思います。


iOSアプリを起動して位置情報へのアクセスを許可する

var locationManager = CLLocationManager()

override func viewDidLoad() {
super.viewDidLoad()

// 位置情報へのアクセスを要求する
locationManager.requestAlwaysAuthorization()
}

これでiOS Appを起動すると、アクセス許可の確認がでるので許可します。


追記(2015/2/20)

CLLocationManagerの変数をメソッド内で定義してインスタンスを作ると

確認ダイアログが出ない可能性があるとのことなので修正しました。

@SatoTakeshiX さん、ご指摘ありがとうございます!



Watch Extension側の設定


位置情報を取得するコードを書く

import WatchKit

import Foundation
import CoreLocation

class InterfaceController: WKInterfaceController, CLLocationManagerDelegate {
@IBOutlet weak var map: WKInterfaceMap!

var locationManager = CLLocationManager()

override init() {
super.init()

locationManager.delegate = self

if CLLocationManager.locationServicesEnabled() {
switch CLLocationManager.authorizationStatus() {
case .AuthorizedAlways, .AuthorizedWhenInUse:
locationManager.startUpdatingLocation()
break
default:
break
}
}
}

func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) {
let lat = newLocation.coordinate.latitude
let lng = newLocation.coordinate.longitude
let coordinate = CLLocationCoordinate2DMake(lat, lng)
let span = MKCoordinateSpanMake(1.0, 1.0)
let region = MKCoordinateRegionMake(coordinate, span)
map.setRegion(region)
}
}


確認してみる

もちろん実機は無いのでシミュレータで確認します。

メニュー > Debug > Location > Custom Location...

緯度経度を変更するとWatch Appに反映されることが確認できると思います。

地名
緯度
経度

APPLE Inc.
37.331667
-122.030833

東京駅
35.681382
139.766084

モン・サン=ミシェル
48.636063
-1.511457

例は最低限のコードなのでなんども更新がかかるなど問題はありますが

とりあえず現在地の地図を表示することはできました。


まとめ

WatchKitで位置情報を扱う時は、iOS Appで位置情報へのアクセス許可を行う必要がある。

参考:

WatchKit Framework Reference > WKInterfaceMap Class Reference

iOS 8から位置情報を取得する方法が変わるよ -@koogawaさん