Essentially I am parsing JSON data and assigning it to a variable called addressPressNow
I then have the following function that executes when a user taps on a UILabel:
The goal is to have Apple Maps open provided the variable value it contains.
Because I am assigning an address to a variable it will contain spaces ex: 3981 Test Drive Cupertino CA 95014
NOTE: The value of the variable is being passed correctly because when I do print(addressPressNow)
in func tapFunction
it prints correctly.
@objc
func tapFunction(sender:UITapGestureRecognizer) {
let targetURL = NSURL(string: "http://maps.apple.com/?q=" + addressPressNow)!
UIApplication.shared.openURL(targetURL as URL)
}
The issue is I am having trouble applying the variable to the string URL with the following error:
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
The following is how I am assigning the value to the variable:
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
}
}
"I am assigning an address to a variable it will contain spaces"
If the address contains spaces then creating NSURL
with the string will crash. You can use addingPercentEncoding to solve the problem
if let encodedAddress = addressPressNow.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
let targetURL = NSURL(string: "http://maps.apple.com/?q=" + encodedAddress)!
UIApplication.shared.openURL(targetURL as URL)
}
And don't use NSURL
and force unwrapping. Update it like this
if let encodedAddress = addressPressNow.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let targetURL = URL(string: "http://maps.apple.com/?q=" + encodedAddress) {
UIApplication.shared.openURL(targetURL)
}
As suggested by matt use 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)
}