Reputation: 6752
I want to trigger a notification everytime the current city changes based on didUpdateLocations
:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let lastLocation = locations.last!
updateLocation(location: lastLocation)
}
So here I would compare if the city has changed and send a push notification based on that. How could I do this?
func updateLocation(location: CLLocation) {
fetchCityAndCountry(from: location) { city, country, error in
guard let city = city, let country = country, error == nil else { return }
self.locationLabel.text = city + ", " + country
if(city !== previousCity){
//Send push notification
}
}
}
I know I can trigger it based on location with a range but that's not specific enough for me.
Upvotes: 1
Views: 115
Reputation: 12139
Consider using the reverse geocoder api, it resolves CLLocation to CLPlacemark, which contains country name, city name and even street name in the language (local) you prefer. So basically, your code will be like.
func updateLocation(location: CLLocation) {
CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error)-> Void in
if error != nil {
return
}
if placemarks!.count > 0 {
let placemark = placemarks![0]
print("Address: \(placemark.name!) \(placemark.locality!), \(placemark.administrativeArea!) \(placemark.postalCode!)")
if placemark.locality! !== previousCity) {
// Send push notification
}
} else {
print("No placemarks found.")
}
})
}
EDIT 2
As for sending the notification, instead of using UNLocationNotificationTrigger
, just use the "normal trigger" - UNTimeIntervalNotificationTrigger
.
let notification = UNMutableNotificationContent()
notification.title = "Notification"
notification.subtitle = "Subtitle"
notification.body = "body"
let notificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 0, repeats: false)
let request = UNNotificationRequest(identifier: "notification1", content: notification, trigger: notificationTrigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
Edit 1
You don't want to call the geocoder very often, so you should check the distance between the current location and the last "checkpoint", only when it's big enough will you call the geocoder, otherwise it would be a waste.
BTW, the notification will be send from the phone itself, no server or APNS involved, this is called a local notification, not push notification.
Upvotes: 2