我有一个iOS应用,该应用需要跟踪研究项目的用户地理位置。但是,该应用会在几个小时后被iOS自动挂起,并且地理位置跟踪会停止工作。
针对我的情况,地理围栏不够,因为不够准确。
有什么方法可以防止应用程序暂停(除非用户手动终止它)?
我想到的一种方法是无限期播放无声音乐,并通过MPRemoteCommandCenter在锁屏上显示音乐控件,就像Spotify的工作方式一样。
是否可以使该应用程序继续运行? (因为我认为Spotify除非用户手动将其终止,否则不会被杀死?)
答案 0 :(得分: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>
答案 1 :(得分: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)
}
}