반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

[Swift] 현재 위치 정보 다루기

2015. 9. 14. 00:02 | Posted by 솔웅


반응형

요즘 Swift를 이용해서 iOS 모바일 어플리케이션 개발을 공부하고 있습니다.


스위프트로 현재 위치를 파악하려면 CoreLocation 을 사용해야 합니다.

아래 강좌를 한번 따라 해 봤는데요.


https://www.veasoftware.com/tutorials/2015/5/12/current-location-in-swift-xcode-63-ios-83-tutorial


일단 비쥬얼한 부분은 없이 코드만 있는 샘플입니다.

ViewController.swift 부분만 분석해 보겠습니다.


import UIKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate
{
   
    let locationManager = CLLocationManager()
   
    override func viewDidLoad()
    {
        super.viewDidLoad()
       
        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()
       
    }
   
    override func didReceiveMemoryWarning()
    {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
   
    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)
    {
       
        CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: {(placemarks, error)->Void in
           
            if (error != nil)
            {
                println("Error: " + error.localizedDescription)
                return
            }
           
            if placemarks.count > 0
            {
                let pm = placemarks[0] as! CLPlacemark
                self.displayLocationInfo(pm)
            }
            else
            {
                println("Error with the data.")
            }
        })
    }
   
    func displayLocationInfo(placemark: CLPlacemark)
    {
       
        self.locationManager.stopUpdatingLocation()
        println(placemark.locality)
        println(placemark.postalCode)
        println(placemark.administrativeArea)
        println(placemark.country)
       
    }
   
    func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!)
    {
        println("Error: " + error.localizedDescription)
    }
}


우선 CoreLocation 을 import 합니다.

그리고   ViewController 에 Delegate 프로토콜을 불러옵니다.


이 ViewController라는 클래스는 UIViewController 클래스와 CLLocationManagerDelegate 프로토콜을 사용한다고 처음에 선언했는데요.

이 CLLocationManagerDelegate 프로토콜은 location과 heading updates를 CLLocationManager 로부터 받게 됩니다.

(Delegate는 제 생각에는 자바에서의 일종의 리스너 역할을 하는 것 같습니다.)

이 Delegate를 사용하는 것은 나중에 보게 되는데요. 사전에 정의된 수많은 location event들에 대해 필요한 메소드들을 불러서 구체적인 부분을 코딩해 나가시면 됩니다.

이건 나중에 보구요. 우선 순서대로 다시 보자면


CLLocationManager() 를 초기화 시킵니다. 이 클래스는 Location 과 heading 관련된 이벤트들을 전달하는 것을 configuring 하는 핵심 포인트인데요. 이 클래스의 인스턴스를 만들어서 location과 heading 이벤트를 언데 전달되고 이 이벤트들을 전달하는 일을 시작하고 끝내는 등의 역할을 하게 됩니다. 


위의 소스코드에서는 locationManager라는 이름으로 이 클래스를 초기화 시켰습니다.


그 다음은 viewDidLoad() 라는 함수를 보시면 됩니다.

이 함수는 UIViewController에 이미 정의돼 있는 함수인데요. UIViewController를 상속했기 때문에 이 함수를 Override 해서 사용할 수 있습니다.

이 함수는 해당 화면이 뜬 이후에 실행이 되게 됩니다.

그러니까 화면이 뜬 후에 제일 먼저 일어나야 할 일들을 여기에더가 정의 해 두면 됩니다.



super.viewDidLoad()로 이미 정의된 기능을 다 실행하도록 한 후에 아래 4개의 라인을 실행합니다.


        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()


일단 CLLocationManager의 delegate를 self로 선언하고 다음에 desiredAccuracy는 Best 로 합니다.

이 외에 KCLLocationAccuracyNearestTenMeters, KCLLocationAccuracyHundredMeters, KCLLocationAccuracyKilometer, KCLLocationAccuraryThreeKilometer 등이 있습니다.

필요한 걸 골라서 쓰면 됩니다. Best 인 경우는 위치정보의 정확도가 가장 좋은 겁니다. 그러면 배터리 소모량이 많아 지겠죠.


그리고 requestWhenInUseAuthorization() 은 이 Location 정보를 이용하려고 할 때 사용자로부터 승인 여부를 묻는데 사용됩니다. 위치정보를 사용할 때 반드시 사용자의 허락을 받아야만 합니다. 이것 외에 requestAlwaysAuthorization() 도 있습니다. 첫번째 것은 앱이 foreground에서 실행 될 때에만 묻고 두번째 것은 forground이든 background 이던 다 물을 수 있습니다.




그 다음은 startUpdateingLocation()를 호출함으로서 Location Service를 사용할 수 있게 됩니다.


이제 locationManager는 사용자의 위치를 tracking 하고 그 값을 전달해 줄 수 있습니다.


didReceiveMemoryWarning()은 override 한 함수로 여기서 따로 살펴 보지는 않겠습니다.


그 다음에 나오는 함수가 바로 CLLocationManagerDelegate에 미리 정의 돼 있던 여러 메소드들을 사용하는 건데요.

첫번째로 didUpdateLocations를 가져왔습니다.

이 함수는 Location이 업데이트 됐을 때 실행되는 함수입니다.


그 안의 코딩을 보면 에러를 핸들링하고 에러가 없을 경우에는 위치 정보를 displayLocationInfo 함수에 전달해 주도록 하고 있습니다.


이 displayLocationInfo는 미리 정의돼 있던 함수가 아니라 개발자가 만든 함수입니다.


이 함수에는 전달받은 위치정보 중에서 locality (도시), postalCode(우편번호)administrativeArea(주) 그리고 country (나라) 정보를 콘솔에 print 하도록 했습니다.


그리고 마지막은 다시 CLLocationManager 의 Delegate에 미리 정의돼 있던 didFailWithError 메소드를 사용했습니다.

에러가 날 경우에는 에러 정보를 print 하도록 했습니다.


이렇게 해서 모든 소스코드를 분석해 봤습니다.



이 강좌에서는 위치 정보를 사용하기 위해서 info.plist에 NSLocationWhenInUseUsageDescription을 추가하라고 돼 있습니다.

그리고 제가 공부하던 다른 책에서는 NSLocationWhenInUsageDescription, NSLocationAlwaysUsageDescription 그리고 NSLocationUsageDescription을 추가하라고 돼 있구요.


그런데 저는 이 것들을 다 추가해도 앱이 제대로 실행이 안 되더라구요.

빌드는 제대로 되는데 저 위 그림에 있는 사용자에게 위치정보 사용 승인을 받는 alert 창이 안 뜨더라구요.


무슨 다른 세팅을 해야 되는지.... ? 잘 모르겠습니다.


일단 이 강좌에 있는 소스파일들을 다운 받아서 실행해서 테스트는 해 봤습니다.

다운 받은 소스의 info.plist에는 아무것도 추가가 안 돼 있던데...


왜 제가 만든 소스코드는 제대로 실행이 안되는지 모르겠네요.


이제 Current Location 정보를 받아서 사용하는 부분은 어느정도 알 것 같습니다.


반응형