ios - 按下 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
}
}
解决方案
“我正在为一个包含空格的变量分配一个地址”
如果地址包含空格,则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)
}
推荐阅读
- java - 使用 cucumber、java 和页面对象的自动化
- spring - 重用 main 中的 application.properties 进行测试?
- python - 如何从每列中选择最常见的常见值
- postgresql - PostgreSQL——将“公历”日期转换为“波斯”日期??-- 在波斯历中显示日期时间戳
- javascript - 在JavaScript / node js中调用for循环内的异步函数
- python - Python Twitter API 从推文中提取多张图片
- python - 如何为给定场景绘制条形图?
- python - 我如何从 DM 频道中的 ctx.author 获取最后一条消息
- firebase - Firebase 存储规则:对允许的用户进行身份验证
- spring-boot - 如何在 Spring Boot 中将 Resilience4j 断路器与 WebFlux 一起使用