#記事一覧
Swift MkMapViewで地図アプリ作成してみた(記事一覧)
#iOSのアプリから取得した緯度経度を保持する
###iOSのアプリでロングタップした位置をwatchOSに送信する
sendMessageでwatchOSにロングタップした位置を送信する方法は以下の記事を参照ください。
- Swift MkMapViewで地図アプリ作成してみた(14)- iOSから送信したデータをwatchOSで受信する
- Swift MkMapViewで地図アプリ作成してみた(15)- watchOSからiOSにデータ送信を要求する
###受信した緯度経度を保持する
クラスのメンバ変数に緯度経度を追加し、iOSからsendMessageで送信された緯度経度を変数に設定する。
class InterfaceController: WKInterfaceController,
WCSessionDelegate { // sasaki
var dlon:Double! = 0
var dlat:Double! = 0
// iPhoneからMessage受信
public func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Swift.Void){
print("receiveMessage::\(message)")
guard let lon = message["lon"] as? Double else {
return
}
guard let lat = message["lat"] as? Double else {
return
}
// iOSからsendMessageで送信された緯度経度を変数に設定
dlon = lon
dlat = lat
}
#CLLocationManagerで現在位置を取得する
###CLLocationManagerのdelegateを登録する
CoreLocationをimportし、CLLocationManagerDelegateを継承する。
現在位置取得に必要なCLLocationManagerの変数を定義する。
import CoreLocation
class InterfaceController: WKInterfaceController,
WCSessionDelegate,
CLLocationManagerDelegate {
var dlon:Double! = 0
var dlat:Double! = 0
var locationManager = CLLocationManager()
Initializerメソッドで、CLLocationManagerのdelegateを登録する。
override init() {
super.init()
// CLLocationManagerのdelegateを登録
locationManager.delegate = self
}
###CLLocationManagerで現在位置の更新を受信する
以下の条件を満たしている場合に、startUpdatingLocationメソッドで現在位置の更新を開始できる。
- locationServicesEnabledメソッドで端末の位置情報サービスが有効である
- authorizationStatusメソッドでユーザから位置情報利用の許可を一度得ている
override init() {
super.init()
// CLLocationManagerのdelegateを登録
locationManager.delegate = self
// 端末の位置情報サービスが有効である
if CLLocationManager.locationServicesEnabled() {
switch CLLocationManager.authorizationStatus() {
// ユーザから位置情報利用の許可を一度得ている
case .authorizedAlways, .authorizedWhenInUse:
// 現在位置の更新を開始
locationManager.startUpdatingLocation()
case .notDetermined:
print("notDetermined")
case .restricted:
print("restricted")
case .denied:
print("denied")
}
}
}
locationManagerメソッドを定義すると、現在位置の更新を受信できる。
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(Date(), locations)
}
#現在位置更新を受信した時にiOSから受信した位置との距離を表示する
###2点間の距離(m)を算出するメソッドを作成する
引数に現在位置を指定して、クラスのメンバ変数に設定したiOSから受信した緯度経度との距離(m)を算出するメソッドを作成する。
func calcDistance(_ a: CLLocationCoordinate2D) -> CLLocationDistance {
// CLLocationオブジェクトを生成
let aLoc: CLLocation = CLLocation(latitude: a.latitude, longitude: a.longitude)
let cloclon:CLLocationDegrees = CLLocationDegrees(exactly: dlon)!
let cloclat:CLLocationDegrees = CLLocationDegrees(exactly: dlat)!
let bLoc: CLLocation = CLLocation(latitude: cloclat, longitude: cloclon)
// CLLocationオブジェクトのdistanceで2点間の距離(m)を算出
let dist = bLoc.distance(from: aLoc)
return dist
}
###現在位置の更新を受信した時に距離を算出してwatchOSのアプリに表示する
locationManagerメソッドで現在位置の更新を受信した時に、iOSから受信した緯度経度との距離(m)を算出して表示する。
// CLLocationManagerのdelegate:現在位置更新
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(Date(), locations)
// iOSから緯度経度を受信している場合
if dlon != 0 && dlat != 0 {
// 現在位置とiOSから受信した緯度経度との距離(m)を算出する
let distance = calcDistance((locations.last?.coordinate)!)
// mをyardに変換する
let yardStr = Int(distance * 1.09361)
// 距離をラベルのテキストに設定する
let fontSize = UIFont.systemFont(ofSize: 45)
let text = String(Int(distance).description + "m" + "\n" + yardStr.description + "y")
let attrStr = NSAttributedString(string: text, attributes:[NSAttributedString.Key.font:fontSize])
label.setAttributedText(attrStr)
}
}
#iOSから緯度経度を受信した時にも現在位置との距離を表示する
###現在位置をクラスのメンバ変数に保持する
メンバ変数をCLLocationCoordinate2D型で定義する。
class InterfaceController: WKInterfaceController,
WCSessionDelegate,
CLLocationManagerDelegate {
var locCord2D:CLLocationCoordinate2D?
現在位置をクラスのメンバ変数に保持する。
// CLLocationManagerのdelegate:現在位置更新
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(Date(), locations)
// 現在位置をクラスのメンバ変数に保持する
locCord2D = (locations.last?.coordinate)!
// iOSから緯度経度を受信している場合
if dlon != 0 && dlat != 0 {
###iOSから緯度経度を受信した時にも現在位置との距離を表示する
sessionメソッドに距離を表示する処理を追加する。
// iPhoneからMessage受信
public func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Swift.Void){
print("receiveMessage::\(message)")
guard let lon = message["lon"] as? Double else {
return
}
guard let lat = message["lat"] as? Double else {
return
}
// iOSからsendMessageで送信された緯度経度を変数に設定
dlon = lon
dlat = lat
// iOSから緯度経度を受信した時にも現在位置との距離を表示する
if nil != locCord2D {
// 現在位置とiOSから受信した緯度経度との距離(m)を算出する
let distance = calcDistance(locCord2D!)
// mをyardに変換する
let yardStr = Int(distance * 1.09361)
// 距離をラベルのテキストに設定する
let fontSize = UIFont.systemFont(ofSize: 45)
let text = String(Int(distance).description + "m" + "\n" + yardStr.description + "y")
let attrStr = NSAttributedString(string: text, attributes:[NSAttributedString.Key.font:fontSize])
label.setAttributedText(attrStr)
}
}