This question already has an answer here:
-
Passing parameters to the method called by a NSTimer
6 answers
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let mostRecentLocation = locations.last else {
return
}
print(mostRecentLocation.coordinate.latitude)
print(mostRecentLocation.coordinate.longitude)
Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(StartTestVC.sendDataToServer), userInfo: nil, repeats: true)
}
func sendDataToServer (latitude: Double, longitude: Double) {
SFUserManager.shared.uploadPULocation(latitude, longitude:longitude)
}
I want send data to server every 1 minute. I am using Timer.scheduledTimer and setting selector. But how could I send lat/lng params to my function?
For sending the data with Timer
you can use the userInfo
parameter for pass the data.
Here is the sample by which you can get call of selector method and by that you can pass your location coordinate to it.
Timer.scheduledTimer(timeInterval: 0.5, target: self, selector:#selector(iGotCall(sender:)), userInfo: ["Name": "i am iOS guy"], repeats:true)
For handling that userInfo
you need to go according to below.
func iGotCall(sender: Timer) {
print((sender.userInfo)!)
}
for your case make sure your didUpdateLocations
is called frequently.
One way to make sure your sendDataToServer
is always uploading the latest coordinates without inputting the coordinates to the function as input arguments would be to store the values in a scope, which can be accessed by the function and use those values inside the function.
Assuming you make mostRecentLocation
a class property, you can use below code
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let mostRecentLocation = locations.last else {
return
}
self.mostRecentLocation = mostRecentLocation
Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(StartTestVC.sendDataToServer), userInfo: nil, repeats: true)
}
func sendDataToServer() {
SFUserManager.shared.uploadPULocation(self.mostRecentLocation.coordinate.latitude, longitude:self.mostRecentLocation.coordinate.longitude)
}
This is exactly what the userInfo
parameter is meant to be used for:
struct SendDataToServerData { //TODO: give me a better name
let lastLocation: CLLocation
// Add other stuff if necessary
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let mostRecentLocation = locations.last else { return }
print(mostRecentLocation.coordinate.latitude)
print(mostRecentLocation.coordinate.longitude)
Timer.scheduledTimer(
timeInterval: 60.0,
target: self,
selector: #selector(StartTestVC.sendDataToServer(timer:)),
userInfo: SendDataToServerData(mostRecentLocation: mostRecentLocation),
repeats: true
)
}
// Only to be called by the timer
func sendDataToServerTimerFunc(timer: Timer) {
let mostRecentLocation = timer.userInfo as! SendDataToServerData
self.sendDataToServer(
latitude: mostRecentLocation.latitude
longitude: mostRecentLocation.longitude
)
}
// Call this function for all other uses
func sendDataToServer(latitude: Double, longitude: Double) {
SFUserManager.shared.uploadPULocation(latitude, longitude:longitude)
}