我正在开发本机Webbrowser,以使Web应用程序与Swift中的核心功能(蓝牙,位置,微型..)交互。本机应用程序托管一个WKWebview来显示Web应用程序的内容,JS通过window.webkit.messageHandlers与WKWebview进行通信。
有一个功能,当位置发生变化时,即使在后台,Web应用程序也会要求本机应用程序检索用户位置。为简单起见,我使用CoreLocation获取位置并将位置发送回WKWebview。 Web应用程序通过窗口侦听器侦听这些事件,然后调用服务器以保存位置。
这在模拟器中运行良好,但是由于某些我不知道的原因,这在真实的iPhone上不起作用。
问题:
任何建议都赞赏
网络应用服务:
this.eventManager.addEventListener(window, 'sendLocalisation', (params : CustomEvent) => {
let data = params.detail.data;
let datas = { 'annotations' : data }
this.sendLocalisation(datas).subscribe( (ans : any ) => {
...
});
window.webkit.messageHandlers.JSLocalisation.postMessage("start");
本地快速代码:
// Variables
private var localisationManager : LocalisationManager!
extension JSEventManager : WKScriptMessageHandler {
open func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "JSLocalisation" {
self.handleLocalisationEvents(message: message.body as! String)
}
}
func handleLocalisationEvents(message : String) {
if message == "start" {
localisationManager.startLocalisation()
}
}
class LocalisationManager : NSObject {
// Delegation
weak var delegate : LocalisationManagerDelegate?
// Variables
private var locationManager : CLLocationManager!
private var positions : [[String: Any]] = []
override init() {
super.init()
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.activityType = .other
locationManager.pausesLocationUpdatesAutomatically = false
}
func startLocalisation() {
delegate?.didStartLocalisation()
locationManager.requestAlwaysAuthorization()
}
}
extension LocalisationManager : CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if CLLocationManager.authorizationStatus() == .authorizedAlways {
startReceivingLocationChanges()
}
}
func startReceivingLocationChanges() {
let authorizationStatus = CLLocationManager.authorizationStatus()
if authorizationStatus != .authorizedWhenInUse && authorizationStatus != .authorizedAlways {
// User has not authorized access to location information.
return
}
// Do not start services that aren't available.
if !CLLocationManager.locationServicesEnabled() {
// Location services is not available.
return
}
// If the user confirms always authorization
if authorizationStatus == .authorizedAlways {
locationManager.allowsBackgroundLocationUpdates = true
}
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.distanceFilter = 40.0 // In meters.
locationManager.delegate = self
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[0]
let timestamp = String(format:"%f", location.timestamp.timeIntervalSince1970*1000)
let longitude = "\(location.coordinate.longitude)"
let latitude = "\(location.coordinate.latitude)"
let position : [String: Any] = ["timestamp" : timestamp, "lon" : longitude, "lat" : latitude, "timezone" : 0 ]
self.positions.append(position)
if self.positions.count == 3 {
sendCoordinates()
}
}
func sendCoordinates(){
let locationsToSend = self.positions
self.positions = []
if let stringToSend = json(from:locationsToSend as Any) {
self.delegate?.shouldSendCoordinates(coordinates: stringToSend)
}
}
func json(from object:Any) -> String? {
guard let data = try? JSONSerialization.data(withJSONObject: object, options: []) else {
return nil
}
return String(data: data, encoding: String.Encoding.utf8)
}
}
// shouldSendCoordinates call this function, shortcut not to display all the delegates trough the app
func sendLocalisation(localisation: String) {
let str = "window.iOSLocalisationAPI.sendPositions('\(localisation)')"
self.evaluateJavaScript(str) { (result, error) in
guard error == nil else {
print(error)
return
}
}
}
在webwiew中注入了脚本:
(function () {
"use strict";
let geonative = {
sendPositions : function(positions) {
var evt = new CustomEvent('sendLocalisation', { detail: { data : positions } });
window.dispatchEvent(evt);
}
}
window.iOSLocalisationAPI = geonative;
}());