While working with xCode 7 in swift, i can´t range beacons in background only when the app is in foreground.
My core location didRangeBeacons is that follows
func locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion) {
let near = beacons[0]
print(near)
}
The didFinishLaunchingWithOptions is the one that follows. Location manager object is global to the class.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
if(locationManager.respondsToSelector("requestAlwaysAuthorization")) {
locationManager.requestAlwaysAuthorization()
}
locationManager.delegate = self
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.startMonitoringForRegion(region)
locationManager.startRangingBeaconsInRegion(region)
locationManager.startUpdatingLocation()
return true
}
In my .plist file i have the NSLocationAlwaysUsageDescription set and in the capabilities i have the background modes on with the location updates and uses bluetooth LE accessories checked.
Also i have the CoreLocation Framework added to the project.
Would very much appreciate the help or some URL´S that may help. Thank you.
I managed to solve that. Core location adds the allowsBackgroundLocationUpdates witch defaults to no. You can see the video (https://developer.apple.com/videos/wwdc/2015/?id=714).
Related
I'm relatively new to Swift and self-taught, and I'm currently having issues with recording Visits using a swift app.
Relevant parts of AppDelegate:
import CoreLocation
class AppDelegate: NSObject, UIApplicationDelegate {
let locationManager = LocationManager.shared
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
locationManager.startMonitoringLocationVisits()
print("AppDelegate just ran")
return true
}
}
Relevant parts of LocationManager:
import CoreLocation
class LocationManager : NSObject, ObservableObject, CLLocationManagerDelegate {
static let shared = LocationManager()
//New location manager
var locationManager = CLLocationManager()
//Seconds between location acquisitions in background
var locationInterval = 120
override init() {
super.init()
locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.activityType = .fitness
self.locationManager.allowsBackgroundLocationUpdates = true
}
}
func locationManager(_ manager: CLLocationManager, didVisit visit: CLVisit) {
print("received a visit")
//Code that sends a notification every time a visit is recorded
print("attempting to save visit")
self.saveVisit(visit: visit) //Code that saves details from the visit to CoreLocation
}
public func startMonitoringLocationVisits() {
locationManager.startMonitoringVisits()
}
The app compiles and runs fine on my device (iPhone 13 pro running iOS 16) but never records any visits. I've tried an example app I found online and that works correctly on my device, so it must be an issue with my code, but I can't figure out what. I also have a background refresh task recording location coordinates every few minutes in the same app that works correctly, and I'm hesitant to start radically changing location manager code to debug the Visits feature since I'm worried I would break the background task feature. Any advice or direction is appreciated!
I've already followed this tutorial in both ways, by implementing the #available directives and by removing code/files, but still a black screen displays. Unless I'm missing something I think I've done both things properly.
This is the current status in the way of removing files/code:
SceneDelegate.swift deleted.
AppDelegate.swift like this:
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
}
And finally Info.plist like this:
What am I missing so the screen still displays black due to the program not supporting versions previous to iOS 13?
Add this code in your AppDelegate file in didFinishLaunchingWithOptions method
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
if #available(iOS 13.0, *) {
} else {
let rootVC = //Initialize root controller
self.window?.rootViewController = rootVC
self.window?.makeKeyAndVisible()
}
return true
}
I guide you step by step.
1st remove SceneDelegate file from the project.
Add var window: UIWindow? to AppDelegate.
Remove below func from AppDelegate.
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
Remove Application Scene Manifest key from Info.plist file.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let navigation = UINavigationController(rootViewController: ViewController())
let frame = UIScreen.main.bounds
window = UIWindow(frame: frame)
window!.rootViewController = navigation window!.makeKeyAndVisible()
return true
}
Extra
Add below delegate methods in AppDelegate file, below didFinishLaunchingWithOptions
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
Currently in my app I'm fetching the user coordinates. I need to keep this coordinates always updated so I placed the location code in app delegate in didFinishLaunchingWithOptions. The code is:
let location = CLLocationManager()
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
location.delegate = self
location.desiredAccuracy = kCLLocationAccuracyBest
location.requestAlwaysAuthorization()
location.requestWhenInUseAuthorization()
return true
Then, in the same AppDelegate.swift I implemented the delegate method to catch every location update as following:
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations)
}
The thing is that I'm always receiving nil values.
It is important to mention that I'm running the app over the simulator but in debug menu I simulate bicycle ride or even the Apple location.
What am I missing?
Of course I edited the plist with NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription
manager.startUpdatingLocation()
I am new to the tvOS platform. I want to know how to get current location latitude and longitude at the application launch. I am writing this code to get the location coordinate.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.delegate = self
self.locationManager.requestLocation()
self.locationManager.requestWhenInUseAuthorization()
}
return true
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
locationValue = manager.location?.coordinate
print("=========didUpdateLocations==========Latitude>>>>>",locationValue.latitude)
print("=========didUpdateLocations==========Longitude>>>>",locationValue.longitude)
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("localizedDescription===================",error.localizedDescription)
}
This code provide the coordinate after the view controller loads. While my requirement is that I want to get coordinate before loading the view controller. Can i enable location service programmatically for single application?
The location service determines the location on demand and it requires time to do so. For that reason, it only offers an asynchronous interface.
So there is now way you can retrieve the location before the view controller is shown. You will need to write your app such that it can display the view controller without knowing the location and later update the screen when the location information is available.
It requires setting the app information and grants, see the discussion Here
I also found the solution and explanation for this identical question Here
I am trying to determine in AppDelegate if user set location permissions for application to "Never". My app always crashing if not getting location.
my code in AppDelegate is:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//location
var manager = CLLocationManager()
if CLLocationManager.authorizationStatus() == .Restricted
|| .authorizationStatus() == .Denied {
manager.requestWhenInUseAuthorization()
manager.requestAlwaysAuthorization()
}
}
Can anyone help me to resolve this issue?
The best article about CoreLocation and requesting authorization is here: http://nshipster.com/core-location-in-ios-8/
A couple of points:
Only request authorization if the current status is .NotDetermined
If the current status is .Denied, then you can post an alert asking
the user to go into settings and turn on location services, but calling either of the request methods will do nothing.
Remember to put in a NSLocationUsageDescription in your plist! (I
forget this routinely.)