Chapters

Hide chapters

Real-World iOS by Tutorials

First Edition · iOS 15 · Swift 5.5 · Xcode 13

Before You Begin

Section 0: 4 chapters
Show chapters Hide chapters

12. App Privacy
Written by Renan Benatti Dias

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

The iPhone completely changed the way people use phones. A phone is no longer just a device for making calls: It’s a whole computer in your pocket, full of features and capabilities.

With it, the App Store transformed the way developers deliver their experience to customers. Developers create apps and submit them to the App Store. Apple reviews them, and then they become available to users. Potential users can browse and find many different kinds of apps, and they trust Apple’s review to guarantee the minimum quality of that app.

However, with all the new capabilities developers can access, privacy has become a real concern to everyone. The conversation about who owns your data and how companies can use it is an issue that triggers a never-ending debate.

Apple has taken a strong position on this: People’s privacy is important and they should decide if they want to share any data with developers.

With that in mind, Apple built new features into iOS and the App Store to make developers more transparent and iOS more private.

In this chapter, you’ll learn about:

  • iOS’s many privacy features.

  • Requesting location data from users.

  • Sending the user’s location in the request to Petfinder’s API to find pets near that location.

  • How apps adapt UI to account for users’ privacy choices.

  • The App Store’s Privacy section.

Before you start, take a closer look at why privacy is important.

Why privacy is important

Apple takes people’s privacy very seriously. It understands that people don’t want to share every detail of their lives. People have the right to choose what and how much they share. That’s why Apple has worked hard to make privacy features: to give people a choice in what they want to share.

Apps may want to collect data to drive a specific feature, make a more targeted advertisement or even improve released features.

Apple understands that developers may need access to this data to build better features, but that doesn’t mean people don’t have a choice. Transparency, letting users understand what they are sharing and why, is a critical aspect of privacy.

That’s why Apple has built features that allow developers to ask for authorization to access those capabilities and make users aware of when and why.

iOS privacy features

Many of iOS’s privacy features focus on apps and developers being transparent.

iOS app using camera.
aUC ixp urevf dijese.

iOS control center.
eAZ zocnteh punvac.

iOS app using microphone.
aEX oks anuds votwufreje.

The privacy view modifier

SwiftUI also has a couple of view modifiers to keep sensitive data private. Lock screens can access a widget without unlocking the iPhone, which is a potential problem if a widget shows sensitive information.

struct CreditCardView: View {
  var body: some View {
    VStack(alignment: .leading, spacing: 82) {
      VStack(alignment: .leading) {
        HStack {
          Text("Ray Bank")
            .font(.title2)
          Spacer()

          Text("platinum")
            .font(.caption2)
        }
        Text("Credit Card")
          .font(.caption)
      }

      VStack(alignment: .leading) {
        HStack(alignment: .bottom) {
          Text("1234 5678 9123 456")
          Spacer()
          Image(systemName: "flag.square.fill")
            .font(.title)
            .imageScale(.large)
        }
        HStack {
          Text("Exp: 02/20")
          Text("Valid: 02/21")
          Text("Security Code:")
          Text("123")
        }
        .font(.caption2)
      }
    }
    .padding()
    .background(.green)
    .foregroundColor(.white)
    .mask(RoundedRectangle(cornerRadius: 8))
    .padding()
  }
}
Example of displaying sensitive information.
Ofakmsa ex pecypurejf yehtisomu ufpapxineuj.

Text("1234 5678 9123 456")
  .privacySensitive()

Text("Security Code:")
Text("123")
  .privacySensitive()
struct WidgetView: View {
  var body: some View {
    CreditCardView()
      .redacted(reason: .privacy)
  }
}
Example of hiding senstitive information.
Ujasyyu uk gutupq vehkcisexo uwrebmayoag.

if redactionReasons == .privacy {
  Text("Hidden card number")
} else {
  Text("1234 5678 9123 456")
}
Example of displaying sensitive information with a hidden message.
Ihujmre uq zatknudezl duxrumuge iyquycacios fadz u homxac puzriqe.

Location and privacy

A user’s location is very sensitive data. It might reveal to developers where the user lives, walks or commutes. So, users should be aware and in control whenever apps have access to their location.

Adding location to find pets near you

To access the user’s location, you first need to ask their permission with a valid reason. Remember, it’s the user’s choice to allow access to their private details.

Building a view to ask permission

Inside AnimalsNearYou/views, create a new SwiftUI View and name it RequestLocationView.swift.

@EnvironmentObject var locationManager: LocationManager
func startUpdatingLocation() {
  locationManager.startUpdatingLocation()
}
import CoreLocationUI
VStack {
  // 1
  Image("creature_dog-and-bone")
    .resizable()
    .frame(width: 240, height: 240)
  // 2
  Text("""
    To find pets near you, first, you need to
    share your current location.
  """)
    .multilineTextAlignment(.center)
  // 3
  LocationButton {
    locationManager.startUpdatingLocation()
  }
  .symbolVariant(.fill)
  .foregroundColor(.white)
  .cornerRadius(8)
}
.padding()
.onAppear {
  // 4
  locationManager.updateAuthorizationStatus()
}
.environmentObject(LocationManager())

The new Location button

LocationButton is a new SwiftUI button that brings a couple of improvements to asking permission to access the user’s location. This new button doesn’t require you to add a reason text in the info.plist that explains why you want to access the user’s location data. It already has a default text and alert for asking permission when the user taps the button and doesn’t require you to manually call a method.

Location status types

iOS has five location authorization statuses:

Updating Animals Near You to request authorization

Now that you have a view for asking for the user’s authorization, it’s time to update Animals Near You to use it.

@EnvironmentObject var locationManager: LocationManager
// 1
if locationManager.locationIsDisabled {
  RequestLocationView()
    .navigationTitle("Animals near you")
} else {
  // 2
  AnimalListView(animals: animals) {
    if !animals.isEmpty && viewModel.hasMoreAnimals {
      HStack(alignment: .center) {
        LoadingAnimation()
          .frame(maxWidth: 125, minHeight: 125)
        Text("Loading more animals...")
      }
      .task {
        await viewModel.fetchMoreAnimals()
      }
    }
  }
  .task {
    await viewModel.fetchAnimals()
  }
  .listStyle(.plain)
  .navigationTitle("Animals near you")
  .overlay {
    if viewModel.isLoading && animals.isEmpty {
      ProgressView("Finding Animals near you...")
    }
  }
}
.environmentObject(LocationManager())
@StateObject var locationManager = LocationManager()
.environmentObject(locationManager)
.environmentObject(LocationManager())
Requesting user's authorization to access their location.
Kelaazgasr otez'n ouhwoviyopuep ba anxoqn fyeog horagaef.

Current Location button alerting user.
Jafxold Miwawout nemxup ocutmaly ejaf.

Pet list.
Pos fopf.

Sending location data in the request

Now, PetSave asks for authorization to access the user’s location. However, it’s not doing anything with this data yet.

func fetchAnimals(page: Int) async -> [Animal]
func fetchAnimals(
  page: Int,
  latitude: Double?,
  longitude: Double?
) async -> [Animal]
func fetchAnimals(
  page: Int,
  latitude: Double?,
  longitude: Double?
) async -> [Animal] {
latitude: nil,
longitude: nil
latitude: latitude,
longitude: longitude
func fetchAnimals() async {
func fetchAnimals(location: CLLocation?) async {
isLoading = true
do {
  // 1
  let animals = await animalFetcher.fetchAnimals(
    page: page,
    latitude: location?.coordinate.latitude,
    longitude: location?.coordinate.longitude
  )

  // 2
  try await animalStore.save(animals: animals)

  // 3
  hasMoreAnimals = !animals.isEmpty
} catch {
  // 4
  print("Error fetching animals... \(error.localizedDescription)")
}
isLoading = false
func fetchMoreAnimals(location: CLLocation?) async {
await fetchAnimals()
await fetchAnimals(location: location)
await viewModel.fetchMoreAnimals()
await viewModel.fetchMoreAnimals(location: locationManager.lastSeenLocation)
await viewModel.fetchAnimals()
await viewModel.fetchAnimals(location: locationManager.lastSeenLocation)
func fetchAnimals(
  page: Int,
  latitude: Double?,
  longitude: Double?
) async -> [Animal] {
AnimalsNearYou view using user's location.
UwagukcJeegHau haib otokf axul'y vequduob.

Tapping Current Location button again on relaunching the app.
Zaxxobx Lapviwp Canepooq nukmiv exiav ec vabeejzgejs hsi iwc.

Requesting authorization when in use

Open LocationManager.swift and add the function below to LocationManager:

func requestWhenInUseAuthorization() {
  cllLocationManager.requestWhenInUseAuthorization()
}
locationManager.startUpdatingLocation()
locationManager.requestWhenInUseAuthorization()
Asking user for permanent location authorization, when the app is in use.
Aggusv anoz yev goqleguct ciyenauw oitkoxusibour, bwep vga ezd es ax isa.

Location accuracy

iOS also has a neat feature for protecting people’s privacy. Most features that request the user’s location don’t need their accurate location. They only require an approximate location to recommend or find places nearby them.

User's precise location on.
Adet'y dlihuve zenewuib ib.

Adapting the UI depending on accuracy level

Dealing with location accuracy means the app has to adapt to some situations. Take Apple Maps for example. When the user allows the app to use a precise location, a blue dot in the map represents their location.

Apple Maps example displaying a blue dot when precise location is on.
Uwmpe Zoht ifazwbi cupzyopunk a fgai wij gwoz fcuveti hireluig us iw.

Apple Maps example displaying a shaded circle when precise location is off.
Izyzu Tabl uxuftla hevrwajutr u cticof jaqmje qrij nxelowa totazeek ag uyz.

Apple Maps favorite section.
Udwpe Kusj teloxufo milyuab.

Updating the tests

Before you finish this feature, you have to update your tests to take into account the new location manager property.

await viewModel.fetchAnimals()
await viewModel.fetchAnimals(location: nil)
await viewModel.fetchMoreAnimals()
await viewModel.fetchMoreAnimals(location: nil)
await viewModel.fetchAnimals()
``

With:

```swift
await viewModel.fetchAnimals(location: nil)
func fetchAnimals(
  page: Int,
  latitude: Double?,
  longitude: Double?
) async -> [Animal] {
Test is successful.
Qovf ap tajdaztyab.

App Store’s Privacy section

When launching an app in the App Store, Apple makes every developer provide a list of data their app collects. App Store’s Privacy Section ensures developers explain to their users what kind of data they’re collecting.

Understanding different types of data

Apple categorizes the many types of data an app may collect. It requires you to understand which kind of data you collect and disclose them under the following categories:

App Store displaying App Privacy section.
Ahc Yleja mesnfupody Iqy Pcaruhb zojneic.

App Privacy details.
Isd Twunonk buluayz.

Key points

Where to go from here?

In this chapter, you went over what’s privacy and why you should care. Also, you added the functionality to get the current location so users of PetSave can enjoy a more personalized experience.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.

You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.

Unlock now