iOSプログラミング with Swift 2


2016.05.29: created by

Swiftで位置情報と電子コンパスを使う

  1. Xcode を起動して "Create a new Xcode project" で "iOS" -> "Application" -> "Single View Application" として新しいプロジェクトを開きます。 ここではプロジェクト名を SwiftGeo としています。



  2. プロジェクトの最初に表示される画面は、ウィンドウの左側に表示されている "Show the project navigator" アイコンをクリックしても表示されます。 "General" -> "Linked Frameworks and Libraries" ->"+"ボタン を押して CoreLocation.framework を追加します。









  3. 位置情報サービスの利用許可を得る設定を行う。 (重要)
  4. info.plist を表示した状態で、右クリックし"Add row" を選択し、

      Key:    NSLocationWhenInUseUsageDescription
      Type:   String
      Value:  現在地の情報を利用します。
    
    を追加します。 ここに追加した説明は、「許可を求める確認ダイアログ」や 「設定 -> プライバシー -> 位置情報サービスのアプリ設定」 で表示されます。







  5. Main.storyboard上の ViewController に、右下の "Object library" から "Label" をドラッグして5行2列で合計10個配置します。各ラベルはAttribute Inspectorで、 "alignment"を「左詰め」にしておきましょう。 左側の5個のラベルは、textをそれぞれ"緯度","経度","標高", "偏角", "方位" に変更しましょう。



  6. Main.storyboard上の ViewController に、右下の "Object library" から "Button" を2個ドラッグして配置します。 さらに、"Button"に表示されているテキストを "Start" と "Stop" にします。



  7. Main.storyboard上の ViewController に、右下の "Object library" から "Segment Control" をドラッグして "偏角" の右側に配置します。 さらに、"Segment Control"に表示されているテキストを "磁北" と "真北" にします。



  8. プロジェクトに画像ファイルを追加します。 ウィドウの右側の"Project Navigator" でプロジェクト名のところを右クリックして "Add Files to プロジェクト名" を選択し、"CompassBG.png", "CompassFG.png" を追加します。 このときOptionsをクリックして、"Destination: [ ] Copy items if needed" にチェックをつけておくこと(重要)。







  9. CompassBG.png CompassFG.png

    これにより、ウィンドウ右下の Meida Library に追加した画像が表示されるようになります。




    Main.storyboard上の画面に CompassBG.png, CompassFG.png の順でドラッグして重なるように配置します。 配置する位置は、後からウィンドウ右上の Size Inspector の View の X, Y で位置を調整できます。







  10. Main.storyboardが表示されている状態で、 ウィンドウの右上の "Show the Assistant Editor" ボタン をクリックして、右側のウィンドウに ViewController.swift が表示されている 状態にします。
  11. Main.storyboard上の右側の(textを"Label"から変更していない) 12個のLabel について、 まず1回クリックして選択してから、 右マウスボタン(またはControllキー+左マウスボタン)でドラッグして、 右側の画面のViewController.swift の
    class ViewController: UIViewController {
    
    の下の行まで持っていきます。
  12. Main.storyboard上の部品を ViewController.swift にConnectします。

    Viewのインスタンス Connectionの種類名前
    Button(Start)Action (TouchUpInside)tapStart
    Button(Stop) Action (TouchUpInside)tapStop
    Label(緯度の右) OutletlatLabel
    Label(経度の右) OutletlngLabel
    Label(標高の右) OutletaltLabel
    Label(偏角の右) OutletargLabel
    Label(方位の右) OutletdirLabel
    Segment Control OutletnorthSwitch
    CompassFG.png OutletcompassFG



  13. ViewController.swift を変更します。
  14. ViewController.swiftに追加するコード(赤字部分)
    import UIKit
    import CoreLocation
    
    class ViewController: UIViewController, CLLocationManagerDelegate {
        @IBOutlet weak var latLabel: UILabel!
        @IBOutlet weak var lngLabel: UILabel!
        @IBOutlet weak var altLabel: UILabel!
        @IBOutlet weak var argLabel: UILabel!
        @IBOutlet weak var dirLabel: UILabel!
        @IBOutlet weak var northSwitch: UISegmentedControl!
        @IBOutlet weak var compassFG: UIImageView!
        
        let lm = CLLocationManager()
    
        @IBAction func tapStart(sender: AnyObject) {
            disabledLocationLabel()
            lm.requestWhenInUseAuthorization()
            lm.delegate = self
            startLocationService()
            startHeadingService()
        }
    
        @IBAction func tapStop(sender: AnyObject) {
            lm.stopUpdatingLocation()
            lm.stopUpdatingHeading()
        }
    
        func locationManager(manager: CLLocationManager, didUpdateLocations locations:[CLLocation]) {
            let locationData = locations.last
            if let lng = locationData?.coordinate.longitude {
                lngLabel.text = String(format:"%.6f",lng)
            }
            if let lat = locationData?.coordinate.latitude {
                latLabel.text = String(format:"%.6f",lat)
            }
            if let alt = locationData?.altitude {
                altLabel.text = String(format:"%.6f",alt)
            }
        }
        
        func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
            switch status {
            case .AuthorizedAlways, .AuthorizedWhenInUse :
                lm.startUpdatingLocation()
            case .NotDetermined:
                lm.stopUpdatingLocation()
                disabledLocationLabel()
            default:
                lm.stopUpdatingLocation()
                disabledLocationLabel()
            }
        }
        
        func locationManager(manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
            var arg = newHeading.magneticHeading - newHeading.trueHeading
            if arg < 0 { arg += 360 }
            argLabel.text = String(format:"%.6f",arg)
            
            let northDir: CLLocationDirection =
                (northSwitch.selectedSegmentIndex == 0) ? newHeading.magneticHeading : newHeading.trueHeading
            compassFG.transform = CGAffineTransformMakeRotation(CGFloat(-northDir * M_PI/180))
            dirLabel.text = String(format:"%.6f",northDir)
            
        }
        
        func startHeadingService() {
            northSwitch.selectedSegmentIndex = 0
            lm.headingOrientation = .Portrait
            lm.headingFilter = 1
            lm.startUpdatingHeading()
        }
        
        func startLocationService() {
            lm.desiredAccuracy = kCLLocationAccuracyBest
            lm.distanceFilter = 1
            lm.startUpdatingLocation()
        }
        
        func disabledLocationLabel() {
            let msg = "位置情報の利用が未許可"
            lngLabel.text = msg
            latLabel.text = msg
            altLabel.text = msg
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    }
    
  15. Xcodeを起動中にiOSデバイスを Mac に接続すると、 Xcode のstatusに "Processing symbol files"

    と表示されて、しばらく待つと 左上の実行デバイスに 接続したiOSデバイスの名前が表示される。 これを選択して実行する。
  16. アプリが起動した状態で画面上の "Start" Button を押すと処理が開始される。 最初は、位置情報にアクセスしてよいか許可を求める画面が表示される。 これは後から、「設定 -> SwiftGeo -> 位置情報」でも変更できる。



  17. サンプルのプロジェクトはこちら。(Xcode 7.3.1版)


http://ynitta.com