首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS 偵測用戶拒絕定位權限並導向不同畫面

     編輯:程式設計綜合問答

需求場景

App 需要根據用戶是否授權定位權限,決定顯示不同的視圖控制器(如:授權顯示地圖頁、拒絕顯示手動輸入頁)。

核心解決方案:實作 CLLocationManagerDelegate

import CoreLocation

class LocationPermissionHandler: NSObject, CLLocationManagerDelegate {
    private let locationManager = CLLocationManager()
    private var onPermissionResult: ((Bool) -> Void)?
    
    override init() {
        super.init()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
    }
    
    func requestPermission(completion: @escaping (Bool) -> Void) {
        onPermissionResult = completion
        
        let status = CLLocationManager.authorizationStatus()
        switch status {
        case .notDetermined:
            locationManager.requestWhenInUseAuthorization() // 或 requestAlwaysAuthorization()
        case .restricted, .denied:
            completion(false)
        case .authorizedWhenInUse, .authorizedAlways:
            completion(true)
        @unknown default:
            completion(false)
        }
    }
    
    // MARK: - CLLocationManagerDelegate
    
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        switch status {
        case .authorizedWhenInUse, .authorizedAlways:
            onPermissionResult?(true)
        case .denied, .restricted:
            onPermissionResult?(false)
        default:
            break
        }
        onPermissionResult = nil // 防止重複回調
    }
    
    // 兼容舊版 iOS:didFailWithError 也會在拒絕時觸發
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        if let clError = error as? CLError, clError.code == .denied {
            onPermissionResult?(false)
            onPermissionResult = nil
        }
    }
}

CLError 代碼對照表(舊版參考)

錯誤代碼常數名稱含義
0kCLErrorLocationUnknown位置暫時未知,繼續嘗試
1kCLErrorDenied用戶拒絕定位權限
2kCLErrorNetwork網路相關錯誤
3kCLErrorHeadingFailure無法取得方向
4kCLErrorRegionMonitoringDenied區域監測被拒絕
.........

在 ViewController 中使用

class MainViewController: UIViewController {
    private let permissionHandler = LocationPermissionHandler()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        checkLocationPermission()
    }
    
    private func checkLocationPermission() {
        permissionHandler.requestPermission { [weak self] granted in
            DispatchQueue.main.async {
                if granted {
                    self?.showMapViewController()
                } else {
                    self?.showManualInputViewController()
                }
            }
        }
    }
    
    private func showMapViewController() {
        let mapVC = MapViewController()
        navigationController?.pushViewController(mapVC, animated: true)
    }
    
    private func showManualInputViewController() {
        let manualVC = ManualLocationInputViewController()
        navigationController?.pushViewController(manualVC, animated: true)
    }
}

Info.plist 必備權限說明

<key>NSLocationWhenInUseUsageDescription</key>
<string>我們需要您的位置來顯示附近的店家資訊</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>我們需要您的位置來提供背景導航功能</string>

進階:引導用戶前往設定頁開啟權限

func openAppSettings() {
    guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return }
    if UIApplication.shared.canOpenURL(settingsUrl) {
        UIApplication.shared.open(settingsUrl, options: [:], completionHandler: nil)
    }
}

// 在拒絕處理中呼叫
let alert = UIAlertController(
    title: "需要定位權限",
    message: "請在設定中開啟定位權限以使用完整功能",
    preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "去設定", style: .default) { _ in
    self.openAppSettings()
})
alert.addAction(UIAlertAction(title: "取消", style: .cancel))
present(alert, animated: true)

總結

使用 CLLocationManagerDelegate 的 didChangeAuthorization 方法可即時偵測授權狀態變化。iOS 14+ 新增 authorizedWhenInUse 與 authorizedAlways 細分,建議優先請求 WhenInUse 權限。拒絕時應友善引導用戶至設定頁,而非單純阻擋功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved