What’s New With Privacy?
Learn about the new privacy features introduced in iOS 14.5, including accessing the new privacy-focused image picker, handling location permissions and more. By Renan Benatti Dias.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
What’s New With Privacy?
30 mins
- Getting Started
- Understanding Library Permissions and the New Restricted API
- Working with Limited Libraries
- Designing for Limited Libraries
- Adding the New PHPickerViewController
- Working with Location Services
- Designing for Location Privacy
- Adding Location Data
- Conforming to CLLocationManagerDelegate
- Showing User Location on Map
- Adding When in Use Description to Info.plist
- Handling Denied Authorization
- Handling accuracy
- Understanding iOS 14’s New Clipboard Prompt
- Understanding the New Camera and Microphone Indicators
- iOS 14.5’s New App Tracking Transparency
- Requesting Permission to Track the User Activity
- Retrieving the Advertising Identifier
- Where to Go From Here?
Working with Location Services
Just like photos, the user’s location is a quite personal piece of data that not all users want to share with every app. Starting with iOS 14, apps have to ask permission to access the user’s location and also how often they can access this data. Instead of just allowing or denying access to their location, users can now choose to Always Allow or Allow While Using App. They can also choose to Allow Once. That way, iOS asks permission the next time the user opens the app.
Users can also decide the extent of the accuracy of their location data. Instead of giving a precise location, iOS gives an approximate location of the user, already enough for features that look for locations around them.
This helps give the user control over when and how the app accesses their location. The user has full control over this, with the ability to change each app authorization and accuracy whenever they want, using the Settings app.
Designing for Location Privacy
Some apps, such as Apple Maps, require full accuracy for some features to work properly. Precise location affects the estimated time of arrival, relevant places and even navigation.
These apps have to adapt their UI and features to give an optimal experience, either for when the user prefers using precise location or not.
While using precise location, Apple Maps uses a pulsating blue dot on the map to show the user’s location.
With precise location off, this dot turns into a shaded circular area, displaying a general location of the user. Also, notice the text at the top of the view indicating precise location is off.
These UI changes indicate the state of accuracy on Apple Maps.
Other changes were made to features that require precise location. While precise location is off, Apple Maps Favorites don’t show an estimated time of arrival (ETA). Calculating an ETA requires precise data. An approximate location could compromise an ETA.
While designing your app, you must keep in mind users might not want to share their precise location. Giving the user power to choose makes them feel safer and in control of their data.
Adding Location Data
Now that you know how important it is to be transparent with the user’s location data, it’s time to add location to the picture. To do this, you’ll add a button for asking authorization to access the user’s location and to show a map displaying their location.
Open NewPictureStore.swift and add the following under hasLocation
:
private lazy var locationManager: CLLocationManager = {
let manager = CLLocationManager()
manager.delegate = self
return manager
}()
This code adds a lazy property of CLLocationManager
you’ll use to track the user’s location. Xcode triggers a compiler error because NewPictureStore
does not conform to CLLocationManagerDelegate
. You’ll fix that later, but first add the following properties after hasLocation
:
@Published
var locationAuthorizationStatus: CLAuthorizationStatus = .notDetermined
@Published
var locationAccuracyAuthorization: CLAccuracyAuthorization = .reducedAccuracy
The first property tracks the app’s authorization status to use location services. The second property tracks the accuracy preferred for this app by the user.
The app’s authorization status can be either:
- .notDetermined: The user has not yet chosen to allow or prevent location data to this app.
- .restricted: The app is not authorized to use location services, not necessarily because the user denied access.
- .denied: The user denied access to location services or location services is disabled in Settings.
- .authorizedAlways: The app has the authorization to use location services whenever the app requires it, even in the background.
- .authorizedWhenInUse: The user has authorized use of location services only while the app is in the foreground.
The accuracy of location data can be either .fullAccess
, when the app has authorization to the full accuracy data, or .reducedAccuracy
, meaning the app has only the user’s approximate location.
Next, add the following method at the end of the class:
func updateLocationAndAccuracyStatus() {
// 1
locationAuthorizationStatus = locationManager.authorizationStatus
// 2
locationAccuracyAuthorization = locationManager.accuracyAuthorization
}
This method does two things:
- Updates the current location authorization status.
- Updates the current accuracy authorization.
You’ll use this method to update both properties whenever location or accuracy status changes.
Conforming to CLLocationManagerDelegate
To conform NewPictureStore
to CLLocationManagerDelegate
, add the following extension at the end of the file:
// MARK: - CLLocationManagerDelegate
extension NewPictureStore: CLLocationManagerDelegate {
// 1
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
updateLocationAndAccuracyStatus()
}
// 2
func locationManager(
_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]
) {
guard let userLocation = locations.first else { return }
self.userLocation.center = userLocation.coordinate
}
}
Here’s a breakdown of what’s happening in each method:
-
CLLocationManager
callslocationManagerDidChangeAuthorization(_:)
whenever a change happens on the app’s location authorization. When that happens, you update both properties withupdateLocationAndAccuracyStatus()
. -
CLLocationManager
calls this method whenever new location data is available. Then, you update the user location property with the latest data.
This handles updating location data, location accuracy and location authorization. Now, you’ll add code to show the user’s location on a map and request authorization for said feature.
Showing User Location on Map
Add the following extension at the bottom of NewPictureStore.swift:
// MARK: - Location Authorization
extension NewPictureStore {
// 1
var locationIsDisabled: Bool {
locationAuthorizationStatus == .denied ||
locationAuthorizationStatus == .notDetermined ||
locationAuthorizationStatus == .restricted
}
// 2
var showAllowLocationButton: Bool {
locationAuthorizationStatus == .notDetermined
}
// 3
func requestLocationAuthorization() {
locationManager.requestWhenInUseAuthorization()
}
// 4
func startUpdatingUserLocation() {
locationManager.startUpdatingLocation()
}
}
The code above creates an extension with a couple of handy properties and methods. Here’s what they do:
-
locationIsDisabled
is a Boolean to disable the location section if the user has denied access to location data. -
showAllowLocationButton
is a Boolean to show a button if iOS didn’t ask for location services permission yet. - This method calls
requestWhenInUseAuthorization()
to show an alert requesting authorization to access location data. - And finally, this method calls
startUpdatingLocation()
to start updating the user’s location data.
Now, open NewPictureView.swift, find the following line inside locationSection
:
.disabled(true)
And replace it with this:
.disabled(store.locationIsDisabled)
This makes sure the location section will be disabled only if the user didn’t authorize access to location data.
Next, find // TODO: Add map here
and add the following code below the comment:
if store.hasLocation {
MapWithLocation(coordinates: $store.userLocation)
.onAppear(perform: store.startUpdatingUserLocation)
// TODO: Precise location off button
}
MapWithLocation
is a custom SwiftUI view that has a Map
and a Text
with latitude and longitude. When it appears on the view, the modifier onAppear(perform:)
calls startUpdatingUserLocation()
to update the user’s location.
Finally, find // TODO: Add allow location data button here
and add this code under:
if store.showAllowLocationButton {
Button("Allow Location Data", action: store.requestLocationAuthorization)
}
This adds the button to ask for authorization for the app to access location data.
Build and run and tap the new button to allow location.
Nothing happened! But check out the console in Xcode.
To ask authorization to access location data, you need to add a string to Info.plist that iOS uses to explain to users why your app requires access to their location. That’s why nothing happens when you tap the button.