按下 UILabel 时分配变量值以打开 Apple Maps 的问题
Issue assigning variable value to open Apple Maps when pressing a UILabel
本质上,我正在解析 JSON 数据并将其分配给一个名为 addressPressNow
的变量,然后我将在用户点击 UILabel 时执行以下函数:
目标是打开 Apple Maps,提供它包含的变量值。
因为我正在为一个变量分配一个地址,它将包含空格
例如:3981 试驾 Cupertino CA 95014
注意:变量的值被正确传递,因为当我在 func tapFunction
中执行 print(addressPressNow)
时它打印正确。
@objc
func tapFunction(sender:UITapGestureRecognizer) {
let targetURL = NSURL(string: "http://maps.apple.com/?q=" + addressPressNow)!
UIApplication.shared.openURL(targetURL as URL)
}
问题是我在将变量应用于字符串 URL 时遇到问题,出现以下错误:
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an
Optional value
以下是我为变量赋值的方式:
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(string: "http://maps.apple.com/?q=" + addressPressNow)!
注意最后的感叹号。这意味着 "if there's a problem, crash me"。如果你真的崩溃了,你几乎不能抱怨;这就是你要求做的。
基本上,如果可以避免,从不使用NSURL(string:)
。要形成有效的 URL,请使用 URL 组件构建它。并由 valid 个组件组成。 (不可能说 facility_address
是否是一个有效的 URL 查询,因为你没有显示它是什么。)
示例:
var comp = URLComponents()
comp.scheme = "https"
comp.host = "maps.apple.com"
comp.queryItems = [URLQueryItem(name: "q", value: "1 Infinite Loop, Cupertino, CA")]
if let url = comp.url {
print(url) // https://maps.apple.com?q=1%20Infinite%20Loop,%20Cupertino,%20CA
}
这给了我们一个有效的 URL 实际有效。
"I am assigning an address to a variable it will contain spaces"
如果地址包含空格,则使用字符串创建 NSURL
将会崩溃。可以用addingPercentEncoding解决问题
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)
}
根据 matt 的建议使用 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)
}
本质上,我正在解析 JSON 数据并将其分配给一个名为 addressPressNow
的变量,然后我将在用户点击 UILabel 时执行以下函数:
目标是打开 Apple Maps,提供它包含的变量值。
因为我正在为一个变量分配一个地址,它将包含空格 例如:3981 试驾 Cupertino CA 95014
注意:变量的值被正确传递,因为当我在 func tapFunction
中执行 print(addressPressNow)
时它打印正确。
@objc
func tapFunction(sender:UITapGestureRecognizer) {
let targetURL = NSURL(string: "http://maps.apple.com/?q=" + addressPressNow)!
UIApplication.shared.openURL(targetURL as URL)
}
问题是我在将变量应用于字符串 URL 时遇到问题,出现以下错误:
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
以下是我为变量赋值的方式:
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(string: "http://maps.apple.com/?q=" + addressPressNow)!
注意最后的感叹号。这意味着 "if there's a problem, crash me"。如果你真的崩溃了,你几乎不能抱怨;这就是你要求做的。
基本上,如果可以避免,从不使用NSURL(string:)
。要形成有效的 URL,请使用 URL 组件构建它。并由 valid 个组件组成。 (不可能说 facility_address
是否是一个有效的 URL 查询,因为你没有显示它是什么。)
示例:
var comp = URLComponents()
comp.scheme = "https"
comp.host = "maps.apple.com"
comp.queryItems = [URLQueryItem(name: "q", value: "1 Infinite Loop, Cupertino, CA")]
if let url = comp.url {
print(url) // https://maps.apple.com?q=1%20Infinite%20Loop,%20Cupertino,%20CA
}
这给了我们一个有效的 URL 实际有效。
"I am assigning an address to a variable it will contain spaces"
如果地址包含空格,则使用字符串创建 NSURL
将会崩溃。可以用addingPercentEncoding解决问题
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)
}
根据 matt 的建议使用 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)
}