浏览代码

Merge pull request #1176 from deltachat/location_updates_and_permissions

improve location permission handling
cyBerta 4 年之前
父节点
当前提交
82b5fc4d5e

+ 0 - 1
deltachat-ios/Chat/ChatViewController.swift

@@ -1100,7 +1100,6 @@ class ChatViewController: UITableViewController {
         guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
             return
         }
-        self.dcContext.sendLocationsToChat(chatId: self.chatId, seconds: seconds)
         appDelegate.locationManager.shareLocation(chatId: self.chatId, duration: seconds)
     }
 

+ 7 - 1
deltachat-ios/Controller/SettingsController.swift

@@ -396,6 +396,7 @@ internal final class SettingsViewController: UITableViewController, ProgressAler
         let title = locationStreaming ?
             "Disable on-demand location streaming" : String.localized("pref_on_demand_location_streaming")
         alert.addAction(UIAlertAction(title: title, style: .default, handler: { [weak self] _ in
+            guard let self = self else { return }
             UserDefaults.standard.set(!locationStreaming, forKey: "location_streaming")
             if !locationStreaming {
                 let alert = UIAlertController(title: "Thanks for trying out the experimental feature 🧪 \"Location streaming\"",
@@ -403,7 +404,12 @@ internal final class SettingsViewController: UITableViewController, ProgressAler
                                                 + "If you want to quit the experimental feature, you can disable it at \"Settings / Advanced\".",
                                               preferredStyle: .alert)
                 alert.addAction(UIAlertAction(title: String.localized("ok"), style: .default, handler: nil))
-                self?.navigationController?.present(alert, animated: true, completion: nil)
+                self.navigationController?.present(alert, animated: true, completion: nil)
+            } else if (self.dcContext.isSendingLocationsToChat(chatId: 0)) {
+                guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
+                    return
+                }
+                appDelegate.locationManager.disableLocationStreamingInAllChats()
             }
         }))
 

+ 38 - 7
deltachat-ios/Helper/LocationManager.swift

@@ -7,6 +7,8 @@ class LocationManager: NSObject, CLLocationManagerDelegate {
     let locationManager: CLLocationManager
     let dcContext: DcContext
     var lastLocation: CLLocation?
+    var chatIdLocationRequest: Int?
+    var durationLocationRequest: Int?
 
     init(context: DcContext) {
         dcContext = context
@@ -22,10 +24,28 @@ class LocationManager: NSObject, CLLocationManagerDelegate {
     }
 
     func shareLocation(chatId: Int, duration: Int) {
-        dcContext.sendLocationsToChat(chatId: chatId, seconds: duration)
         if duration > 0 {
-            locationManager.requestAlwaysAuthorization()
+            var authStatus: CLAuthorizationStatus
+            if #available(iOS 14.0, *) {
+                authStatus = locationManager.authorizationStatus
+            } else {
+                authStatus = CLLocationManager.authorizationStatus()
+            }
+            switch authStatus {
+            case .notDetermined:
+                // keep chatId and duration for user's authorization decision
+                chatIdLocationRequest = chatId
+                durationLocationRequest = duration
+                locationManager.requestAlwaysAuthorization()
+            case .authorizedAlways, .authorizedWhenInUse:
+                dcContext.sendLocationsToChat(chatId: chatId, seconds: duration)
+                locationManager.startUpdatingLocation()
+            default:
+                // TODO: show an alert to inform the user why nothing works :)
+                logger.info("Location permission was rejected.")
+            }
         } else {
+            dcContext.sendLocationsToChat(chatId: chatId, seconds: duration)
             if !dcContext.isSendingLocationsToChat(chatId: 0) {
                 locationManager.stopUpdatingLocation()
             }
@@ -68,14 +88,25 @@ class LocationManager: NSObject, CLLocationManagerDelegate {
         switch status {
         case .denied, .restricted:
             disableLocationStreamingInAllChats()
-        case .authorizedWhenInUse:
-            logger.warning("Location streaming will only work as long as the app is in foreground.")
-            locationManager.startUpdatingLocation()
-        case .authorizedAlways:
-            locationManager.startUpdatingLocation()
+        case .authorizedWhenInUse, .authorizedAlways:
+            if let chatId = chatIdLocationRequest,
+               let duration = durationLocationRequest {
+                dcContext.sendLocationsToChat(chatId: chatId, seconds: duration)
+            }
+            if dcContext.isSendingLocationsToChat(chatId: 0) {
+                locationManager.startUpdatingLocation()
+            }
+        case .notDetermined:
+            // we cannot request again for authorization, because
+            // that would create an infinite loop, let's just disable location streaming instead
+            if dcContext.isSendingLocationsToChat(chatId: 0) {
+                disableLocationStreamingInAllChats()
+            }
         default:
             break
         }
+        chatIdLocationRequest = nil
+        durationLocationRequest = nil
     }
 
     func disableLocationStreamingInAllChats() {