Currently, my code drops a pin on the user's current location. There is one small problem when I try to move the map around, because the view will shift back and be centered around that current location pin. I want the user be able to navigate the map and move it around, and if the user switches view controllers (goes to another tab) and comes back, the map will be centered around the user location pin. I have been trying to modify this code to do this, but I have not had any luck where to start.
import UIKit
import MapKit
import CoreLocation
let newPin = MKPointAnnotation()
class MapVC: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var map: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// User's location
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
if #available(iOS 8.0, *) {
locationManager.requestAlwaysAuthorization()
} else {
// Fallback on earlier versions
}
locationManager.startUpdatingLocation()
// add gesture recognizer
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(MapVC.mapLongPress(_:))) // colon needs to pass through info
longPress.minimumPressDuration = 1.5 // in seconds
//add gesture recognition
map.addGestureRecognizer(longPress)
}
// func called when gesture recognizer detects a long press
func mapLongPress(_ recognizer: UIGestureRecognizer) {
print("A long press has been detected.")
let touchedAt = recognizer.location(in: self.map) // adds the location on the view it was pressed
let touchedAtCoordinate : CLLocationCoordinate2D = map.convert(touchedAt, toCoordinateFrom: self.map) // will get coordinates
let newPin = MKPointAnnotation()
newPin.coordinate = touchedAtCoordinate
map.addAnnotation(newPin)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
map.removeAnnotation(newPin)
let location = locations.last! as CLLocation
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
//set region on the map
map.setRegion(region, animated: true)
newPin.coordinate = location.coordinate
map.addAnnotation(newPin)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You can use custom location manager class and call the singleton function in didfinishlaunching with option and save latitude and longitude in UserDefault .Set camera position in viewDidLoad for mapView class
1.Make singleton class
var locationShareInstance:locationManagerClass = locationManagerClass()
class locationManagerClass: NSObject, CLLocationManagerDelegate, WebServiceDelegate , UIAlertViewDelegate
{
var locationManager = CLLocationManager()
class func sharedLocationManager() -> locationManagerClass
{
locationShareInstance = locationManagerClass()
return locationShareInstance
}
func startStandardUpdates() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.activityType = .automotiveNavigation
locationManager.distanceFilter = 10
locationManager.pausesLocationUpdatesAutomatically = false
if (Bundle.main.object(forInfoDictionaryKey: "NSLocationWhenInUseUsageDescription") != nil) {
locationManager.requestWhenInUseAuthorization()
}
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// If it's a relatively recent event, turn off updates to save power.
let location: CLLocation = locations.last!
let strLocation = "\(location.coordinate.latitude)"
if strLocation == "" {
}else{
UserDefaults.standard.set("\(location.coordinate.latitude)", forKey: "lat")
UserDefaults.standard.set("\(location.coordinate.longitude)", forKey: "long")
UserDefaults.standard.synchronize()
debugPrint("Spedd: \(location.speed)")
// self.updateLocationToServer()
self.stopStandardUpdate()
}
}
func stopStandardUpdate(){
locationManager.stopUpdatingLocation()
}
//MARK:- WHEN DENIED
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == CLAuthorizationStatus.denied {
NSLog("DENIAL")
UserDefaults.standard.set("\(0.0)", forKey: "lat")
UserDefaults.standard.set("\(0.0)", forKey: "long")
self.generateAlertToNotifyUser()
}
}
func generateAlertToNotifyUser() {
if CLLocationManager.authorizationStatus() == CLAuthorizationStatus.notDetermined{
var title: String
title = ""
let message: String = "Location Services are not able to determine your location"
let alertView: UIAlertView = UIAlertView(title: title, message: message, delegate: self, cancelButtonTitle: "Cancel", otherButtonTitles: "Settings")
alertView.show()
}
if CLLocationManager.authorizationStatus() == CLAuthorizationStatus.denied{
var title: String
title = "Location services are off"
let message: String = "To post spots or find near by spots, you must turn on Location Services from Settings"
let alertView: UIAlertView = UIAlertView(title: title, message: message, delegate: self, cancelButtonTitle: "Cancel", otherButtonTitles: "Settings")
alertView.show()
}
if CLLocationManager.authorizationStatus() == CLAuthorizationStatus.notDetermined
{
startStandardUpdates()
}
}
}
Call this functions in didfinishlaunchingwithoption
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let locationManager = locationManagerClass.sharedLocationManager()
locationManager.startStandardUpdates()
}
3.Set camera in viewDidLoad of your class
if UserDefaults.standard.object(forKey: "lat") != nil {
let lat = UserDefaults.standard.object(forKey: "lat") as! String
let long = UserDefaults.standard.object(forKey: "long") as! String
var userLoc = CLLocationCoordinate2D()
userLoc.latitude = CDouble(lat)!
userLoc.longitude = CDouble(long)!
let span = MKCoordinateSpanMake(0.02, 0.02)
let region = MKCoordinateRegion(center: userLoc, span: span)
mapVw.setRegion(region, animated: true)
mapVw.showsUserLocation = true
}
Related
I have added three permissions in info.plist
and popup coming with three options.. here
1)if i click "allow while using app" then i need to autofill textfields with current location address but
if i click "allow once" then i dont need to autofill textfields with current location
in my code in both allow once and allow while using conditions textfields are autofilling with current location address:
class MapViewController: UIViewController, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
var latitude: String?
var logitude: String?
#IBOutlet weak var text1: UITextField!
#IBOutlet weak var text2: UITextField!
#IBOutlet weak var text3: UITextField!
let annotation = MKPointAnnotation()
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let _: CLLocationCoordinate2D = manager.location?.coordinate else { return }
let userLocation :CLLocation = locations[0] as CLLocation
latitude = "\(userLocation.coordinate.latitude)"
logitude = "\(userLocation.coordinate.longitude)"
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(userLocation) { (placemarks, error) in
if (error != nil){
print("error in reverseGeocode")
}
let placemark = placemarks! as [CLPlacemark]
if placemark.count>0{
let placemark = placemarks![0]
let placemarkDictonary: NSDictionary=placemark.addressDictionary as! NSDictionary
self.text1.text=placemarkDictonary["ZIP"] as? String
self.text2.text=placemarkDictonary["City"] as? String
self.text3.text=placemarkDictonary["Street"] as? String
}
}
let center = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1))
mapView.setRegion(region, animated: true)
let myAnnotation: MKPointAnnotation = MKPointAnnotation()
myAnnotation.coordinate = CLLocationCoordinate2DMake(userLocation.coordinate.latitude, userLocation.coordinate.longitude);
myAnnotation.title = "Current location"
mapView.addAnnotation(myAnnotation)
locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .denied:
print("User hates you!!")
case .authorizedWhenInUse:
let viewController = self.storyboard?.instantiateViewController(withIdentifier: "FinalViewController") as! FinalViewController
self.navigationController?.pushViewController(viewController, animated: true);
case .authorizedAlways:
let viewController = self.storyboard?.instantiateViewController(withIdentifier: "FinalViewController") as! FinalViewController
self.navigationController?.pushViewController(viewController, animated: true);
}
}
}
actually i need only current location coordinates when i click "allow once", no need to autofill address in textfields. how to do that?
please help with code.
When In Use and Allow Once are the same permission but with different expiry duration. Tapping Allow Once on the location permission prompt will enable When In Use permission for the current session of the app, ie. until the user force kills the app or if the app stays in the background for a long duration. If the user tapped Allow Once permission, you will get all location updates as if he gave When In Use permission. But if the user kills the app and relaunches it, the system will again show location permission prompt.
So what you are trying to do will not be possible by checking the status returned by locationManager(_ manager: CLLocationManager, didChangeAuthorization as it will give the status as authorizedWhenInUse for both of these permissions. You can't differentiate them.
Documentation
I am trying to create a view controller on swift that shows where the user is located. I have already implemented google maps, so now all I have to do is plug in the correct code. When doing so, I keep getting these two error messages then the app crashes. Can someone help me with figuring out a solution> any and all help is appreciated.
import UIKit
import Foundation
import Firebase
import MapKit
import GoogleMaps
import CoreLocation
class mainViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
let defaults = UserDefaults.standard
let locationManager = CLLocationManager()
var mapView = GMSMapView()
var camera = GMSCameraPosition()
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
GMSServices.provideAPIKey("AIzaSyBDOLisA3c-wDTbkbSssAxEb3iLw7Y5vHo")
let camera = GMSCameraPosition.camera(withLatitude: (self.locationManager.location?.coordinate.latitude)!, longitude: (self.locationManager.location?.coordinate.latitude)!, zoom: 17)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
view = mapView
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: (self.locationManager.location?.coordinate.latitude)!, longitude: (self.locationManager.location?.coordinate.latitude)!)
marker.snippet = "Current Location"
marker.map = mapView
self.mapView.addSubview(mapView)
view.backgroundColor = GREEN_Theme
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.title = "Welcome"
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Logout", style: .plain, target: self, action: #selector(Logout))
}
#objc func Logout() {
print("Logged Out")
do {
// I am receiving this error message on the auth.auth().signOut() "Use of unresolved identifier 'Auth'"
try Auth.auth().signOut()
defaults.set(false, forKey: "user is logged in")
let loginController = UINavigationController(rootViewController: LoginController())
present(loginController, animated: true, completion: nil)
} catch let err {
print(err.localizedDescription)
}
}
}
Your issue is that the CLLocationManager does not have enough time to fetch the info and in the meantime other functions ask for that info which its still nil.
The below will take care the issue, it also stops updating the locations all the time which can be battery draining especially considering that you have set AccuracyBest.
func getLocation(){
locationManager=CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
let lastLocation=locations[locations.count-1]
if lastLocation.horizontalAccuracy>0{
locationManager.stopUpdatingLocation()
let latitude = lastLocation.coordinate.latitude
let longitude = lastLocation.coordinate.longitude
GMSServices.provideAPIKey("AIzaSyBDOLisA3c-wDTbkbSssAxEb3iLw7Y5vHo")
// everything that is going to require the latitude and longitude from the location manager goes here
let camera = GMSCameraPosition.camera(withLatitude: (self.locationManager.location?.coordinate.latitude)!, longitude: (self.locationManager.location?.coordinate.latitude)!, zoom: 17)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
self.view = mapView
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: (self.locationManager.location?.coordinate.latitude)!, longitude: (self.locationManager.location?.coordinate.latitude)!)
marker.snippet = "Current Location"
marker.map = mapView
self.mapView.addSubview(mapView)
}
}
Your viewDidLoad should have:
override func viewDidLoad() {
super.viewDidLoad()
getLocation()
view.backgroundColor = GREEN_Theme
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.title = "Welcome"
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Logout", style: .plain, target: self, action: #selector(Logout))
}
You are using Google Map as your map view, which means that you create an instance of the GMSMapView class. That's an object. You have one. And I assume that it's IBOutlet-wired. It comes with several delegate methods. So you may want to set its delegate. And you want your view controller to receive data from GMSMapView. So you set the delegate of that class to self (your view controller).
import UIKit
import Foundation
import Firebase
import GoogleMaps
import CoreLocation
class mainViewController: UIViewController, CLLocationManagerDelegate, GMSMapViewDelegate {
// MARK: - Instance variables
private let locationManager = CLLocationManager()
// MARK: - IBOutlets
#IBOutlet weak var mapView: GMSMapView!
// MARK: - IBActions
// MARK: - Life cycle
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
mapView.isMyLocationEnabled = true
}
// MARK: - Life cycle
// MARK: - GMSMapView delegate methods
func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {
reverseGeocodeCoordinate(position.target) // sending data when the mapView is not moved or pinched by the finger //
}
func reverseGeocodeCoordinate(_ coordinate: CLLocationCoordinate2D) {
let geocoder = GMSGeocoder()
geocoder.reverseGeocodeCoordinate(coordinate) { response, error in
guard let address = response?.firstResult(), let lines = address.lines else {
return
}
...
...
}
}
}
In my console, I can access Firebase latitude, longitude, and name of restaurant. I have a few print statements that I use to test that I am getting the values I needed. When I try to assign these values into an annotation.coordinate = CLLocationCoordinate2DMake(with the respective info here) I still can't get this function to print in maps.
I mainly created a function so that I can call it in viewDidLoad() so that everything I want automatically comes up when this page of the app loads.
I also created an action for a button so that when a user clicks a button on shown on the view controller, it also prints the location but THAT case also is not working. When I make coordinates I also do not know if I need ! on res.latitude and res.longitude!…. When I take it off it still does not work. A previous project I created I added annotations the same way I did here MINUS the firebase array. I created one myself with struct variables (title, latitude, longitude) in them that are later called.
import UIKit
import Firebase
import FirebaseStorage
import FirebaseDatabase
import MapKit
import CoreLocation
class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {//add last 2 delegates/protocols.conforming
//firebase refrences
var dataBaseRef: FIRDatabaseReference! {
return FIRDatabase.database().reference()
}
var storageRef: FIRStorageReference! {
return FIRStorage.storage().reference()
}
var restaurantArray = [Restaurant]()
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var segments: UISegmentedControl!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
title = "Maps"
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Main Menu", style: .plain, target: self, action: #selector(SSASideMenu.presentLeftMenuViewController))
self.locationManager.delegate = self//as soon as loaded find location--conforms to delegate
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest//best location
self.locationManager.requestWhenInUseAuthorization()//only want location when using app
self.locationManager.startUpdatingLocation()//turn on location manager..make location start looking
self.mapView.showsUserLocation = true//shows blue dot
displayRestaurants()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
fetchRestaurants()
displayRestaurants()
}
//see if you want to give it a try!!!!!!!!!!!!!!!
func fetchRestaurants(){
FIRDatabase.database().reference().child("AthensRestaurants/Restaurants").observe(.value, with: { (snapshot) in
var results = [Restaurant]()
for res in snapshot.children{
let res = Restaurant(snapshot: res as! FIRDataSnapshot)
results.append(res)
}
self.restaurantArray = results
}) { (error) in
print("error encountered dumbass")
print(error.localizedDescription)
}
}
//work here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
func displayRestaurants(){
//array already created--using a firebase array
for res in restaurantArray {
let annotation = MKPointAnnotation()
annotation.title = res.name
print(res.name)
let x = res.latitude //shows that this works and I can retrieve data!!!
print (x! as Double)
let y = res.longitude
print(y! as Double)
annotation.coordinate = CLLocationCoordinate2D(latitude: res.latitude!, longitude: res.longitude!) //Should the exclamation marks be there "!"
mapView.addAnnotation(annotation)
}
}
//A way of testing
#IBAction func test12(sender: UIButton) {
displayRestaurants() //another way i tried makiing anotations show....!!!!!!!!!
}
//below works on seperate projects
//MARK: - Location Delegate Methods
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {//didupdate is contiously called so below is continuously called
let location = locations[0]
let span = MKCoordinateSpanMake(0.01, 0.01)
let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
let region = MKCoordinateRegionMake(myLocation, span)//lat long--region that we want map to scope to--parameters is closeness zoom
self.mapView.setRegion(region, animated: true)//since we have thise we can stop updating eventually
self.locationManager.stopUpdatingLocation()
}
//check for errors
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {//should be NSError but
print("Errors:" + error.localizedDescription)
//displayRestaurants()
}
//segment changer for terrain, hybrid, and regular---just allows different types of map views
#IBAction func segChange(_ sender: Any) {
switch segments.selectedSegmentIndex {
case 0:
mapView.mapType = MKMapType.standard
break
case 1:
mapView.mapType = MKMapType.satellite
break
case 2:
mapView.mapType = MKMapType.hybridFlyover
break
default:
break
}
}
}
Currently, my code drops a pin on the user's current location. There is one small problem when I try to move the map around, because the view will shift back and be centered around that current location pin. I want the user be able to navigate the map and move it around, and if the user switches view controllers (goes to another tab) and comes back, the map will be centered around the user location pin. I have been trying to modify this code to do this, but I have not had any luck where to start.
import UIKit
import MapKit
import CoreLocation
let newPin = MKPointAnnotation()
class MapVC: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var map: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// User's location
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
if #available(iOS 8.0, *) {
locationManager.requestAlwaysAuthorization()
} else {
// Fallback on earlier versions
}
locationManager.startUpdatingLocation()
// add gesture recognizer
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(MapVC.mapLongPress(_:))) // colon needs to pass through info
longPress.minimumPressDuration = 1.5 // in seconds
//add gesture recognition
map.addGestureRecognizer(longPress)
}
// func called when gesture recognizer detects a long press
func mapLongPress(_ recognizer: UIGestureRecognizer) {
print("A long press has been detected.")
let touchedAt = recognizer.location(in: self.map) // adds the location on the view it was pressed
let touchedAtCoordinate : CLLocationCoordinate2D = map.convert(touchedAt, toCoordinateFrom: self.map) // will get coordinates
let newPin = MKPointAnnotation()
newPin.coordinate = touchedAtCoordinate
map.addAnnotation(newPin)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
map.removeAnnotation(newPin)
let location = locations.last! as CLLocation
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
//set region on the map
map.setRegion(region, animated: true)
newPin.coordinate = location.coordinate
map.addAnnotation(newPin)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Your code has several problems:
You declare a variable newPin at global scope and in mapLongPress(...) you declare a new variable let newPin = ... locally so the global newPin isn't used.
In didUpdateLocations() you first remove the (global) newPin annotation (why??) and set it again at the end of the function. Because the global newPin was never set to anything useful this will never get the desired result.
Furthermore, in didUpdateLocations() you set the map's region and center point to the current location. This is done on every location update, giving weird results when trying to pan the map.
To set center and region when the view appears, try something like that:
class MapVC: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var map: MKMapView!
let locationManager = CLLocationManager()
// class variable for the current location
var lastLocation: CLLocation?
override func viewDidLoad() {
// ...
}
override func viewDidAppear(_ animated: Bool) {
if self.lastLocation != nil {
// set center and region to current location
let center = CLLocationCoordinate2D(latitude: self.lastLocation.coordinate.latitude, longitude: self.lastLocation.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
//set region on the map
map.setRegion(region, animated: true)
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
self.lastLocation = locations.last
}
}
I am new to app development and I have been trying to create an app which will use core location manager to find the users location and then display it with mapkit. Below is the code I came up with. I haven't been able to fix it, does anyone know what I'm doing wrong? Thanks.
//
// ViewController.swift
// MapKit Test
//
// Created by TMT on 7/11/15.
// Copyright (c) 2015 TMT Inc. All rights reserved.
//
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapView.showsUserLocation = true
mapView.showsPointsOfInterest = true
mapView.delegate = self
let locationManager = CLLocationManager()
// Ask for Authorisation from the User.
locationManager.requestAlwaysAuthorization()
// For use in foreground
locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
#NSCopying var location: CLLocation! { get }
var span = MKCoordinateSpanMake(0.2
, 0.2)
var region = MKCoordinateRegion(center: location, span: span)
mapView.setRegion(region, animated: true)
var request = MKLocalSearchRequest()
request.naturalLanguageQuery = "library"
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You are not handling the delegate method for the location/map. Your code is setting up the map and location frameworks and delegate methods. You have initialized them and told the compiler you want to do something with mapkit/corelocation. So now you need to to handle the delegate methods MKMapViewDelegate, CLLocationManagerDelegate which you have included, and set to self
Place the delegate handling in addition to your code somewhere
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
//Get map location
let location = locations.last as! CLLocation
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.mapView.setRegion(region, animated: true)
//Get co ordinates
CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: {(placemarks, error)->Void in
if (error != nil) {
println("Error: " + error.localizedDescription)
return
}
if placemarks.count > 0 {
let pm = placemarks[0] as! CLPlacemark
self.displayLocationInfo(pm)
} else {
println("Error with the data.")
}
})
}
func displayLocationInfo(placemark: CLPlacemark) {
//Remove observer
self.locationManager.stopUpdatingLocation()
println(placemark.locality)
println(placemark.postalCode)
println(placemark.administrativeArea)
println(placemark.country)
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println("Error: " + error.localizedDescription)
}