Getting and Managing Location Updates

As long as the players are more than 10 meters away from the place where the text is drawn, they should see a screen showing the distance to that location. Using this information, they have to find the text’s location. As soon as the players get within 10 meters of the text, they will see the AR view on their screen and they can search for the text.

As we did in the previous chapters, let’s add a class that manages the location updates from the GPS sensor. Use the shortcut N to add a new Cocoa Touch class, call it LocationProvider, and make it a subclass of NSObject.

Import CoreLocation and the LogStore logging library into LocationProvider.swift:

 import​ ​UIKit
 import​ ​CoreLocation
 import​ ​LogStore

Next, add or change the highlighted code that initializes and sets up a location manager:

»class​ ​LocationProvider​: ​NSObject​, ​CLLocationManagerDelegate​ {
 
»private​ ​let​ locationManager: ​CLLocationManager
 
»override​ ​init​() {
»
» locationManager = ​CLLocationManager​()
»
»super​.​init​()
»
» locationManager.delegate = ​self
» locationManager.​requestWhenInUseAuthorization​()
» }
 }

If you’ve worked through the other chapters, this code should be quite familiar to you. The location manager delivers the location updates to its delegate. We’ll display the distance to the text location only when the app is running. This means we need to ask the user only for When in Use authorization.

Note that we added the protocol CLLocationManagerDelegate to the class declaration because the location provider acts as the delegate for the location manager.

The call locationManager.requestWhenInUseAuthorization triggers the request shown to the users. To react to the user’s selection, add the following method to LocationManager:

 func​ ​locationManager​(_ manager: ​CLLocationManager​,
  didChangeAuthorization status: ​CLAuthorizationStatus​) {
 
 switch​ status {
 case​ .authorizedWhenInUse:
 printLog​(​"success"​)
 default​:
 // ToDo: implement
 break
  }
 }

This method prints success to the console when the user grants the request. Implement the other case as an exercise. You can find the other cases when you open the developer documentation with the shortcut 0 and search for CLAuthorizationStatus. Think about what the app might look like without access to the current location. If you don’t know how to make it usable in this case, inform the users of that.

Unfortunately, you can’t ask for the authorization again. The users need to open the iOS settings and update the authorization themselves if they change their mind. You can redirect the user to the app settings with the following code:

 UIApplication​.shared.​open​(​URL​(string: ​UIApplication​.openSettingsURLString)!)

The property locationManager is defined as private, which means that it is accessible only from within this class. Other classes don’t need to know where the location updates originate from. To make it possible to start and stop the location events from outside of this class, add the following code to LocationProvider:

 func​ ​start​() {
  locationManager.​startUpdatingLocation​()
 }
 
 func​ ​stop​() {
  locationManager.​stopUpdatingLocation​()
 }

These methods call the corresponding methods on locationManager.

Pro Tip: Hide Implementation Detail

images/aside-icons/tip.png

Hide implementation details from other parts of the code. This way, you can change how the class or structure works without breaking the app. Try to build the interface of your classes and structures so they don’t need to change when the implementation changes.

In Chapter 1, Drawing on Maps, we used a closure to propagate the location updates to the user interface. In this chapter, we’ll use Combine for this task. Import Combine into LocationProvider.swift:

 import​ ​UIKit
 import​ ​CoreLocation
 import​ ​LogStore
 import​ ​Combine

Next, add the highlighted property below the locationManager property:

 private​ ​let​ locationManager: ​CLLocationManager
»@Published​ ​var​ lastLocation: ​CLLocation​?

With the @Published property wrapper, we create a publisher for that property. Whenever the location manager delivers a new location, we assign it to this property. Add the following method to LocationProvider:

 func​ ​locationManager​(_ manager: ​CLLocationManager​,
  didUpdateLocations locations: [​CLLocation​]) {
 
  lastLocation = locations.last
 }

To make this code work, we need to add the usage description into Info.plist. Open Info.plist and add an entry with the key NSLocationWhenInUseUsageDescription and the text “The location will be used to show the distance to a stored location.” That’s all for the LocationProvider. Next, we’ll implement the view controller that will show the distance to the text location.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.100.120