IOS Location Tracking
Các ứng dụng sử dụng dữ liệu vị trí với nhiều mục đích khác nhau. Các app này sử dụng dữ liệu vị trí thông qua Core Location framework. Framework này cung cấp một số dịch vụ mà bạn có thể sử dụng để có get và theo dõi vị trí hiện tại của thiết bị. Standard location service cung cấp một cách cấu ...
Các ứng dụng sử dụng dữ liệu vị trí với nhiều mục đích khác nhau. Các app này sử dụng dữ liệu vị trí thông qua Core Location framework. Framework này cung cấp một số dịch vụ mà bạn có thể sử dụng để có get và theo dõi vị trí hiện tại của thiết bị. Standard location service cung cấp một cách cấu hình cao để có được vị trí hiện tại và theo dõi những thay đổi. Region monitoring cho phép bạn giám sát trong một khu vực với đường kính xác định Significant-change location service cung cấp một cách để có được vị trí hiện tại và được thông báo khi có thay đổi đáng kể xảy ra, quan trọng là làm sao sử dụng nó một cách chính xác để tránh sử dụng quá nhiều năng lượng. Nếu bạn đang xây dựng một ứng dụng sử dụng location tracking, bản tóm tắt ngắn này trình bày một vài điều cần lưu ý cho Location Tracking trong iOS mà có thể giúp bạn tiết kiệm thời gian Goal Report vị trí của user sau mỗi x phút. Nhiều yêu cầu khác tuỳ theo đặc điểm dự án. Problem Ứng dụng IOS không thể được đánh thức bởi timer (bộ đếm thời gian). Thực tế này là khó hiểu đối với các nhà quản lý sản phẩm và người mới vào môi trường iOS. Tôi tin rằng Apple đã làm điều này để giới hạn task trong nền để giảm thiểu sự tiêu hao pin. Phương án hiện tại là thực hiện task khi có sự thay đổi vị trí. Không sử dụng GPS ở background, nhưng nó không đủ để giải quyết vấn đề. Solution Sử dụng GPS để xác định một vị trí chính xác. Fallback cho các trường hợp không chính xác để tiết kiệm pin Gửi silent push notifications nếu người dùng không di chuyển. Tuỳ chỉnh Location Tracking and Sending settings. Giải pháp là sự kết hợp các phương pháp nêu trên. Đây là cách đơn giản nhất để hoàn thành mục tiêu. GPS usage Chúng tôi giả định GPS được sử dụng khi chúng ta gọi là 'startUpdatingLocation' với 'desiredAccuracy' phù hợp GPS được sử dụng trong thời gian quy định trong GPSTracking Settings. Sau khi GPS được tắt, location được gửi đến máy chủ và the Imprecise Tracking được bật. Imprecise location services Có 3 API để theo dõi vị trí sử dụng pin hiệu quả: Significant location changes— các vị trí nằm trong khoảng mỗi 500 mét (thường lên đến 1 km) Region monitoring —Theo dõi vị trí trong vùng hình tròn có bán kính 100m hoặc hơn. Visit events — giám sát vị trí dựa trên địa điểm như là nhà, văn phòng, .... Cách chính xác nhất trong số các cách ở trên là Region monitoring: Khi GPS được tắt, tôi thiết lập một khu vực 100m xung quanh vị trí cuối cùng nhận được. Khi người dùng ra khỏi khu vực này thì ta có thể đánh thức app, lúc này GPS sẽ được bật lại nếu cần. Ngược lại thì một khu vực mới được thiết lập. Silent push notifications Nếu người dùng đi đến một nơi và ngồi tại đó mà không thay đổi vị trí, chúng ta sẽ gửi 1 silent push notification giống như một push notification bình thường. Thông báo đó sẽ đánh thức ứng dụng và cung cấp cho nó 1 thời gian để khởi động GPS-tracking/location sending. Location Tracking and Sending settings Chúng ta nên thiết lập cấu hình cho từng đối tượng riêng biệt hơn là dùng chung 1 cấu hình cho tất cả. Có 2 cấu hình: một là cho foreground và hai là cho background. Bước tiếp theo là ta sẽ gửi những cấu hình này từ server. The implementation of the solution Chúng ta sẽ kết thúc với LocationUpdateService, là một tập hợp của nhiều service nhỏ, một trong đó là LocationTracker. LocationUpdateService: ** LocationTracker** ** LocationStorage** ** LocationSender** LocationTracker là đại diện cho 'CLLocationManager'. Tracker được bắt đầu với LocationTrackingSettings Thay vì tìm hiểu sâu vào chi tiết thực hiện tôi muốn chỉ ra những lưu ý khi làm việc với 'CLLocationManager'. Cảnh báo khi dùng GPS trong background Một ứng dụng trong đó có điều khoản thích hợp (để sử dụng location service trong background) được đánh thức bất cứ khi nào có sự kiện liên quan đến location xảy ra. Vấn đề là, nếu bạn bắt đầu quá trình bất đồng bộ như gửi các location đến server thì ứng dụng có khả năng xảy ra tình trạng suspended vì mất 1 khoảng thời gian để xử lý response. Nói cách khác, các ứng dụng gần như bị treo ngay lập tức sau hàm callback. Chúng ta phải ngừng sử dụng "UIBackgroundTask" khi ứng dụng đang thực hiện các task khác, và ngừng "UIBackgroundTask" ngay khi nó finish. Điều quan trọng là hãy nhớ rằng thời gian nhất định cho bất kỳ background task chỉ giới hạn trong 3 phút, và bạn phải sử dụng xử lý một cách hợp lý. Significant location changes được gọi như hàm delegate callback của locations từ GPS Trong... didUpdateLocations callback thì không có cách nào để phân biệt được sự thay đổi vị trí từ GPS hay là từ Significant location change. Để giải quyết vấn đề này, chúng ta lọc vị trí thay đổi do significant location change.
func locationSignificantlyChanged(_ location: CLLocation) -> Bool { guard let filteringSettings = self.settings.locationsFiltering, let lastTrackedLocation = self.lastTrackedLocation else { self.lastTrackedLocation = location return true } ... if timeChangedSignificantly || accuracyImprovedSignificantly || distanceChangedDramatically || (distanceChangedSignificantly && !accuracyDecreased) { self.lastTrackedLocation = location return true } return false }
Start significant location changes có thể chỉ trả về vị trí của vài giờ trước đó. Vì thực tế này, chúng ta sẽ sử dụng một instance cho 'CLLocationManager' và 1 instance khác cho imprecise tracking.
public func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { guard manager == self.locationManager || self.state == .impreciseTracking else { return } if self.state == .impreciseTracking { self.updateTracking() } let filteredLocations = locations.filter (self.locationSignificantlyChanged) guard filteredLocations.count > 0 else { return } self.delegate?.locationTracker(self, didUpdateLocations: filteredLocations) }
Region-related events được cung cấp bởi tất cả các instance của ‘CLLocationManager’ Nếu bạn sử dụng nhiều instance cho 'CLLocationManager' và một delegate cho tất cả thì bạn phải đảm bảo xử lý callback một cách hợp lý
public func locationManager(manager: CLLocationManager, didExitRegion region: CLRegion) { guard manager == self.impreciseLocationManager else { return } self.updateTracking() self.delegate?.locationTracker(self, didExitRegion: region) }