Hướng dẫn lấy user''s location
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 ...
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.
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ả: