I am making a weather app which gets temperature info by sending current coordinates. So I am using CLLocationManager. I haven't make any HTTP request yet. I would like to see "Location Unavailable" on my screen but it is not working.
I am following a tutorial and wrote exactly same code but in tutorial it is working. In debug session, it doesn't jump to didFailwithError or didUpdateLocations methods.I added all necessary things in my
info.plist and my phone's location services are open. According to my research locationManager.startUpdatingLocation() should call automatically
these methods but when I run my app nothing appears on UI.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("you got the location")
}
//Write the didFailWithError method here:
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
cityLabel.text = "Location Unavaiable"
}
And
let locationManager = CLLocationManager ()
override func viewDidLoad() {
super.viewDidLoad()
//TODO:Set up the location manager here.
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
You are updating location too soon, in fact before you get the permission from user.
After you ask for permission
locationManager.requestWhenInUseAuthorization()
Delegate method will call
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
}
Now its time to start updates. Guarding the status is a good idea since you don't want to start updating unless user permits it.
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
guard status == .authorizedWhenInUse else { return }
manager.startUpdatingLocation()
}
Now you'll get location updates
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations)
}
Related
I am using Google Map SDK. I want to catch every moment when user changes his location, maybe from CLLocationManagerDelegate. Can anyone say which method can execute previous job?
I tried to use func locationManager( _ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) but it doesnot work well. When I run application, after 3-4 seconds this method call then If I change my location it doesnot do nothing.
Did you call startUpdatingLocation()?
Suppose that the below code is your CLLocationManager.
lazy var locationMgt: CLLocationManager = {
let manager = CLLocationManager()
manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
manager.distanceFilter = 1 // 1 meter
manager.activityType = .automotiveNavigation
manager.allowsBackgroundLocationUpdates = true
#if os(iOS)
manager.pausesLocationUpdatesAutomatically = false
#endif
manager.delegate = self
return manager
}()
Then ask for permission and start updating the location:
locationMgt.requestWhenInUseAuthorization()
// you can call startUpdatingLocation() inside this function or call it right after requestWhenInUseAuthorization()
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
locationMgt.startUpdatingLocation()
}
Then your delegate implementation:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let last = locations.last else { return }
// here user's last location is available.
}
I need to get the geographical coordinates on Mac OS. Here is my code, but an error is reported when running: domain = kclerrordomain code = 0 "(null)"
import Cocoa
import CoreLocation
let locationManager:CLLocationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
//设置定位服务管理器代理
locationManager.delegate = self
//设置定位进度
locationManager.desiredAccuracy = kCLLocationAccuracyBest //最佳定位
//更新距离
// locationManager.distanceFilter = 100
//发出授权请求
locationManager.requestAlwaysAuthorization()
if (CLLocationManager.locationServicesEnabled()){
//允许使用定位服务的话,开始定位服务更新
// print("定位开始")
}
}
extension ViewController:CLLocationManagerDelegate{
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//获取最新的坐标
let currLocation : CLLocation = locations.last! // 持续更新
print("纬度:\(currLocation.coordinate.latitude) 纬度:\(currLocation.coordinate.longitude) 海拔:\(currLocation.altitude) 水平精度:\(currLocation.horizontalAccuracy) 垂直精度:\(currLocation.verticalAccuracy) 方向:\(currLocation.course) 速度:\(currLocation.speed)")
}
func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) {
print("location manager auth status changed to:" )
switch status {
case .restricted:
print("status restricted")
case .denied:
print("status denied")
case .authorized:
print("已授权")
locationManager.startUpdatingLocation()
case .notDetermined:
print("status not yet determined")
default:
print("unknown state: \(status)")
}
}
func locationManager(_ manager: CLLocationManager,
didFailWithError error: Error) {
print( "location manager failed with error \(error)" )
}
}
enter image description here
When running application:
enter image description here
You need to add location usage description in your info.plist file. After adding your info.plist should look like this .
Add this line in viewDidLoad.
manager.startUpdatingLocation()
Then add the delegate method that updates the location.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations.last?.coordinate)
}
I am using Google maps SDK for iOS.
The isMyLocationEnabled is set to true.
Sometimes the use location updated to the right location. But sometimes the location is not updated.
I wanted to know if this option is using the original coordinates of the user? also, there is an option to update the user location? ) I am talking about the blue point.
May be this can help:
import Foundation
import CoreLocation
class Location: NSObject {
static let shared = Location()
var locationManager = CLLocationManager()
func locationManagerSetup() {
// Ask for Authorisation from the User.
locationManager.requestAlwaysAuthorization()
// If location services is enabled get the users location
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestLocation()
locationManager.startUpdatigLocation()
}
}
}
extension Location: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first {
// do something
manager.stopUpdatingLocation()
}
else {
manager.requestLocation()
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
manager.requestLocation()
}
// If we have been deined access give the user the option to change it
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if(status == CLAuthorizationStatus.denied) {
// do something
}
}
}
My question is very simple. I would like to display an error message i.e. "Cannot find iBeacon" if iBeacon monitoring fails, after calling startSearchingForSessions via a button press after being called in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager = CLLocationManager()
if self.locationManager.responds(to: #selector(CLLocationManager.requestWhenInUseAuthorization)) {
self.locationManager.requestWhenInUseAuthorization()
}
self.locationManager.delegate = self
self.locationManager.pausesLocationUpdatesAutomatically = false
let uuid = UUID(uuidString: "869A6E2E-AE14-4CF5-8313-8D6976058A7A")
self.beaconRegion = CLBeaconRegion(proximityUUID: uuid!, identifier: "com.dejordan.myapp"
startSearchingForSessions()
}
func startSearchingForSessions() {
// Start looking for the beacons with that UUID and Identifier.
self.locationManager.startMonitoring(for: self.beaconRegion)
self.locationManager.startRangingBeacons(in: self.beaconRegion)
self.locationManager.startUpdatingLocation()
}
And handling the found beacons thusly:
// Required by the Location Manager.
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
self.locationManager.startRangingBeacons(in: self.beaconRegion)
}
func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
if state == CLRegionState.outside {
print("Cannot Find Beacon")
}
}
// Required by the Location Manager.
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
self.locationManager.stopRangingBeacons(in: self.beaconRegion)
}
// This is called if any beacons are found.
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
var result = Array<CLBeacon>()
for beacon in beacons {
result.append(beacon)
}
foundBeacons = result
// If we found any, we need to see
// what class they belong to based on information
// from Parse.
self.identifyFoundBeacons()
// We can stop looking for beacons now.
self.locationManager.stopMonitoring(for: self.beaconRegion)
self.locationManager.stopRangingBeacons(in: self.beaconRegion)
self.locationManager.stopUpdatingLocation()
}
I have implemented the delegate error methods in an attempt to find where this occurs but thus far in navigating the mounds of documentation on iBeacon I have come up fruitless.
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Location manager failed: \(error.localizedDescription)")
}
func locationManager(_ manager: CLLocationManager, monitoringDidFailFor region: CLRegion?, withError error: Error) {
print("Failed monitoring region: \(error.localizedDescription)")
}
Thank you!
If you simply want to know when beacons are not detected (vs. when there was a low-level failure to look for beacons), then simply use the following delegate method:
public func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
if state == CLRegionState.outside {
print("Cannot find beacon")
}
}
Interestingly enough, didRangeBeacons in the delegate method
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion)
gets called with an empty array of [CLBeacon]s, wherein I can use the beacons array size to determine whether or not any beacons were found.
Not what I expected, but this has solved my problem!
For some reason Xcode thinks I'm not implementing didFailWithError method of the CLLocationManagerDelegate protocol
I fail to see what I'm doing wrong, as I literally copied from another SO post that said this didFailWithErrormethod was updated for Swift 3. So I don't understand why Xcode thinks I'm not implementing didFailWithError
Any insight would be greatly appreciated!
Code
class OptionsViewController: UIViewController,
CLLocationManagerDelegate {
var locationManager: CLLocationManager = CLLocationManager()
override func viewDidLoad() {
//Ask user for location
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
//Use users current location if no starting point set
if CLLocationManager.locationServicesEnabled() {
if CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse
|| CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedAlways {
locationManager.requestLocation()
}
else{
locationManager.requestWhenInUseAuthorization()
}
}
else{
//Alert user to open location service, bra bra bra here...
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("error:: \(error)")
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
print("didChangeAuthorization")
if status == CLAuthorizationStatus.authorizedWhenInUse
|| status == CLAuthorizationStatus.authorizedAlways {
locationManager.requestLocation()
}
else{
//other procedures when location service is not permitted.
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("Did update location called")
// let locValue:CLLocationCoordinate2D = manager.location!.coordinate
// print("locations = \(locValue.latitude) \(locValue.longitude)")
if locations.first != nil {
print("location:: (location)")
}
}
Aaaandd I realized it's b/c I needed to use an Error of a specific type (specifically Swift.Error)
This is the right method declaration for didFailWithError:
func locationManager(_ manager: CLLocationManager, didFailWithError error: Swift.Error) {