Hướng dẫn lấy user's location
Bài đăng này đã không được cập nhật trong 3 năm
Permissions
Apple cho phép developers có thể lấy được user’s location bằng cách sử dụng CoreLocation Framework. Tuy nhiên, app phải được user cho phép sử dụng location services bằng cách đồng ý request user’s permission khi mở lên. Có 2 loại authorization:
- When In Use chỉ cho phép app lấy location khi đang mở lên
- Always có thể lấy được location khi app đang ở backgroud Trong các versions trước, request permission để dùng location service không rõ ràng. Ta chỉ cần tạo 1 instance CLLocationManager và sử dụng đoạn code sau là có thể trigger hệ thống để nhắc user xác thực location service nếu user chưa approve hoặc deny trước đó.
import CoreLocation
let manager = CLLocationManager()
if CLLocationManager.locationServicesEnabled() {
manager.startUpdatingLocation()
}
Hiện tại, request permission và bắt đầu dùng location service là hành động riêng biệt. Cụ thể, có 2 hàm khác nhau khi request permissions requestWhenInUseAuthorization và requestAlwaysAuthorization.
if CLLocationManager.authorizationStatus() == .notDetermined {
manager.requestAlwaysAuthorization()
}
if CLLocationManager.authorizationStatus() == .notDetermined {
manager.requestWhenInUseAuthorization()
}
Nếu user đồng ý cho app sử dụng location service sẽ có 1 delegate xác định trạng thái authorization
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedAlways || status == .authorizedWhenInUse {
manager.startUpdatingLocation()
// ...
}
}
Ngoài ra, ta cần đăng ký request location trong Info.plist. Có 2 key là NSLocationWhenInUseUsageDescription và NSLocationAlwaysUsageDescription. Nếu ta gọi requestWhenInUseAuthorization hay requestAlwaysAuthorization mà không chỉ định trong plist sẽ không có thông báo show ra cho user. . Enable background mode cho location trong tab Capabilities.
Xử lý Location Service
Tiếp theo, ta khởi tạo CLLocationManager - 1 object chịu trách nhiệm về location data
import CoreLocation
fileprivate lazy var locationManager: CLLocationManager = {
let manager = CLLocationManager()
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.allowsBackgroundLocationUpdates = true
manager.pausesLocationUpdatesAutomatically = false
manager.delegate = self
manager.requestAlwaysAuthorization()
return manager
}()
Có nhiều cách tùy chỉnh để lấy location và sẽ ảnh hưởng đến lượng pin tiêu thụ:
- distanceFilter: lấy location theo khoảng cách là meter.
- desiredAccuracy: lấy theo độ chính xác của location (kCLLocationAccuracyBestForNavigation, kCLLocationAccuracyBest, kCLLocationAccuracyNearestTenMeters, kCLLocationAccuracyHundredMeters, kCLLocationAccuracyKilometer, kCLLocationAccuracyThreeKilometers).
- activityType: chỉ định type của user activity (other, automotiveNavigation, fitness, otherNavigation) Để lấy thông tin location ta cần implement delegate sau:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.max(by: { (location1, location2) -> Bool in
return location1.timestamp.timeIntervalSince1970 < location2.timestamp.timeIntervalSince1970}) else { return }
}
Sau khi có location, ta thực hiện hiển thị lên bản đồ
func didUpdateTrackingLocation(_ location: CLLocation) {
locations.append(location)
if let polyline = currentPolyline {
mapView.remove(polyline)
}
currentPolyline = self.polyline(locations: locations, title: "location")
mapView.add(currentPolyline!)
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.blue.withAlphaComponent(0.8)
renderer.lineWidth = 2.0
return renderer
}
}
Kết quả:
All rights reserved