首页 > 解决方案 > 按下 UILabel 时分配变量值以打开 Apple 地图

问题描述

本质上,我正在解析 JSON 数据并将其分配给一个名为的变量addressPressNow,然后当用户点击 UILabel 时执行以下函数:

目标是打开 Apple Maps,前提是它包含的变量值。

因为我将地址分配给变量,所以它将包含空格,例如:3981 Test Drive Cupertino CA 95014

注意:变量的值被正确传递,因为当我这样做print(addressPressNow)时,func tapFunction它会正确打印。

@objc
func tapFunction(sender:UITapGestureRecognizer) {

    let targetURL = NSURL(string: "http://maps.apple.com/?q=" + addressPressNow)!


    UIApplication.shared.openURL(targetURL as URL)

}

问题是我无法将变量应用于字符串 URL,并出现以下错误:

线程 1:致命错误:在展开可选值时意外发现 nil

以下是我将值分配给变量的方式:

struct FacilityInfo: Decodable {
    let address: String

class infoViewController: UIViewController {

    var addressPressNow : String = ""

override func viewDidLoad() {
    super.viewDidLoad()



    let tap = UITapGestureRecognizer(target: self, action: #selector(infoViewController.tapFunction))
    addressInfo.isUserInteractionEnabled = true
    addressInfo.addGestureRecognizer(tap)


    let url = URL(string: "https://test/test/example”)!

    let task = URLSession.shared.dataTask(with: url) { data, response, error in

        // ensure there is no error for this HTTP response
        guard error == nil else {
            print ("error: \(error!)")
            return
        }

        // ensure there is data returned from this HTTP response
        guard let data = data else {
            print("No data")
            return
        }

        // Parse JSON into array of Car struct using JSONDecoder


        guard let cars = try? JSONDecoder().decode([FacilityInfo].self, from: data), let secondCar = cars.first
        else {
            print("Error: Couldn't decode data into cars array")
            return
        }
        DispatchQueue.main.async {
            self.addressPressNow = secondCar.facility_address
        }

    }

标签: iosswifturlapple-maps

解决方案


“我正在为一个包含空格的变量分配一个地址”

如果地址包含空格,则NSURL使用字符串创建将崩溃。您可以使用添加百分比编码来解决问题

if let encodedAddress = addressPressNow.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
    let targetURL = NSURL(string: "http://maps.apple.com/?q=" + encodedAddress)!
    UIApplication.shared.openURL(targetURL as URL)
}

并且不要使用NSURL和强制展开。像这样更新它

if let encodedAddress = addressPressNow.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
    let targetURL = URL(string: "http://maps.apple.com/?q=" + encodedAddress) {
        UIApplication.shared.openURL(targetURL)
}

正如马特建议的那样使用URLComponents

let addressPressNow = "3981 Test Drive Cupertino CA 95014"
var components = URLComponents(string: "http://maps.apple.com")
components?.queryItems = [URLQueryItem(name: "q", value: addressPressNow)]
print(components?.url)//http://maps.apple.com?q=3981%20Test%20Drive%20Cupertino%20CA%2095014
if let targetURL = components?.url {
    UIApplication.shared.open(targetURL, options: [:], completionHandler: nil)
}

推荐阅读