Present user location swift - swift

I'm new to Swift, I want to show user location on map, I added MKMapView, and added an outlet, here is my code:
import UIKit
import Foundation
import MapKit
import CoreLocation
class ViewController: UIViewController ,CLLocationManagerDelegate{
#IBOutlet weak var map: MKMapView!
let manager = CLLocationManager()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[0]
let span: MKCoordinateSpan = MKCoordinateSpanMake(0.01,0.01)
let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
let region:MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)
map.setRegion(region, animated: true)
self.map.showsUserLocation = true
}
override func viewDidLoad() {
super.viewDidLoad()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
But when I run the app on the simulator it shows me some other location on the USA. But I'm from another place that is not even close to the USA.

Your code is fine, that's because you run it on simulator, select Debug-->Simulate Location-->Choose some other location and you will see that location on the screen

Because simulator use fake location for testing purpose. you can also change that location See in the image(https://i.stack.imgur.com/2GN7x.png).
If you run on actual device it shows your current location.

Related

Xcode Swift, Geo Location won't show where i am

any one understand why Geo location won't show me where i am, also the permissions don't work over..... I'm baffled... laptop location is fine, also the app permissions are also set, also the Allow permissions tap, box for the user won't appear either
(iv explained this all above and it won't post unless i type more stuff in the box, but could some one explain why this code doesn't work norrr does it display no errors at all, i had also checked - DEBUG - locations... still nothing
import UIKit
import MapKit
import CoreLocation
class MapScreen: UIViewController {
#IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
let regionInMeters: Double = 10000
override func viewDidLoad() {
super.viewDidLoad()
checkLocationServices()
}
func setupLocationManager() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
func centerViewOnUserLocation() {
if let location = locationManager.location?.coordinate {
let region = MKCoordinateRegion.init(center: location, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)
mapView.setRegion(region, animated: true)
}
}
func checkLocationServices() {
if CLLocationManager.locationServicesEnabled() {
setupLocationManager()
checkLocationAuthorization()
} else {
// Show alert letting the user know they have to turn this on.
}
}
func checkLocationAuthorization() {
switch CLLocationManager.authorizationStatus() {
case .authorizedWhenInUse:
mapView.showsUserLocation = true
centerViewOnUserLocation()
locationManager.startUpdatingLocation()
break
case .denied:
// Show alert instructing them how to turn on permissions
break
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
case .restricted:
// Show an alert letting them know what's up
break
case .authorizedAlways:
break
}
}
}
extension MapScreen: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
let region = MKCoordinateRegion.init(center: location.coordinate, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)
mapView.setRegion(region, animated: true)
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
checkLocationAuthorization()
}
}
Did you add the permission strings to your info.plist?
You need to add explanations for these otherwise the permission prompt won't appear, and no location updates will be send to your app.
NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription
You should also get an error for this in your console so check that as well.

Swift MapView Stuck Around User's Current Location

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 having difficulty receiving a user's current location with Swift 2.0

I have been surfing the web for methods to get a user's current location in Swift 2.0, Unfortunately none have work. Here is the code I have been working on, but it cannot work. I have been playing with the info.plist file but don't know what to add? Can anyone tell me what I am doing wrong?
import CoreLocation
class ViewController: UIViewController {
let locationManager = CLLocationManager()
override func viewDidLoad(){
super.viewDidLoad()
findMyLocation()
}
func findMyLocation() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
}
extension ViewController: CLLocationManagerDelegate {
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
for location in locations {
print("THIS IS THE LATTITUDE \(location.coordinate.latitude)")
}
locationManager.stopUpdatingLocation()
}
}
EDIT: in your didUpdateLocations function don't force stopUpdatingLocation. This function is called multiple times before your location is finalized to be shown on the map. Remove that line and you'll see that your console will print 3-5 times with your lat and long.
The recommended way to get the user location is to always check to make sure you have the permission so that if you don't you can alert the user and ask for said permission.
In your viewDidLoad()
locationManager?.requestAlwaysAuthorization()
// .AuthorizedInUse or .AuthorizedAlways depending on your app
if CLLocationManager.authorizationStatus() == .AuthorizedInUse {
locationManager?.distanceFilter = 5.0
locationManager?.requestLocation()
}
This ensures that you're requesting authorization if there is none and checking if they declined. In addition utilize this function in your CLLocationManagerDelegate
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus)
{
//Again this can be .AuthorizedAlways or .AuthorizedInUse depending
if status == .AuthorizedAlways {
locationManager?.startUpdatingLocation()
// ...
}
}
This allows the app to respond properly if they change the location permissions in the middle of using your location services after the viewDidLoad().
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
centerLocation = location
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02))
userLocationRegion = region
mainMapView.showAnnotations(mainMapView.annotations, animated: true)
self.mainMapView.setRegion(region, animated: true)
}
you need to add NSLocationWhenInUseUsageDescription or/and NSLocationAlwaysUsageDescription depends on your use case

Swift programming: Multiple Positions on Map View

I have a simple problem and I am new to IOS - I want to have multiple GPS streams coming on the same map. Please help as to how could that be done
the current code works:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad()
{
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.mapView.showsUserLocation = true
self.mapView.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationmanager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let location = locations.last
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)
self.locationManager.stopUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
{
print("Errors: " + error.localizedDescription)
}
}
but this only gives me one location.
You have a map displayed, and on that map you want to display two locations.
The first location is that of the device, so you get the co-ordinates from the device's GPS.
The second location is somebody else's position. Where are you getting their co-ordinates from? You cannot access their GPS. The app on their device must write their co-ordinates to a server somewhere. You app then reads these co-ordinates from the server and displays them using a MKPointAnnotation. There is no "GPS stream" for the app other than that for the device it is running on.
Similarly, the app on your device must write your own co-ordinates, so it can appear on their app.
If you don't have a server, you could investigate using Apple's CloudKit (for example).

How to go to user location with Mapkit (Swift)

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)
}