I have two view controllers and I am trying to pass data from one to the other. The data is returned from an MKLocalSearch closure. But I cannot seem to get my delegate method to run. I hope that someone can shed some light on this? I mocked up a smaller version of what I'm trying to do. Also, I don't use storyboards. I code up everything. Here is the code...
import UIKit
import MapKit
protocol SendDataDelegate {
func sendData(data: String)
}
class OneViewController: UIViewController {
var delegate: SendDataDelegate?
override func viewDidLoad() {
super.viewDidLoad()
doSearch() { coord in
if let coord = coord {
//When the execution gets here, coord does have
//the values to be sent to the nexr view controller.
self.delegate?.sendData(data: "\(coord)")
let twoViewController = TwoViewController()
self.present(twoViewController, animated: true)
}
}
}
func doSearch(completion: @escaping (CLLocationCoordinate2D?) -> Void) {
var coord: CLLocationCoordinate2D?
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = "New York"
let search = MKLocalSearch(request: request)
search.start(completionHandler: {(response, error) in
if error != nil {
print("Error occured in search:\(error!.localizedDescription)")
} else if response!.mapItems.count == 0 {
print("No matches found")
} else {
print("Matches found")
coord = response?.mapItems[0].placemark.coordinate
}
completion(coord)
})
}
}
import UIKit
class TwoViewController: UIViewController, SendDataDelegate {
var myData: String = ""
var oneViewController = OneViewController()
override func viewDidLoad() {
super.viewDidLoad()
oneViewController.delegate = self
}
func sendData(data: String) {
myData = data
print ("myData: \(myData)")
}
}
In your TwoViewController
, you have a property holding another instance of OneViewController
and setting the delegate of it to self
.
So, each time you create an instance of TwoViewController
, a new instance of OneViewController
is created, but none of them are actually the one in due of showing the actual view of OneViewController
.
In your case, delegate pattern is not appropriate and you should better call the method of TwoViewController
directly:
class OneViewController: UIViewController {
//no need to have a delegate
override func viewDidLoad() {
super.viewDidLoad()
doSearch() { coord in
if let coord = coord {
//When the execution gets here, coord does have
//the values to be sent to the nexr view controller.
let twoViewController = TwoViewController()
twoViewController.sendData(data: "\(coord)")
self.present(twoViewController, animated: true)
}
}
}
//...
}
class TwoViewController: UIViewController {
var myData: String = ""
//Creating a new instance of `OneViewController` has no meaning.
override func viewDidLoad() {
super.viewDidLoad()
//Useless to set the delegate of newly created `OneViewController`.
}
func sendData(data: String) {
myData = data
print ("myData: \(myData)")
}
}
If you have any reason to have a property oneViewController
in TwoViewController
, please explain why. Your current code explains nothing.