i have problem with getting my location with CLLocationDelegate.
i created new subclass of UIView and work well, but when i created subclass of NSObject, CLLocationDelegate not called. I can find where is problem.
here is my code:
import UIKit
import CoreLocation
class LocationData: NSObject, CLLocationManagerDelegate {
var locationManager : CLLocationManager = CLLocationManager()
override init() {
super.init()
if self.locationManager.respondsToSelector(Selector("requestAlwaysAuthorization")) {
self.locationManager.requestWhenInUseAuthorization()
}
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.distanceFilter = 50
self.locationManager.startUpdatingLocation()
println("init LocationData")
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println(error.description)
}
func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) {
println("updated")
}
}
Thanks!
Your code is fine! But when instantiating the class, you need to do like this:
import UIKit
class ViewController: UIViewController {
let LocationData: LocationData = LocationData() //<- here is the secret to works!!!
override func viewDidLoad() {
super.viewDidLoad()
}
I also suggest that you change your init to something like this:
override init() {
super.init()
let authorizationStatus: CLAuthorizationStatus = CLLocationManager.authorizationStatus()
if authorizationStatus == .notDetermined {
locationManager.requestWhenInUseAuthorization()
}
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.distanceFilter = 50
self.locationManager.startUpdatingLocation()
print("init LocationData")
}
And don't forget to add NSLocationWhenInUseUsageDescription in the info.plist project.
Related
I'm trying to make a maps application using Mapkit. but I can't seem to access the blue dot when i run the app on the simulator. i'm still new to Mapkit and any tips would be really appreciated. here's my code. p.s: i'm coding using Swift 4.2 and Xcode 11
import UIKit
import MapKit
import CoreLocation
class mapViewController: UIViewController {
let locationManager = CLLocationManager()
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
locationManager.requestWhenInUseAuthorization()
checkLocationServices()
}
func setupLocationManager() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
func centerViewOnUserLocation() {
if let location = locationManager.location?.coordinate {
let region = MKCoordinateRegion.init(center: location, latitudinalMeters: 10000, longitudinalMeters: 10000)
mapView.setRegion(region, animated: true)
}
}
func checkLocationServices() {
if CLLocationManager.locationServicesEnabled() {
setupLocationManager()
checkLocationAuthorization()
} else {
}
}
func checkLocationAuthorization() {
let pin = MKPointAnnotation()
switch CLLocationManager.authorizationStatus() {
case .authorizedWhenInUse:
mapView.showsUserLocation = true
mapView.addAnnotation(pin)
break
case .denied:
break
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
break
case .restricted:
break
case .authorizedAlways:
break
}
}
}
extension mapViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// we'll be back
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
//we'll be back
}
}
Check Simulator menu: Features > Location > Custom Location
Is there any way to reduce the number of times the locationManager updates? Currently is updated over 100 times in 30 seconds! My app collects the coordinates of the user and pushes this to a database, But I'm collecting too many coordinates.
Can I reduce the number of times the app updates user location?
func locationManager(_ manager: CLLocationManager, didUpdateLocations
locations: [CLLocation]) {
let lat = LocationManager.sharedInstance.location.coordinate.latitude
let long = LocationManager.sharedInstance.location.coordinate.longitude
}
Use CLLocationManager's distanceFilter property.
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
// MARK: - Variables
let locationManager = CLLocationManager()
// MARK: - IBOutlets
#IBOutlet weak var mapView: MKMapView!
// MARK: - IBAction
// MARK: - Life cycle
override func viewDidLoad() {
super.viewDidLoad()
/* delegate */
mapView.delegate = self
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
/* checking location authorization */
checkLocationAuthorizationStatus()
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
locationManager.allowsBackgroundLocationUpdates = true
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = 20.0 // 20.0 meters
}
}
// MARK: - Authorization
func checkLocationAuthorizationStatus() {
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse || CLLocationManager.authorizationStatus() == .authorizedAlways {
} else {
locationManager.requestWhenInUseAuthorization()
}
}
// MARK: - CLLocationManager delegate methods
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let mostRecentLocation = locations.last else {
return
}
print(mostRecentLocation)
}
}
I'm new to swift - currently, my current location is only output once in the console when I first call setupLocationManager() on init through override func awakeFromNib(). When I want it to output my new location by calling locationManager.startUpdatingLocation() when I click a button with the method updateLocation(), it prints an error. Any way to fix this? All help is appreciated.
import Cocoa
import CoreLocation
class StatusMenuController: NSObject, CLLocationManagerDelegate {
#IBOutlet weak var statusMenu: NSMenu!
let statusItem = NSStatusBar.system().statusItem(withLength: NSVariableStatusItemLength)
var locationManager:CLLocationManager!
var currentLocation:CLLocation?
#IBAction func quitClicked(_ sender: NSMenuItem) {
NSApplication.shared().terminate(self)
}
#IBAction func updateClicked(_ sender: NSMenuItem) {
updateLocation()
}
func updateLocation() {
locationManager.startUpdatingLocation()
}
override func awakeFromNib() {
statusItem.menu = statusMenu
let icon = NSImage(named: "statusIcon")
icon?.isTemplate = true
statusItem.image = icon
statusItem.menu = statusMenu
setupLocationManager()
}
func setupLocationManager(){
locationManager = CLLocationManager()
locationManager?.delegate = self
//self.locationManager?.requestAlwaysAuthorization()
locationManager?.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager?.startUpdatingLocation()
}
// Below method will provide you current location.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if currentLocation == nil {
currentLocation = locations.last
locationManager?.stopMonitoringSignificantLocationChanges()
let locationValue:CLLocationCoordinate2D = manager.location!.coordinate
print(locationValue)
locationManager?.stopUpdatingLocation()
}
}
// Below Method will print error if not able to update location.
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Error")
}
}
There is an if condition in the code which suspends updating the location after the location is set once (if currentLocation == nil). You have to reset currentLocation to nil before restarting the manager.
#IBAction func updateClicked(_ sender: NSMenuItem) {
currentLocation = nil
updateLocation()
}
I am trying to get the users latitude and longitude.
import Foundation
import CoreLocation
class locationModule: NSObject, CLLocationManagerDelegate {
var locationManager = CLLocationManager()
func getLocation() {
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
var location: CLLocationCoordinate2D = (manager.location?.coordinate)!
print(location.latitude)
print(location.longitude)
}
}
This is code is in a seperate Swift file, So I need getLocation() to be able to call func locationManager, how would I call the locationManager function from the getLocation() function.
Your code is fine, but it's not being called, probably because you didn't add the key to your Info.plist.
For your code, add NSLocationAlwaysUsageDescription to your Info.plist, with a value such as All your base are belong to us, so I use your location whenever I want. as the String value. Then just start your locationManager somewhere like func applicationDidBecomeActive(application: UIApplication) like this:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var locMod:locationModule?
func applicationDidBecomeActive(application: UIApplication) {
if ( locMod == nil )
{
locMod = locationModule()
}
locMod?.getLocation()
}
The first time, you will see the prompt, then you will see the location being logged.
FYI, here's how I organized the locationModule:
class locationModule: NSObject, CLLocationManagerDelegate {
var locationManager = CLLocationManager()
internal func getLocation() {
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
// MARK : CLLocationManagerDelegate protocol
#objc
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
for location in locations {
print("\(location.coordinate.latitude), \(location.coordinate.longitude)")
}
}
}
So, I am trying to get my Location inside a function of my ViewController.swift.
The Code I use works when i try it like this:
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
var manager : CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyHundredMeters
manager.requestAlwaysAuthorization()
manager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var locValue : CLLocationCoordinate2D
locValue = manager.location.coordinate
println("Coordinates = \(locValue.longitude) + \(locValue.latitude)")
manager.stopUpdatingLocation()
}
But what I am trying to do is get it while pressing a button which toggles a function:
var manager : CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyHundredMeters
manager.requestAlwaysAuthorization()
manager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var locValue: CLLocationCoordinate2D = manager.location.coordinate
println("locations = \(locValue.longitude) \(locValue.latitude)")
manager.stopUpdatingLocation()
}
#IBAction func refresh() {
getWeatherData()
refreshButton.hidden = true
acitivityIndicatorView.hidden = false
acitivityIndicatorView.startAnimating()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func getWeatherData() -> Void {
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [AnyObject]!) {
var locValue: CLLocationCoordinate2D = manager.location.coordinate
println("locations = \(locValue.longitude) \(locValue.latitude)")
manager.stopUpdatingLocation()
While using a breakpoint i realized it gets to func locationManager but it jumps to the end of my getweatherdata() function.
I can't see why it doesn't work.
What you are doing is not possible. Inly thing you can do is call manager.startUpdatingLocation() inside refresh() and wait till didUpdateLocations get called with the updated location data.
#IBAction func refresh() {
manager.startUpdatingLocation()
refreshButton.hidden = true
acitivityIndicatorView.hidden = false
activityIndicatorView.hidesWhenStopped = true
acitivityIndicatorView.startAnimating()
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var locValue: CLLocationCoordinate2D = manager.location.coordinate
println("locations = \(locValue.longitude) \(locValue.latitude)")
manager.stopUpdatingLocation()
refreshButton.hidden = false
acitivityIndicatorView.stopAnimating()
}