SwiftUI

iOS Gps定位 background模式

我们在进行iOS App开发的时候,经常需要使用Gps地图定位。目前iOS定位功能主要用下面两个框架。

   CoreLocation:(着重功能实现)
         ①地理定位 
         ②运行速度取得 
         ③海拔高度取得 
         ④Gps信号强度取得

   MapKit:用于地图展示(着重界面展示)
         ①自定义大头针 
         ②地图画路线  
         ③userLocation等

有时我们需要在App进入到background后台后,仍然能够使用Gps来进行定位,这样我们就需要使用CoreLocation框架(MapKit在App进入到background后台后就会停止)那么如何在App进入到background后,使用CoreLocation来定位呢?只需要按照下面步骤配置就可以。


1. 在 Xcode --- Signing&Capabilities --- Background Modes 开启Location updates
选中Location updates,如果需要在后台播放声音,Audio也需要选中。

2. 在Xcode工程中info.plist中追加下面两个项目:
        Privacy - Location Always and When In Use Usage Description
        Privacy - Location When In Use Usage Description

3. 在SceneDelegate中可以通过CLLocationManager 启动Gps。
    ※非常重要,只有设定allowsBackgroundLocationUpdates 和 showsBackgroundLocationIndicator = true  
Gps才能后台运行。
                   
import UIKit
import SwiftUI
import CoreLocation

class SceneDelegate: UIResponder, UIWindowSceneDelegate, CLLocationManagerDelegate {

    var window: UIWindow?
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        Constants.locationManager.delegate = self
        Constants.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
        Constants.locationManager.distanceFilter = 1
        Constants.locationManager.requestAlwaysAuthorization()
        // ※非常重要,只有设定allowsBackgroundLocationUpdates,showsBackgroundLocationIndicator Gps才能后台运行。
        Constants.locationManager.allowsBackgroundLocationUpdates = true
        Constants.locationManager.showsBackgroundLocationIndicator = true
        setCurrentLocationFlag = true

        if (CLLocationManager.locationServicesEnabled()) {
            Constants.locationManager.startUpdatingLocation()
        }

        let contentView = ContentView()

        // Use a UIHostingController as window root view controller.
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }
    
    // 当Gps取得新Location时,会active locationManager这个方法
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        // 获取最新的坐标
        let currLocation: CLLocation = locations.last! 
    }

    // App从后台进入前台时,会调用这个方法
    func sceneWillEnterForeground(_ scene: UIScene) {
        print("sceneWillEnterForeground")
        // Called as the scene transitions from the background to the foreground.
        // Use this method to undo the changes made on entering the background.
    }
   
    // App进入后台时,会调用这个方法
    func sceneDidEnterBackground(_ scene: UIScene) {
        print("sceneDidEnterBackground" )
    }

4. 在设备中, App位置情报设定中。选择「使用中许可」 或者 「一直使用」。

5.  如果想使用AVAudioPlayer, 在background后台播放声音。需要注意 options: [.mixWithOthers] 和 setActive(true)
  try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: [.mixWithOthers])
                        
  try AVAudioSession.sharedInstance().setActive(true)