参数类型 'CLLocationDegrees?'(也称为"可选<Double>")不符合预期的类型 'CVarArg'



我正在创建一个web应用程序。该应用程序是一种地图,因此我需要检索用户的位置。原则上这是可行的,但经度和纬度必须发送到服务器。我使用函数updateLocation来完成此操作。在最底层,它出了问题。功能locationManager会跟踪位置是否已更改。然后应该将新的lon和lat发送到服务器。基本上,我想通过在locationManager函数中调用updateLocation函数来实现这一点。只是这样不行。我从Xcode收到以下错误消息:

参数类型"CLLocationDegrees?"(又名"可选")不符合预期类型"CVarArg">

有人知道我该怎么解决这个问题吗。附言:我知道有些代码可能很麻烦。我对SwiftUI不是很熟悉。

Webview

//
//  WebView.swift
//  ferocity
//
//  Created by Jens Buwalda on 2022-06-17.
//
import Foundation
import SwiftUI
import WebKit
import CoreLocation
struct WebView : UIViewRepresentable {
let url: URL
var webView = WKWebView()
var manager = LocationManagerService()

func makeUIView(context: Context) -> WKWebView  {
let request = URLRequest(url: url)
webView.load(request)
return webView
}

// AND IT HAS TO CALL THIS (OR UPDATE THE WEBVIEW)
func updateLocation(lat:String, lon:String){
webView.evaluateJavaScript("deviceLocation(" + lat + ", " + lon + ");")
}

func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.navigationDelegate = context.coordinator
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
//Conform to WKNavigationDelegate protocol here and declare its delegate
class Coordinator: NSObject, WKNavigationDelegate {
var parent: WebView
init(_ parent: WebView) {
self.parent = parent
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
// Check if there is a token in the url
let token = getQueryStringParameter(url: navigationAction.request.url!.absoluteString, param: "token")
// Save token if available
let defaults = UserDefaults.standard
if token != nil{
defaults.set(token, forKey: "token")
}

// Check if a token is present in storage
if let memoryToken = defaults.string(forKey: "token") {
print("Memory token: " + memoryToken)
// Add token to new url
let reloadUrl = insertQueryItems(url: navigationAction.request.url!.absoluteString, key: "token", value: memoryToken)!
print("Reload url: " + reloadUrl.absoluteString)
// Check if the url id different from the current url
if navigationAction.request.url?.absoluteString != reloadUrl.absoluteString{
print("Reload")
webView.load(URLRequest(url: reloadUrl))
}
} else {
print("No token in memory")
}

//Change padding on login page
if ((navigationAction.request.url?.absoluteString.contains("sso")) != false){
// TODO: add padding to top
// self.parent.padding(      )
} else {
// Remove the padding
}
decisionHandler(.allow)
}

func getQueryStringParameter(url: String, param: String) -> String? {
guard let url = URLComponents(string: url) else { return nil }
return url.queryItems?.first(where: { $0.name == param })?.value
}

func insertQueryItems(url: String, key: String, value: String) -> URL?{
var urlObject = URLComponents(string: url)
var urlComponents = urlObject?.queryItems
if(urlComponents == nil){
urlComponents = []
}
urlComponents?.removeAll(where: { $0.name == key })
urlComponents?.append(URLQueryItem(name: key, value: value))
urlObject?.queryItems = urlComponents
return urlObject?.url

}
}
}
class LocationManagerService: NSObject, ObservableObject, CLLocationManagerDelegate {
var manager: CLLocationManager = CLLocationManager()
@Published var location: CLLocation?
@Published var enabled: Bool = false

override init() {
super.init()
manager.delegate = self

if CLLocationManager.locationServicesEnabled() {
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
}
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("location changed")
location = locations.first
let user_lat = String(format: "%f", location?.coordinate.latitude!)
let user_long = String(format: "%f", location?.coordinate.longitude)
//THIS FUNCTION UPDATES
}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
}

func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
enabled = CLLocationManager.locationServicesEnabled()
}
}

location?.coordinate.latitude!错误。你的位置是Optional<CLLocation>,你需要打开它,首先确保不是零guard let location = locations.last else { return },以获得一个诚实的、非可选的位置(最近交付给你的代表的位置)。locations.first返回一个可选的,因为位置数组中可能有0个位置,即可能没有第一个位置。

你不能强行打开纬度,因为纬度是CLLocationDegrees,也就是Double,如果你有一个位置,那么它的坐标将有一个诚实的、非可选的纬度。

guard let coordinate = locations.last?.coordinate else { return }
let user_lat = String(format: "%f", coordinate.latitude)
let user_long = String(format: "%f", coordinate.longitude)

location?.coordinate.latitude这样的表达式是Optional<CLLocationDegrees>,但不能用!最后,因为位置是可选的,而不是纬度,您可以选择将其与?这留下了Optional<CLLocationDegrees>类型的整个表达式。

最新更新