【问题标题】:iOS Get user location in Notification Service ExtensioniOS 在通知服务扩展中获取用户位置
【发布时间】:2020-08-30 21:51:28
【问题描述】:

是否可以在UNNotificationServiceExtension 中使用CoreLocation 框架? 我试过的:

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?
    private let locationManager = CLLocationManager()

    override func didReceive(_ request: UNNotificationRequest,
                             withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        os_log("%{public}@",
        log: OSLog(subsystem: "bundleIdentifier", category: "WakeUpExtension"),
        type: OSLogType.debug,
        "Push received")
        locationManager.delegate = self
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()

        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
    }

    override func serviceExtensionTimeWillExpire() {
        os_log("%{public}@",
        log: OSLog(subsystem: "bundleIdentifier", category: "WakeUpExtension"),
        type: OSLogType.debug,
        "Task expired")
        locationManager.stopUpdatingLocation()
        locationManager.delegate = nil

        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }

}
extension NotificationService: CLLocationManagerDelegate {

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        locations.forEach {
            os_log("%{public}@",
            log: OSLog(subsystem: "bundleIdentifier", category: "WakeUpExtension"),
            type: OSLogType.debug,
            $0.horizontalAccuracy)
        }

        for location in locations {
            let locationAge = -location.timestamp.timeIntervalSinceNow
            if locationAge < 5 {
                os_log("%{public}@",
                log: OSLog(subsystem: "bundleIdentifier", category: "WakeUpExtension"),
                type: OSLogType.debug,
                "Send")
                locationManager.stopUpdatingLocation()
                locationManager.delegate = nil
                contentHandler?(UNNotificationContent())
            }
        }
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        os_log("%{public}@",
        log: OSLog(subsystem: "bundleIdentifier", category: "WakeUpExtension"),
        type: OSLogType.debug,
        error.localizedDescription)
    }
}

我在控制台中得到的只是:

【问题讨论】:

  • 我认为您无法在扩展上下文中访问用户的位置。但是,您可以将requestLocation 用于一次性位置,而不是尝试开始和停止位置更新。
  • @Paulw11 你的意思是在主应用程序中使用requestLocation 还是推送扩展程序?我尝试在扩展中使用此方法,结果相同
  • 是的,我怀疑您不能在扩展程序中使用位置信息

标签: ios swift core-location unnotificationserviceextension


【解决方案1】:

看起来CLLocationManagerDelegate 方法永远不会在UNNotificationServiceExtension 中被调用。但是可以从CLLocationManager location 属性中获取上次接收到的位置:

 let locationManager = CLLocationManager()
 let lastLocation = locationManager.location

【讨论】:

    【解决方案2】:

    您需要实现一个后台 url 会话。它有助于延迟延期到期,在这种情况下,直到提供位置更新(以及编写的任何其他后期处理)。

    private lazy var urlSession: URLSession = {
        let config = URLSessionConfiguration.background(withIdentifier: "MySession")
        config.sessionSendsLaunchEvents = true
        return URLSession(configuration: config, delegate: self, delegateQueue: nil)
    }()
    

    参考: https://developer.apple.com/documentation/foundation/url_loading_system/downloading_files_in_the_background

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-01
      • 2022-08-03
      • 2020-02-20
      • 1970-01-01
      • 2017-02-23
      相关资源
      最近更新 更多