スクリーンショット 2015-06-30 21.13.30

位置情報を取得するアプリを作ります。

Xcodeをいじるのでポイントは以下
1.Core Location フレームワークを追加

スクリーンショット 2015-06-30 21.17.17

2.info.plistにkey:NSLocation… value:任意の文言 を追加する。
・アプリ使用中のみ許可: NSLocationWhenInUseUsageDescription
・アプリ使用中以外も常に許可: NSLocationAlwaysUsageDescription

スクリーンショット 2015-06-30 21.18.35

スクリーンショット 2015-06-30 21.18.23

3.実装する
実装サンプルはSwift Docsまんまです。

//
//  ViewController.swift
//  CoreLocation001
//

import UIKit
import CoreLocation

class ViewController: UIViewController , CLLocationManagerDelegate{
    
    var myLocationManager:CLLocationManager!
    
    // 緯度表示用のラベル.
    var myLatitudeLabel:UILabel!
    
    // 経度表示用のラベル.
    var myLongitudeLabel:UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // ボタンの生成.
        let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        myButton.backgroundColor = UIColor.orangeColor()
        myButton.layer.masksToBounds = true
        myButton.setTitle("Get", forState: .Normal)
        myButton.layer.cornerRadius = 50.0
        myButton.layer.position = CGPoint(x: self.view.bounds.width/2, y:self.view.bounds.height/2)
        myButton.addTarget(self, action: "onClickMyButton:", forControlEvents: .TouchUpInside)
        
        // 緯度表示用のラベルを生成.
        myLatitudeLabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 30))
        myLatitudeLabel.layer.position = CGPoint(x: self.view.bounds.width/2, y:self.view.bounds.height/2+100)
        
        // 軽度表示用のラベルを生成.
        myLongitudeLabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 30))
        myLongitudeLabel.layer.position = CGPoint(x: self.view.bounds.width/2, y:self.view.bounds.height/2+130)
        
        
        // 現在地の取得.
        myLocationManager = CLLocationManager()
        
        myLocationManager.delegate = self
        
        // セキュリティ認証のステータスを取得.
        let status = CLLocationManager.authorizationStatus()
        
        // まだ認証が得られていない場合は、認証ダイアログを表示.
        if(status == CLAuthorizationStatus.NotDetermined) {
            println("didChangeAuthorizationStatus:\(status)");
            // まだ承認が得られていない場合は、認証ダイアログを表示.
            self.myLocationManager.requestAlwaysAuthorization()
        }
        
        // 取得精度の設定.
        myLocationManager.desiredAccuracy = kCLLocationAccuracyBest
        // 取得頻度の設定.
        myLocationManager.distanceFilter = 100
        
        self.view.addSubview(myButton)
    }
    
    func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        
        println("didChangeAuthorizationStatus");
        
        // 認証のステータスをログで表示.
        var statusStr = "";
        switch (status) {
        case .NotDetermined:
            statusStr = "NotDetermined"
        case .Restricted:
            statusStr = "Restricted"
        case .Denied:
            statusStr = "Denied"
        case .AuthorizedAlways:
            statusStr = "AuthorizedAlways"
        case .AuthorizedWhenInUse:
            statusStr = "AuthorizedWhenInUse"
        }
        println(" CLAuthorizationStatus: \(statusStr)")
    }
    
    // ボタンイベントのセット.
    func onClickMyButton(sender: UIButton){
        // 現在位置の取得を開始.
        myLocationManager.startUpdatingLocation()
    }
    
    // 位置情報取得に成功したときに呼び出されるデリゲート.
    func locationManager(manager: CLLocationManager!,didUpdateLocations locations: [AnyObject]!){
        
        // 緯度・経度の表示.
        myLatitudeLabel.text = "緯度:\(manager.location.coordinate.latitude)"
        myLatitudeLabel.textAlignment = NSTextAlignment.Center
        
        myLongitudeLabel.text = "経度:\(manager.location.coordinate.longitude)"
        myLongitudeLabel.textAlignment = NSTextAlignment.Center
        
        
        self.view.addSubview(myLatitudeLabel)
        self.view.addSubview(myLongitudeLabel)
        
    }
    
    // 位置情報取得に失敗した時に呼び出されるデリゲート.
    func locationManager(manager: CLLocationManager!,didFailWithError error: NSError!){
        print("error")
    }
    
}

4.iOSシュミレータで動かす時には、Debugモードで位置情報を付与してあげる。

シュミレータ起動->Debug->Simular location

スクリーンショット 2015-06-30 21.23.43

ここで先ほどinfo.plistに入れたvalueの文言が表示されてますね。
スクリーンショット 2015-06-30 21.28.42

Allowを選んで、位置情報が表示されました。
スクリーンショット 2015-06-30 21.13.30

5.シュミレータのAllow情報などを消すには
iOS Simulator -> Reset Content and Settings

スクリーンショット 2015-06-30 21.28.03

 

6.位置情報の取得タイミング!

めっちゃはまりました。位置情報の取得タイミングは非同期です。
locationManagerが動くと、位置情報は取得されています。(おそらく)

そのため、位置情報を取得して、fooサーバにlat/lngを付与して情報を取得するような処理を書きたい時は
locationManagerの中で、位置情報が取得できた後に、記述する必要があります。

こう書くと当たり前ですが、結構な時間詰まってしまいました。。。

//
//  ViewController.swift
//

import UIKit
import CoreLocation

class ViewController: UIViewController,CLLocationManagerDelegate {
    
    
    var myLocationManager:CLLocationManager!
    
    struct location{
        static var lat = ""
        static var lng = ""
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Geo Request
        self.getGeo()

    }
    
    func getGeo(){
        // 現在地の取得.
        myLocationManager = CLLocationManager()
        
        myLocationManager.delegate = self
        // セキュリティ認証のステータスを取得.
        let status = CLLocationManager.authorizationStatus()
        // まだ認証が得られていない場合は、認証ダイアログを表示.
        if(status == CLAuthorizationStatus.NotDetermined) {
            println("didChangeAuthorizationStatus:\(status)");
            // まだ承認が得られていない場合は、認証ダイアログを表示.
            self.myLocationManager.requestAlwaysAuthorization()
        }
        // 取得精度の設定.
        myLocationManager.desiredAccuracy = kCLLocationAccuracyBest
        // 取得頻度の設定.
        myLocationManager.distanceFilter = 100

        // 現在位置の取得を開始.
        myLocationManager.startUpdatingLocation()
    }
    
    func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        
        println("didChangeAuthorizationStatus");
        
        // 認証のステータスをログで表示.
        var statusStr = "";
        switch (status) {
        case .NotDetermined:
            statusStr = "NotDetermined"
        case .Restricted:
            statusStr = "Restricted"
        case .Denied:
            statusStr = "Denied"
        case .AuthorizedAlways:
            statusStr = "AuthorizedAlways"
        case .AuthorizedWhenInUse:
            statusStr = "AuthorizedWhenInUse"
        }
        println(" CLAuthorizationStatus: \(statusStr)")
    }
    
    // 位置情報取得に成功したときに呼び出されるデリゲート.
    func locationManager(manager: CLLocationManager!,didUpdateLocations locations: [AnyObject]!){
        
        location.lat = String(stringInterpolationSegment: manager.location.coordinate.latitude)
        location.lng = String(stringInterpolationSegment: manager.location.coordinate.longitude)
        
        println(location.lat)
        println(location.lng)
        
        // HTTP Request ★★★
        self.reqHttp()
        
    }
    
    // 位置情報取得に失敗した時に呼び出されるデリゲート.
    func locationManager(manager: CLLocationManager!,didFailWithError error: NSError!){
        print("error")
    }
    
    
    func reqHttp(){
        // 通信先のURLを生成.
        var myUrl:NSURL = NSURL(string:"http://foo/bar?lat=" + String(location.lat) + "&lng="+String(location.lng)+"/")!
        
        // リクエストを生成.
        var myRequest:NSURLRequest  = NSURLRequest(URL: myUrl)
        // 送信処理を始める.
        NSURLConnection.sendAsynchronousRequest(myRequest, queue: NSOperationQueue.mainQueue(), completionHandler: self.getHttp)
        println(myUrl)
    }
    
    func getHttp(res:NSURLResponse?,data:NSData?,error:NSError?){
        // NSData -> NSDictionary
        let json:NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments, error: nil) as! NSDictionary
    }
        
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }


}

 

以上で、位置情報の取得方法でした!

参考
https://sites.google.com/a/gcl……hino-qu-de
http://dev.classmethod.jp/refe……ification/
http://swift-studying.com/blog……ft/?p=1078
http://shirokai.hatenablog.com……/swift-gps
http://www.hnyssh.net/?p=577