Getting location using another class not working when calling function swift - ios

I was using the ViewController class before to get the users updates but now when expanding the application i needed to move it to another class that simply handles all the location updates. Here is the code that i am using now:
class ViewController: UIViewController, UITextFieldDelegate {
#IBAction func pickMeUpButton(sender: AnyObject) {
sendPushNotificationController().sendPushNotification("sendRequest",userLat: defaults.stringForKey("userLat")!, userLong: defaults.stringForKey("userLong")! )
}
#IBOutlet var numberForPickup: UITextField!
let defaults = NSUserDefaults.standardUserDefaults()
override func viewDidLoad() {
super.viewDidLoad()
self.numberForPickup.delegate = self
getLocationController().initLocation()
}
So i made another class called getLocationController with an init function that should start the location updates. Here is the code:
class getLocationController: UIViewController, CLLocationManagerDelegate {
var locationManager: CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func initLocation(){
print("Im in here")
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation) {
print("In location")
if UIApplication.sharedApplication().applicationState == .Active {
print("App in Foreground")
}else {
let Device = UIDevice.currentDevice()
let iosVersion = Double(Device.systemVersion) ?? 0
let iOS9 = iosVersion >= 9
if iOS9{
locationManager.allowsBackgroundLocationUpdates = true;
locationManager.pausesLocationUpdatesAutomatically = false;
}
//let iOS7 = iosVersion >= 7 && iosVersion < 8
print("App is backgrounded. New location is %#", newLocation)
}
}
}
Now the print in initLocation is printed but not the print in didUpdateLocations. I used the very same code in ViewController class and it worked perfectly fine. Now when i am trying to move it to another class that is now really a view on the phone but simply a helper class its not working. Any ideas why?

I don't see you assigning the getLocationController to a variable anywhere in the ViewController. That means the getLocationController would go out of scope and be destroyed, wouldn't it? That would explain why the callback didUpdateToLocation isn't called.
Try:
class ViewController: UITextFieldDelegate {
#IBAction func pickMeUpButton(sender: AnyObject) {
sendPushNotificationController().sendPushNotification("sendRequest",userLat: defaults.stringForKey("userLat")!, userLong: defaults.stringForKey("userLong")! )
}
#IBOutlet var numberForPickup: UITextField!
let defaults = NSUserDefaults.standardUserDefaults()
var glc:getLocationController // is this how it is in Swift?!
override func viewDidLoad() {
super.viewDidLoad()
self.numberForPickup.delegate = self
glc = getLocationController()
glc.initLocation()
}

Related

Making an app using swift that gets user's location

I ran my code for getting the user's location and this is the error I get. Can someone please help me figure it out?
My code is as follows:
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var citybtn: UIButton!
#IBOutlet weak var citylbl: UILabel!
let locationManager = CLLocationManager()
var currentLocation : CLLocation!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Used to start getting the users location
//let locationManager = CLLocationManager()
// For use when the app is open
//locationManager.requestAlwaysAuthorization()
// If location services is enabled get the users location
//if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest // You can change the locaiton accuary here.
locationManager.requestWhenInUseAuthorization()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
locationAuthStatus()
}
func locationAuthStatus() {
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
currentLocation = locationManager.location
print(currentLocation.coordinate.latitude)
print(currentLocation.coordinate.longitude)
} else {
locationManager.requestWhenInUseAuthorization()
locationAuthStatus()
}
}
#IBAction func buttonpresses(_ sender: Any) {
}
}
sounds like you did not enable the location update capability of your target:
choose target
select capabilities
in Background Modes, tick Location updates

App crashes when dismissing view controller

I've a simple ViewController that displays my current location coordinates.
Everything is working properly, but when I dismiss the ViewController, the app crashes without any specific error log.
The class code goes like this:
import UIKit
class LocationViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate, UIPopoverPresentationControllerDelegate {
// General objects
#IBOutlet var closeButton: UIButton!
#IBOutlet var latitudeLabel: UILabel!
#IBOutlet var longitudeLabel: UILabel!
#IBOutlet var infoButton: UIButton!
// Global variables
var location: CLLocationManager? = CLLocationManager()
var geocoder = CLGeocoder();
var placemark = CLPlacemark();
var hasPin: Bool = false;
override func viewDidLoad() {
super.viewDidLoad()
// Ask for Authorisation from the User.
location?.requestAlwaysAuthorization();
// For use in foreground
location?.requestWhenInUseAuthorization();
getCurrentLocation();
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func closeButton(_ sender: AnyObject) {
self.dismiss(animated: true, completion: {
print("dismissing locationViewController");
self.location = nil;
});
}
#IBAction func infoButton(_ sender: AnyObject) {
// TODO
}
// MARK: - General functions
func getCurrentLocation() -> Void {
if (CLLocationManager.locationServicesEnabled()) {
location?.delegate = self;
location?.desiredAccuracy = kCLLocationAccuracyBest;
location?.startUpdatingLocation();
}
}
// MARK: - CLLocationManagerDelegate
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("ERROR = \(error)");
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// Gets the user coordinates
let locValue:CLLocationCoordinate2D = manager.location!.coordinate;
USER_LATITUDE = locValue.latitude;
USER_LONGITUDE = locValue.longitude;
longitudeLabel.text = "\(USER_LONGITUDE)";
latitudeLabel.text = "\(USER_LATITUDE)";
location?.stopUpdatingLocation()
}
Does anyone have any clue why this happens?
No error log is prompted that's what makes me even more confused.
First I thought I had to set the location variable to be optional and then set it to nil when I dismiss the VC but the crash is still happening.
Crashlytics says that the App crashes inside the LocationViewController line 0 , which is in fact weird.
I call this ViewController, from a button click inside another VC like this:
#IBAction func locationButton(_ sender: AnyObject) {
let storyboard = UIStoryboard(name: "Main", bundle: nil);
let viewController = storyboard.instantiateViewController(withIdentifier: "locationVC");
self.present(viewController, animated: true, completion: nil);
}
I'm using Swift3 with the latest Xcode Beta Version on iOS 10.
Thanks
Replace this:
var location: CLLocationManager? = CLLocationManager()
With this:
let location = CLLocationManager()
Change all code as necessary (this is no longer an Optional so there is nothing to unwrap) and delete the line that tries to set it to nil.
If you are worried that the location manager might be trying to get your location when you dismiss, then implement viewWillDisappear and tell it to stop updating.
You need to add the privacy entry in Info.plist and also request authorization to use location services. A good overview can be found here: http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/

My simple map project doesn't get & show my location in simulator

I am using XCode v7.2.1, Simulator v9.2 .
I have a UIViewController which shows a map & is supposed to get my location & show it on map:
import UIKit
import MapKit
class LocationVC: UIViewController, MKMapViewDelegate {
#IBOutlet weak var map: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
map.delegate = self
}
override func viewDidAppear(animated: Bool) {
if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse {
map.showsUserLocation = true
} else {
locationManager.requestWhenInUseAuthorization()
}
}
}
I have added the NSLocationWhenInUseUsageDescription in info.plist as shown below:
I have also selected the Debug -> Location -> Custom Location ... and set the longitude & latitude of Helsinki, Finland as shown below:
When I run my app, the map is shown, however it doesn't get my location. Why? (I mean I don't see the blue point in anywhere of the map).
===== UPDATE ====
I also tried this when my app is running, however it doesn't help either.
you are requesting the user's location, but not actually doing anything with the response. become the delegate of the location manager and respond to the authorization change.
this code works for me on 7.2.1 (after selecting "Apple" in Debug -> Location):
import UIKit
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var map: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse {
map.showsUserLocation = true
} else {
locationManager.requestWhenInUseAuthorization()
}
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
guard status == .AuthorizedWhenInUse else { print("not enabled"); return }
map.showsUserLocation = true
}
}
I agree with #Casey 's answer,but sometimes you need to do a little more with CLLocationManagerDelegate method.
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first {
//reset mapView's center in case your custom location was wrong.
map.centerCoordinate = location.coordinate
//mannual call show annotations to avoid some bugs
map.showAnnotations(map.annotations, animated: true)
}
}
you just have to add
locationManager.delegate = self
mapView.showsUserLocation = true

IOS 8 swift CoreLocation

Im learning Xcode 6.3 and swift and following a book from apress Beginning Xcode with swift, in chapter 4 when doing the first tab for the location tracker it shows nothing at all and I'm confused. The code for the first tab is this
import UIKit
import CoreLocation
class TrackViewController: UIViewController, CLLocationManagerDelegate {
var locationManager: CLLocationManager!
#IBOutlet weak var locationText: UITextView!
#IBOutlet weak var toggleSwitch: UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
// 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.
}
#IBAction func changeToggle(sender: UISwitch) {
if toggleSwitch.on {
self.locationText.text = " "
if (CLLocationManager.locationServicesEnabled() == false) {
self.toggleSwitch.on = false
}
if locationManager == nil {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.distanceFilter = 10.0
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.requestWhenInUseAuthorization()
UIApplication.sharedApplication().cancelAllLocalNotifications()
NSLog("location is on supposely")
}
locationManager.startUpdatingLocation()
} else {
if locationManager != nil {
locationManager.stopUpdatingLocation()
}
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var location: CLLocation = locations[locations.endIndex - 1] as! CLLocation
self.locationText.text = location.description
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
locationText.text = "failed with error \(error.description)"
}
}
I have activated in the simulator the location services and in info.plist added the NSLocationWhenInUsageDescription and the Privacy - Location..., but nothing happens when toggling the switch I get no feedback that something is on. Any help??

Trying to find users location in Xcode with Swift on starting the app but having optional error?

I'm attempting to have the app find the user's location once the app has been started. However, I continually find an error in the viewDidLoad method as I try to requestWhenInUseAuthorization and I receive the following error:
fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)
I would be really grateful if anyone could help me find a solution to this problem. Thanks!
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
var lastLocation = CLLocation()
var locationAuthorizationStatus:CLAuthorizationStatus!
var window: UIWindow?
let locationManager: CLLocationManager!
var seenError : Bool = false
var locationFixAchieved : Bool = false
var locationStatus : NSString = "Not Started"
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.initLocationManager()
}
override func viewDidLoad() {
super.viewDidLoad()
if (CLLocationManager.locationServicesEnabled()) {
seenError = false
locationFixAchieved = false
locationManager = CLLocationManager()
self.initLocationManager()
locationManager.requestWhenInUseAuthorization()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
mapView.showsUserLocation = true
mapView.delegate = self
self.mapView.setUserTrackingMode(MKUserTrackingMode.Follow, animated: true);
}
// Location Manager helper stuff
func initLocationManager() {
locationManager.requestWhenInUseAuthorization()
}
// Location Manager Delegate stuff
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
locationManager.stopUpdatingLocation()
if ((error) != nil) {
if (seenError == false) {
seenError = true
print(error)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Your didload method is getting called before the didAppear method. Therefore, your location manager is not initialized yet. So you need to initialize it before using it.

Resources