Loop through coordinates and find the closest shop to a point Swift 3 - ios

Idea :
App lets drivers see the closest shop/restaurants to customers.
What I have :
Coordinates saved as strings
let clientLat = "24.449384"
let clientLng = "56.343243"
a function to find all the shops in my local area
I tried to save all the coordinates of a shop in my local area and I succeeded:
var coordinates: [CLLocationCoordinate2D] = [CLLocationCoordinate2D]()
func performSearch() {
coordinates.removeAll()
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = "starbucks"
request.region = mapView.region
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")
for item in response!.mapItems {
self.coordinates.append(item.placemark.coordinate)
// need to sort coordinates
// need to find the closest
let annotation = MKPointAnnotation()
annotation.coordinate = item.placemark.coordinate
annotation.title = item.name
self.mapView.addAnnotation(annotation)
}
}
})
}
What I need:
I wish to loop through the coordinates and find the closest shop (kilometers) to the lat and long strings then put a pin on it.
UPDATE
func performSearch() {
coordinates.removeAll()
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = "starbucks"
request.region = mapView.region
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")
for item in response!.mapItems {
self.coordinates.append(item.placemark.coordinate)
let pointToCompare = CLLocation(latitude: 24.741721, longitude: 46.891440)
let storedCorrdinates = self.coordinates.map({CLLocation(latitude: $0.latitude, longitude: $0.longitude)}).sorted(by: {
$0.distance(from: pointToCompare) < $1.distance(from: pointToCompare)
})
self.coordinate = storedCorrdinates
}
let annotation = MKPointAnnotation()
annotation.coordinate = self.coordinate[0].coordinate
self.mapView.addAnnotation(annotation)
}
})
}
Thank you #brimstone

You can compare distances between coordinates by converting them to CLLocation types and then using the distance(from:) method. For example, take your coordinates array and map it to CLLocation, then sort that based on the distance from the point you are comparing them to.
let coordinates = [CLLocationCoordinate2D]()
let pointToCompare = CLLocation(latitude: <#yourLat#>, longitude: <#yourLong#>)
let sortedCoordinates = coordinates.map({CLLocation(latitude: $0.latitude, longitude: $0.longitude)}).sorted(by: {
$0.distance(from: pointToCompare) < $1.distance(from: pointToCompare)
})
Then, to set your annotation's coordinate to the nearest coordinate, just subscript the sortedCoordinates array.
annotation.coordinate = sortedCoordinates[0].coordinate

I would like to share my solution :)
1) In my case, I upload data from the API, so I need to create a model.
import MapKit
struct StoresMap: Codable {
let id: Int?
let title: String?
let latitude: Double?
let longitude: Double?
let schedule: String?
let phone: String?
let ukmStoreId: Int?
var distanceToUser: CLLocationDistance?
}
The last variable is not from API, but from myself to define distance for each store.
2) In ViewController I define:
func fetchStoresList() {
NetworkManager.downloadStoresListForMap(firstPartURL: backendURL) { (storesList) in
self.shopList = storesList
let initialLocation = self.locationManager.location!
for i in 0..<self.shopList.count {
self.shopList[i].distanceToUser = initialLocation.distance(from: CLLocation(latitude: self.shopList[i].latitude!, longitude: self.shopList[i].longitude!))
}
self.shopList.sort(by: { $0.distanceToUser! < $1.distanceToUser!})
print("Closest shop - ", self.shopList[0])
}
}
3) Don't forget to call the function in viewDidLoad() and import MapView framework :)

Related

Two Functions are calling in Swift

I am using GoogleMaps to show the location marker on screens after fetching the location from Firestore database but the problem is I have three functions.
First function is showing all the list of users on the google maps, I called it in viewDidLoad() method.
func showListOfAllUsers() {
for document in snapshot!.documents {
print(document.data())
let marker = GMSMarker()
self.location.append(Location(trackingData: document.data()))
print(self.location)
guard let latitude = document.data()["Latitude"] as? Double else { return }
guard let longitude = document.data()["longitude"] as? Double else { return }
marker.position = CLLocationCoordinate2D(latitude: latitude as! CLLocationDegrees , longitude: longitude as! CLLocationDegrees)
marker.map = self.mapView
marker.userData = self.location
marker.icon = UIImage(named: "marker")
bounds = bounds.includingCoordinate(marker.position)
print("Data stored in marker \(marker.userData!)")
}
}
Now I presented a list of users in which I am passing the selected user co-ordinates to show the markers on the GoogleMaps.
func getAllLocationOfSelectedUserFromFirestore() {
for document in snapshot!.documents {
print(document.data())
let marker = GMSMarker()
self.location.append(Location(trackingData: document.data()))
print(self.location)
guard let latitude = document.data()["Latitude"] as? Double else { return }
guard let longitude = document.data()["longitude"] as? Double else { return }
marker.position = CLLocationCoordinate2D(latitude: latitude as! CLLocationDegrees , longitude: longitude as! CLLocationDegrees)
marker.map = self.mapView
marker.userData = self.location
bounds = bounds.includingCoordinate(marker.position)
print("Data stored in marker \(marker.userData!)")
}
}
I used delegate method to pass the selected user information.
extension MapViewController: ShowTrackingSalesMenListVCDelegate {
func didSelectedFilters(_ sender: ShowTrackingSalesMenListViewController, with userID: String) {
self.selectedUserID = userID
self.userLogButton.isHidden = false
print("The selected UserID is \(selectedUserID)")
self.getAllLocationOfSelectedUserFromFirestore() // called here the second function
}
Here is GMSMapViewDelegate function in which I am passing the user informations in userData.
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
print("didTap marker")
self.view.endEditing(true)
self.mapView.endEditing(true)
if let _ = self.activeMarker {
self.infoWindowView.removeFromSuperview()
self.activeMarker = nil
}
self.infoWindowView = MarkerInfoView()
let point = mapView.projection.point(for: marker.position)
self.infoWindowView.frame = CGRect(x: (point.x-(self.infoWindowView.width/2.0)), y: (point.y-(self.infoWindowView.height+25.0)), width: self.infoWindowView.width, height: self.infoWindowView.height)
self.activeMarker = marker
for mark in location {
self.infoWindowView.storeNameLabel?.text = mark.name
}
print(self.infoWindowView.storeNameLabel?.text as Any)
if let data = marker.userData as? [String:Any] {
print(data)
self.storeMapData = data
print(self.storeMapData)
var name = "N/A"
if let obj = data["name"] as? String {
name = obj
}
} else {
}
infoWindowView.delegate = self
self.mapView.addSubview(self.infoWindowView)
return true
}
It is showing the marker of the selected user on GoogleMaps. Now the problem is GMSMapViewDelegate function is same for both the above functions and it is showing the markers from both the functions on map. But I want to show only the selected user information on Maps. The red marker showing the selected user locations. How can I do this?
Just put a boolean flag and when you select the user set it to true and check it in the delegate and clear map overlay and put your marker only

I get an empty CLLocationCoordinates array when loading data from user defaults

I'm trying to store to UserDefaults an array of CCLocationCoordinates from the tracking portion of my app paired with the name of the tracked route as key, to be able to recall it later on to use it within a function.
The problem is that when I call that function I get the index out of range error. I checked and the array is empty.
As I'm new to user defaults I tried to see other similar posts but they're all about NSUserDefaults and didn't find a solution.
Heres the code for the functions for storing and recalling the array:
func stopTracking2() {
self.trackingIsActive = false
self.trackigButton.backgroundColor = UIColor.yellow
locationManager.stopUpdatingLocation()
let stopRoutePosition = RouteAnnotation(title: "Route Stop", coordinate: (locationManager.location?.coordinate)!, imageName: "Route Stop")
self.actualRouteInUseAnnotations.append(stopRoutePosition)
print(actualRouteInUseCoordinatesArray)
print(actualRouteInUseAnnotations)
drawRoutePolyline() // draw line to show route
// checkAlerts2() // check if there is any notified problem on our route and marks it with a blue circle, now called at programmed checking
saveRouteToUserDefaults()
postRouteToAnalitics() // store route anonymously to FIrebase
}
func saveRouteToUserDefaults() {
// save actualRouteInUseCoordinatesArray : change for function
// userDefaults.set(actualRouteInUseCoordinatesArray, forKey: "\(String(describing: userRoute))")
storeCoordinates(actualRouteInUseCoordinatesArray)
}
// Store an array of CLLocationCoordinate2D
func storeCoordinates(_ coordinates: [CLLocationCoordinate2D]) {
let locations = coordinates.map { coordinate -> CLLocation in
return CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
}
let archived = NSKeyedArchiver.archivedData(withRootObject: locations)
userDefaults.set(archived, forKey: "\(String(describing: userRoute))")
userDefaults.synchronize()
}
func loadRouteFromUserDefaults() {
// gets entry from userRouteArray stored in userDefaults and append them into actualRouteInUseCoordinatesArray
actualRouteInUseCoordinatesArray.removeAll()
actualRouteInUseCoordinatesArray = userDefaults.object(forKey: "\(String(describing: userRoute))") as? [CLLocationCoordinate2D] ?? [CLLocationCoordinate2D]() // here we get the right set of coordinates for the route we are about to do the check on
// load route coordinates from UserDefaults
// actualRouteInUseCoordinatesArray = loadCoordinates()! //error found nil
}
// Return an array of CLLocationCoordinate2D
func loadCoordinates() -> [CLLocationCoordinate2D]? {
guard let archived = userDefaults.object(forKey: "\(String(describing: userRoute))") as? Data,
let locations = NSKeyedUnarchiver.unarchiveObject(with: archived) as? [CLLocation] else {
return nil
}
let coordinates = locations.map { location -> CLLocationCoordinate2D in
return location.coordinate
}
return coordinates
}
}
extension NewMapViewController {
// ALERTS :
func checkAlerts2() {
loadRouteFromUserDefaults() //load route coordinates to check in
// CHECK IF ANY OBSTACLE IS OUN OUR ROUTE BY COMPARING DISTANCES
while trackingCoordinatesArrayPosition != ( (actualRouteInUseCoordinatesArray.count) - 1) {
print("checking is started")
print(actualRouteInUseCoordinatesArray)
let trackingLatitude = actualRouteInUseCoordinatesArray[trackingCoordinatesArrayPosition].latitude
let trackingLongitude = actualRouteInUseCoordinatesArray[trackingCoordinatesArrayPosition].longitude
let alertLatitude = alertNotificationCoordinatesArray[alertNotificationCoordinatesArrayPosition].latitude
let alertLongitude = alertNotificationCoordinatesArray[alertNotificationCoordinatesArrayPosition].longitude
let coordinateFrom = CLLocation(latitude: trackingLatitude, longitude: trackingLongitude)
let coordinateTo = CLLocation(latitude: alertLatitude, longitude: alertLongitude)
let coordinatesDistanceInMeters = coordinateFrom.distance(from: coordinateTo)
// CHECK SENSITIVITY: sets the distance in meters for an alert to be considered an obstacle
if coordinatesDistanceInMeters <= 10 {
print( "found problem")
routeObstacle.append(alertNotificationCoordinatesArray[alertNotificationCoordinatesArrayPosition]) // populate obstacles array
trackingCoordinatesArrayPosition = ( trackingCoordinatesArrayPosition + 1)
}
else if alertNotificationCoordinatesArrayPosition < ((alertNotificationCoordinatesArray.count) - 1) {
alertNotificationCoordinatesArrayPosition = alertNotificationCoordinatesArrayPosition + 1
}
else if alertNotificationCoordinatesArrayPosition == (alertNotificationCoordinatesArray.count - 1) {
trackingCoordinatesArrayPosition = ( trackingCoordinatesArrayPosition + 1)
alertNotificationCoordinatesArrayPosition = 0
}
}
findObstacles()
NewMapViewController.checkCounter = 0
displayObstacles()
}
In the extension you can see the function that uses the array.
Right after the print of the array I get the index out of range error.
Thanks as usual to the community.
After trying various solutions offered I decided to rewrite the whole thing.
So after finding a post on how to code/decode my array to string I decided it was the way to go. It shouldn't be heavy on the system as it's a string that gets saved. Please let me know what you think of this solution.
Thank to #Sh_Khan to point out it was a decoding issue, and to #Moritz to point out I was performing a bad practice.
So the code is:
func storeRoute() {
// first we code the CLLocationCoordinate2D array to string
// second we store string into userDefaults
userDefaults.set(encodeCoordinates(coords: actualRouteInUseCoordinatesArray), forKey: "\(String(describing: NewMapViewController.userRoute))")
}
func loadRoute() {
//first se load string from user defaults
let route = userDefaults.string(forKey: "\(String(describing: NewMapViewController.userRoute))")
print("loaded route is \(route!))")
//second we decode it into CLLocationCoordinate2D array
actualRouteInUseCoordinatesArray = decodeCoordinates(encodedString: route!)
print("decoded route array is \(actualRouteInUseCoordinatesArray))")
}
func encodeCoordinates(coords: [CLLocationCoordinate2D]) -> String {
let flattenedCoords: [String] = coords.map { coord -> String in "\(coord.latitude):\(coord.longitude)" }
let encodedString: String = flattenedCoords.joined(separator: ",")
return encodedString
}
func decodeCoordinates(encodedString: String) -> [CLLocationCoordinate2D] {
let flattenedCoords: [String] = encodedString.components(separatedBy: ",")
let coords: [CLLocationCoordinate2D] = flattenedCoords.map { coord -> CLLocationCoordinate2D in
let split = coord.components(separatedBy: ":")
if split.count == 2 {
let latitude: Double = Double(split[0]) ?? 0
let longitude: Double = Double(split[1]) ?? 0
return CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
} else {
return CLLocationCoordinate2D()
}
}
return coords
}
Rather than using heavy-weight objectiv-c-ish NSKeyed(Un)Archiver and making a detour via CLLocation I recommend to extend CLLocationCoordinate2D to adopt Codable
extension CLLocationCoordinate2D : Codable {
public init(from decoder: Decoder) throws {
var arrayContainer = try decoder.unkeyedContainer()
if arrayContainer.count == 2 {
let lat = try arrayContainer.decode(CLLocationDegrees.self)
let lng = try arrayContainer.decode(CLLocationDegrees.self)
self.init(latitude: lat, longitude: lng)
} else {
throw DecodingError.dataCorruptedError(in: arrayContainer, debugDescription: "Coordinate array must contain two items")
}
}
public func encode(to encoder: Encoder) throws {
var arrayContainer = encoder.unkeyedContainer()
try arrayContainer.encode(contentsOf: [latitude, longitude])
}
}
and replace the methods to load and save data with
func storeCoordinates(_ coordinates: [CLLocationCoordinate2D]) throws {
let data = try JSONEncoder().encode(coordinates)
UserDefaults.standard.set(data, forKey: String(describing: userRoute))
}
func loadCoordinates() -> [CLLocationCoordinate2D] {
guard let data = UserDefaults.standard.data(forKey: String(describing: userRoute)) else { return [] }
do {
return try JSONDecoder().decode([CLLocationCoordinate2D].self, from: data)
} catch {
print(error)
return []
}
}
storeCoordinates throws it hands over a potential encoding error
Load the data with
actualRouteInUseCoordinatesArray = loadCoordinates()
and save it
do {
try storeCoordinates(actualRouteInUseCoordinatesArray)
} catch { print(error) }
Your problem is that you save it as data and try to read directly without unarchiving , You can try
let locations = [CLLocation(latitude: 123, longitude: 344),CLLocation(latitude: 123, longitude: 344),CLLocation(latitude: 123, longitude: 344)]
do {
let archived = try NSKeyedArchiver.archivedData(withRootObject: locations, requiringSecureCoding: true)
UserDefaults.standard.set(archived, forKey:"myKey")
// read savely
if let data = UserDefaults.standard.data(forKey: "myKey") {
let saved = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! [CLLocation]
print(saved)
}
}
catch {
print(error)
}

Can I get a store name/restaurant name with mapkit?(swift)

I have a mapview and I added a method to drop a pin on the location where the user had pressed. The callout shows the address of the location as shown on the image.
screenshot of my mapview with annotation pin and callout view.
And my code is as following:
func onTapGestureRecognized(sender: UILongPressGestureRecognizer) {
self.mapView.removeAnnotations(mapView.annotations)
let location = tapRecognizer.location(in: mapView)
let coordinate = mapView.convert(location,toCoordinateFrom: mapView)
let getLat: CLLocationDegrees = coordinate.latitude
let getLon: CLLocationDegrees = coordinate.longitude
let theLocation: CLLocation = CLLocation(latitude: getLat, longitude: getLon)
let geoCoder = CLGeocoder()
geoCoder.reverseGeocodeLocation(theLocation, completionHandler: { (placemarks, error) -> Void in
// Place details
var placeMark: CLPlacemark!
placeMark = placemarks?[0]
var theLocationName = ""
var theStreetNumber = ""
var theStreet = ""
var theCity = ""
var theZip = ""
var theCountry = ""
// Address dictionary
print(placeMark.addressDictionary as Any)
// Location name
if let locationName = placeMark.name{
theLocationName = locationName
}
if let streetNumber = placeMark.subThoroughfare{
theStreetNumber = streetNumber
}
// Street address
if let street = placeMark.thoroughfare {
theStreet = street
}
// City
if let city = placeMark.locality {
theCity = city
}
// Zip code
if let zip = placeMark.postalCode{
theZip = zip
}
// Country
if let country = placeMark.isoCountryCode{
theCountry = country
}
let annotation = MKPointAnnotation()
annotation.title = theLocationName
annotation.subtitle = theStreetNumber + " " + theStreet + ", " + theCity + ", " + theCountry + ", " + theZip
if let location = placeMark.location {
annotation.coordinate = location.coordinate
// Display the annotation
self.mapView.showAnnotations([annotation], animated: true)
}
})
}
As you can see, when I try to get the location name by calling the line (((( if let locationName = placeMark.name )))), I can only get the address: "5197 Yonge St", instead of the restaurant name : " Pho 88 Restaurant ".
Can anyone tell me where I did wrong? or is it simply cannot be achieved? Thanks!
I can't give you a complete answer, but I may be able to point you in the right direction. As far as I can see, you will only ever get a single entry returned for placemarks, but you can get a more complete list using MKLocalSearchRequest. the challenge is going to be how you match up the returned values to exactly which one you want - maybe you have to ask the user to select from a short list? Also, I think you need to specify which type of establishment you're searching for. Here's something you could include within your completion handler above
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = "restaurant" // or whatever you're searching for
request.region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: getLat, longitude: getLon), span: self.mapView.region.span)
let search = MKLocalSearch(request: request)
search.start { response, error in
guard let response = response else {
print("There was an error searching for: \(request.naturalLanguageQuery) error: \(error)")
return
}
print("There are \(response.mapItems.count)")
for item in response.mapItems {
// You may be able to match the address to what the geoCode gives you
// or present the user with a list of options
print("\(item.name), \(item.placemark)")
}
}
When I was testing this, the addresses didn't always match up, even when zoomed in - so that geoCoder might give me 1-3 Some Street while the MKLocalSearchRequest returned a restaurant at 3 Some Street

MapBox swift 3 api

I use MapBox api swift 2.3 and reading geojson. But after swift 3 dont work began to upgrade.
Swift 2.3 examples; its work
for location in locations {
nate2D(latitude: location[1].doubleValue, longitude: location[0].doubleValue)
coordinates.append(coordinate)
}
Swift 3.0 dont work
if let feature = feature as? NSDictionary {
if let geometry = feature["geometry"] as? NSDictionary {
if geometry["type"] as? String == "Polygon" {
var coordinates: [CLLocationCoordinate2D] = []
if let locations = geometry["coordinates"] as? NSArray {
for location in locations {
for i in (0 ..< (location as AnyObject).count)
{
let coordinate = CLLocationCoordinate2D(latitude: ???, longitude: ???)
coordinates.append(coordinate)
}
}
}
let shape = MGLPolygon(coordinates: &coordinates, count: UInt(coordinates.count))
DispatchQueue.main.async(execute: {
[unowned self] in
self.mapView.addAnnotation(shape)
})
}
}
}
enter image description here
It ' s correct answer
for location in locations {
for i in (0 ..< (location as AnyObject).count)
{
let a = locations[0] as? NSArray
let b = a?[i] as? NSArray
var c = b?[0]
print(c);
let coordinate = CLLocationCoordinate2D(latitude: b?[1] as! CLLocationDegrees, longitude: b?[0] as! CLLocationDegrees)
coordinates.append(coordinate)
}
}

Create MapKit Circle overlay from multiple CloudKit records

I've been trying to add a new map view to my app which shows an overlay of all of the Geofenced regions in my CloudKit database.
At the moment I'm able to create pins from each of the locations with the following code.
func fetchData() {
let predicate = NSPredicate(format: "TRUEPREDICATE", argumentArray: nil)
let query = CKQuery(recordType: "Collection", predicate: predicate)
let operation = CKQueryOperation(query: query)
operation.desiredKeys = ["Location"]
operation.recordFetchedBlock = { (record : CKRecord) in
self.collectionLocation = record.objectForKey("Location") as? CLLocation
print(self.collectionLocation?.coordinate.latitude)
self.buildBubbles()
}
publicDB!.addOperation(operation)
operation.queryCompletionBlock = {(cursor, error) in
dispatch_async(dispatch_get_main_queue()) {
if error == nil {
} else {
print("error description = \(error?.description)")
}
}
}
}
func buildBubbles() {
if CLLocationManager.isMonitoringAvailableForClass(CLCircularRegion.self) {
let intrepidLat: CLLocationDegrees = (self.collectionLocation?.coordinate.latitude)!
let intrepidLong: CLLocationDegrees = (self.collectionLocation?.coordinate.longitude)!
let title = "Item"
let coordinate = CLLocationCoordinate2DMake(intrepidLat, intrepidLong)
let regionRadius = 300.0
let region = CLCircularRegion(center: CLLocationCoordinate2D(latitude: coordinate.latitude,
longitude: coordinate.longitude), radius: regionRadius, identifier: title)
self.locationManager.startMonitoringForRegion(region)
let restaurantAnnotation = MKPointAnnotation()
restaurantAnnotation.coordinate = coordinate;
restaurantAnnotation.title = "\(title)"
self.mapView.addAnnotation(restaurantAnnotation)
// Overlay code goes here
}
else {
print("System can't track regions")
}
}
But when I go to add the overlay:
let circle = MKCircle(centerCoordinate: coordinate, radius: regionRadius)
self.mapView.addOverlay(circle)
The app fails with error:
"This application is modifying the autolayout engine from a background
thread, which can lead to engine corruption and weird crashes. This
will cause an exception in a future release."
My guess is that I'm doing too much inside the background thread but when I move the "buildBubbles" function into the main queue it adds the circle overlay but only adds one of the Locations to the map.
Thanks for taking the time to look I would really appreciate any help.
Your interface into the bubbles function only provides for holding one location. Try changing the interface, such as to an array, and then see what you get. You will also need to worry about how you actually synchronize one versus the other
I did as Feldur suggested and created an array from the CloudKit Data then moved the MapKit set up from the background thread.
func fetchBubble() {
let query = CKQuery(recordType: "Collection", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil))
publicDB!.performQuery(query, inZoneWithID: nil) { results, error in
if error == nil {
for collection in results! {
let collectionLocation = collection.valueForKey("Location") as? CLLocation
let collectionName = collection.valueForKey("Name") as! String
dispatch_async(dispatch_get_main_queue(), { () -> Void in
if CLLocationManager.isMonitoringAvailableForClass(CLCircularRegion.self) {
let intrepidLat: CLLocationDegrees = (collectionLocation?.coordinate.latitude)!
let intrepidLong: CLLocationDegrees = (collectionLocation?.coordinate.longitude)!
let title = collectionName
let coordinate = CLLocationCoordinate2DMake(intrepidLat, intrepidLong)
let regionRadius = 50.0
let region = CLCircularRegion(center: CLLocationCoordinate2D(latitude: coordinate.latitude,
longitude: coordinate.longitude), radius: regionRadius, identifier: title)
self.locationManager.startMonitoringForRegion(region)
let restaurantAnnotation = MKPointAnnotation()
self.mapView.addAnnotation(restaurantAnnotation)
restaurantAnnotation.coordinate = coordinate
let circle = MKCircle(centerCoordinate: coordinate, radius: regionRadius)
self.mapView.addOverlay(circle)
self.numberOfObjectsInMyArray()
}
else {
print("System can't track regions")
}
})
}
}
else {
print(error)
}
}
}

Resources