1

我有一个 iOS 应用程序需要跟踪用户的地理位置以进行研究项目。但是,该应用程序会在几个小时后被 iOS 自动暂停,并且地理位置跟踪停止工作。

地理围栏对我的情况来说是不够的,因为它不够准确。

有什么方法可以防止应用程序被暂停(除非用户手动终止它)?

我想到的一种方法是无限期地播放无声音乐,并通过MPRemoteCommandCenter在锁屏上显示音乐控件,就像 Spotify 的工作方式一样。

这会让应用程序保持活力吗?(因为我相信 Spotify 永远不会被杀死,除非用户手动终止它?)

4

2 回答 2

0

这是我的代码的一部分。我已删除不需要的部分,因此您可能需要在使用时进行编辑。

import GooglePlaces
import GoogleMaps



class StartRideViewController: UIViewController, CLLocationManagerDelegate, GMSMapViewDelegate{

var mapView: GMSMapView!
var locationManager = CLLocationManager()

override func viewDidLoad() {
    super.viewDidLoad()

let notificationCenter = NotificationCenter.default
    notificationCenter.addObserver(self, selector: #selector(appMovedToBackground), name: Notification.Name.UIApplicationWillResignActive, object: nil)
    notificationCenter.addObserver(self, selector: #selector(appMovedToForeGround), name: Notification.Name.UIApplicationDidBecomeActive, object: nil)

}


@objc func appMovedToBackground() {
    print("App moved to background!")
    print(isStartRide)
    if isStartRide == false{
        btn_Share.isHidden = true
        locationManager.allowsBackgroundLocationUpdates = false
        locationManager.stopUpdatingLocation()
    }
}

@objc func appMovedToForeGround() {
    //getMeRidersData()
}

func initiateLocation(){
locationManager.delegate = self
        locationManager.requestWhenInUseAuthorization()
        locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
        locationManager.distanceFilter = 1
        locationManager.startUpdatingLocation()
        //locationManager.startUpdatingHeading()
        locationManager.allowsBackgroundLocationUpdates = true

        //checkForLocationServices()
        checkLocationAuthorizationStatus()

guard let myLatitude = locationManager.location?.coordinate.latitude else{
        return
    }
    guard let myLongitude = locationManager.location?.coordinate.longitude 
else{
        return
    }


    showMap(myLatitude:myLatitude, myLongitude:myLongitude)

}
func showMap(myLatitude:Double, myLongitude:Double){
    let camera = GMSCameraPosition.camera(withLatitude: myLatitude, 
longitude: myLongitude, zoom: 17)
    mapView = GMSMapView.map(withFrame: view.bounds, camera: camera)
    //mapView = GMSMapView.map(withFrame: CGRect(x: 0, y: 0, width: 
self.view.frame.width, height: self.view.frame.height - 250), camera: camera)

    mapView?.center = self.view.center
    self.view.addSubview(mapView!)

    mapView.padding = UIEdgeInsetsMake(150, 0, 80, 0)
    mapView.settings.myLocationButton = true
    mapView.delegate = self
    //mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    mapView.isMyLocationEnabled = true
    frameForMapView.addSubview(mapView)

}

func checkLocationAuthorizationStatus() {
    let status = CLLocationManager.authorizationStatus()
    if status == CLAuthorizationStatus.notDetermined{
        print("NotDetermined")
        locationManager.requestWhenInUseAuthorization()
        CLLocationManager.locationServicesEnabled()
        locationManager.requestLocation()
    }else {
        print("Problem with authorization")
    }
}


// Handle incoming location events.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let location: CLLocation = locations.last!
    print("Location: \(location)")
    moveMyImageOnMap()
    print(isStartRide, gotCounterFromLastRide , counter)
    if isStartRide && gotCounterFromLastRide{
        updateMyLocationToDataBase()
    }
}

//    func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
//        print(newHeading)
//    }

// Handle authorization for the location manager.
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
    switch status {
    case .restricted:
        print("Location access was restricted.")
    case .denied:
        print("User denied access to location.")
        // Display the map using the default location.
    case .notDetermined:
        print("Location status not determined.")
    case .authorizedAlways: fallthrough
    case .authorizedWhenInUse:
        print("Location status is OK.")
        if mapView != nil {
            mapView.isMyLocationEnabled = true
        }

    }
}

// Handle location manager errors.
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    locationManager.stopUpdatingLocation()
    print("Error: \(error)")

    let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as! String

    let msg :String = "You have denied the app to access your location. Please enable the location services in your settings for the app to get the location";
    let alertController = UIAlertController(title: "Allow \(appName) to access your location while you are using the app?", message: msg, preferredStyle: .alert)
    let cancelAction = UIAlertAction(title: "CANCEL", style: UIAlertActionStyle.default, handler: nil)

    let settingsAction = UIAlertAction(title: "SETTINGS", style: .default) { (_) -> Void in
        guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
            return
        }

        if UIApplication.shared.canOpenURL(settingsUrl) {
            UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                print("Settings opened: \(success)") // Prints true
            })
        }
    }


    alertController.addAction(cancelAction)
    alertController.addAction(settingsAction)

    self.present(alertController, animated: true, completion: nil)
}


}
于 2018-12-29T04:32:08.133 回答
0

我有类似的应用程序,它使用用户位置进行跟踪。检查您是否在 info.plist 中拥有所有这些权限。并具体告诉用户您为什么使用位置权限

<key>NSLocationAlwaysUsageDescription</key>
<string>Application needs permission to access your current location. 
</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Application needs permission to access your current location. 
</string>
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
于 2018-12-28T12:12:37.947 回答