Setting Background Modes and Device Capability Privacies in iOS Apps
This tutorial demonstrates sample iOS apps that use CallKit (audio/video calling), Stream Chat SwiftUI, iOS device capabilities, and the Photos Library to assist you in configuring background modes and requesting user permissions in iOS projects.
What are the required background modes and protected resource privacies on iOS? Discover and learn to set them appropriately in this article. It focuses on configuring background modes for iOS apps in Xcode and requesting authorization to access the user’s camera, microphone, and media.
This article uses the following projects to demonstrate how background modes work in iOS apps. You will also learn about setting privacy for messaging, audio, and video calling apps with the same projects and a chat messaging app using the Stream Chat SwiftUI SDK. Find them from the Swift and SwiftUI Tutorial Projects repository on GitHub.
- CallKit: Audio/video calling demo for background modes
- Photos and files usage privacy demo
- Camera usage privacy demo
Understanding Background Execution Mode on iOS
An app is said to be in the foreground when a user interacts and engages with it actively. A user engaging with a calling app, for example, having an active video call with a friend, may switch to another app on the device. This action will cause the calling app to move away from the foreground but will still be running and not necessarily visible to the user. The calling app running or executing code while not in the foreground is called background execution mode.
Background modes are services an app offers that require it to execute tasks when it is not active or running in the foreground. In the case of VoIP (audio and video) calling apps, enabling background modes can cause the app to update and execute tasks in the background when the user launches another app or transitions to the home screen.
On iOS, you can use background modes for apps that belong to specific categories or use cases. These categories of apps and use cases may require several background capabilities for different tasks and services, such as audio, video, location, fetch, Bluetooth central, and processing. Your app can adopt one or more of these background modes. However, Apple limits the number of background modes you can configure for your app to improve the performance and battery life of the users' devices.
How Background Execution Works
Any app that wishes to run in the background must send a request to the system. Think of this as using the Picture-in-Picture (PIP) functionality on WhatsApp or FaceTime calls when you switch to another app. You can engage actively with the new app (for example, writing notes) without the PIP calling hindering you.
Common Background Execution Use Cases
Apps that require background execution may fall into the following categories.
- CallKit integration: Audio and video calling
- Files download and upload
- Content updates that occur periodically
- Workout: Steps counting
- Location and navigation
- Accessory communication
Configuring Background Modes on iOS
Some iOS apps require you to set up some app capabilities to enable certain background operations. For instance, when working with an audio playback app, you would like the app to play audio while not in the foreground.
Similarly, it is a great user experience for your video playback app to display the picture-in-picture feature to users while the app is in the background. Depending on the iOS project you create, you can specify the background modes below for your apps.
- Audio, AirPlay, and Picture in Picture:
You can use this background mode for iOS and tvOS apps that support media playback and VoIP. Using this background mode, the app's background audio playback and picture-in-picture behaviors will work as expected when the app transitions from the foreground to an inactive state. When you enable this capability, your app's audio playback will continue to play when users lock their iOS device or switch to another app. Enabling this capability also makes the fullscreen video playback of your app switch seamlessly to picture-in-picture playback when users transition to other apps.
- Location updates: Enabling this background mode allows your app to receive location updates when it is in a suspended state. You can enable this mode for map and navigation apps to display users' physical location and assist users in navigating to a particular environment while the app is in the background. Think of this mode as when using the Maps app or Google Maps on an iPhone to navigate to a location in the city. After specifying the destination address, you can suspend the Maps app or Google Maps to the background and still receive location updates (alerts), such as left and right turns and the time left to reach a geographic region while driving, riding, or walking.
- Voice over IP: You should add this mode for apps that support CallKit. Enabling this mode allows CallKit-based apps to launch automatically when for example, there is an incoming call while the app is in the background.
- External accessory communication: Enable this mode for an app that communicates with external hardware that connects to the iOS device physically to deliver data regularly using Bluetooth wireless technology, a 30-pin connector, or an Apple Lightning connector. Refer to the Apple documentation for more information about connecting to external accessories using an iOS device.
Uses Bluetooth LE accessory: This mode enables an app to communicate with Bluetooth-equipped low energy (LE) accessories while the app is in the background and ensures a great device battery life.
Background fetch: The background app refresh API helps apps to fetch new content and keeps the content up to date at all times. It requests the system to run the app periodically in the background before the user brings it to the foreground. Example use cases can be social and activity feeds, fetching emails, and retrieving the latest information in an app.
- Remote notifications: The remote notifications API helps your app to wake up from the background without displaying a visible notification to the user. You can use this API for content that users do not consider urgent. Examples include receiving new messages and muted channels in chat apps. In a messaging app, for example, it helps to disable alerts for specific threads so that a user does not get a visible notification any time a message is delivered. Its purpose is to alert the iOS device whenever new content is available. Also, it will prevent the app from launching if you do not set it.
- Background processing: This API gives your app ample runtime to execute deferrable maintenance tasks like indexing a database. It can be used for use cases, such as training a Core ML model, content syncing, backing up content, and cleaning up databases.
- Use Nearby Interaction:
- If your iOS app requires finding and interacting with nearby devices (using identifiers, distance, and direction), you must set this mode for the app to work in the background. Before the interaction can work, the devices must be in physical proximity so that when you run the app, position, and device tokens can be shared with the system to identify them. Check Nearby Interaction in the Apple documentation for more information.
- Push to Talk: Enabling this mode causes your iOS/iPadOS app to wake up in response to push notifications to play incoming audio while the app is in the background. When enabled, it sends a temporally token from the Apple Push Notification service (APNs) to the system to launch the app in the background to handle audible content.
Setting Background Modes For a Messaging App
You can see a great example of background execution in chat messaging apps. The main functionalities of a messaging app may be having chat conversations with people, uploading and downloading attachments from other participants, and muting or disabling notifications from a particular thread. Since sending messages is a core function of the app, its users expect sent messages to be delivered as soon as they send them. In most cases, such as when there is a bad or slow network, messages won't reach immediately to the other chat participants. At this point, the user may switch to another app, thinking the message is already delivered. To ensure the message is delivered while the app is not in the foreground, you can use the Background Modes API to handle this situation.
How Background Modes Work in VoIP Apps
The background modes API for phone calls (video and voice calling) is VoIP Push Notifications. If you do not request this API for your VoIP app, the system will fail to launch the app. In the case of a calling app, assuming user A has audio unmuted, video on, and is in an active call with user B. When user A suspends the app to go into the background, iOS device capabilities, such as the camera and microphone, will not be accessible. In this case, the system will mute user A's audio, and the picture-in-picture (video) feature will not be available when the app is in the background. The app's inability to access audio and PIP from the background is a default behavior on iOS.
To override this default behavior, specify the required background modes so that audio and picture-in-picture become accessible when the app goes to the background. After enabling these background mode capabilities, unmuted audio will remain unmuted when the app goes into the background. Also, picture-in-picture will be available to the call participant while the app remains in the background.
Configuring Background Modes For Audio/Video Calling Apps
In this example, you will add Voip over IP as the required background for a CallKit (audio/video calling). Download the finished CallKit integration demo from GitHub and test it on an iPhone. Failure to specify Voip over IP as the required background mode will make the app run successfully. However, it will display a blank screen.
- Click the app's name in the Project Navigator, select your target, and go to the Signing & Capabilities tab.
- Enable Voip over IP by clicking the checkbox on its left side.
- If you now run the app, you will see the incoming call screen, as demonstrated in the image below.
Before you begin accessing users' location data, media, and device capabilities, you must request authorization in your app from the device owner. The users of your app have autonomy over their device camera, data, videos, and photos and control over which apps can use these personal assets. Since users are sensitive and care a lot about privacy and their data, you should always let them know clearly why your app needs to access their assets (for example, photos) or data on their devices. Even when you enable the required privacy in your app, users can deny or grant access when using the app for the first time. They can also reverse their decision in the system settings of the iOS device.
In iOS, there are several situations in which your app will need the user's permission to access data, content, and capabilities. The permissions display only once when users try to use the required feature of the app for the first time. Examples of these include:
- iOS device capabilities: camera and microphone access for VoIP apps
- Access to personal information, users' location, health data, and contact information
- Private resources such as local networks, Bluetooth, and Wi-Fi connections
- Media: Photos and recorded videos
These permissions consist of keys and values you should specify as strings in your Xcode project.
Privacies For Protected Resources
To indicate that an app needs access to protected resources, you must specify a UsageDescription key-value pair in a SwiftUI app's Info tab or a UIKit app's Information Property List (info.plist). The value associated with the keys must be specified as a string and must give the reason why the app needs access. The following are some common privacies required for your apps to access the user's calendars, cameras, contacts, FaceID, files, motion data, photos, health data, etc.
- Privacy - Bluetooth Always Usage Description: This is a string that specifies why the app needs to access the user’s Bluetooth.
- Privacy - Calendar Usage Description: This is a message that explains to the user why the app needs calendar data access.
- Privacy - Face ID Usage Description: A string that prompts the user why the app needs to use Face ID for authentication.
- Privacy - Health Records Usage Description: A string that explains to the user why the app needs to access clinical records.
- Privacy - Location Usage Description: A message asking the user why the app wants to access location data.
- Privacy - Media Library Usage Description: A message that explains why the app wants to access the media library (Apple Music).
- Privacy: Microphone Usage Description: A message that prompts the user why the app wants to access the device’s microphone.
- Privacy - Motion Usage Description: A message that prompts the user why the app wants to access the device's motion data.
- Privacy - Photo Library Usage Description: A string that prompts the user why the app needs the authorization to access photos in the Photo Library.
Refer to the Apple documentation for more information about all the privacies available on the various platforms.
Requesting Permission to Use iOS Device Capabilities
This section shows how to configure privacy in an iOS app to authorize it to access the user's camera and microphone. The image below displays the string that prompts the user to grant or deny access to camera usage after you set the UsageDescription as described above. You can download the demo SwiftUI project Camera Usage Privacy Demo on GitHub and test it with an iOS device. The demo app displays the iOS device camera when you run the Xcode project.
Audio and video calling apps access and use the callers' camera and microphone during calls. When users launch the calling app for the first time, it is ethical and required to ask their permission for camera and microphone usage. Apple requires you to configure the following two privacy settings for VoIP apps.
- Privacy - Microphone Usage Description
- Privacy - Camera Usage Description
Note: If you do not add the settings above in the calling app, it will not launch and display the camera. To configure these privacy settings in your Xcode project:
- Select the project's name in the top left of the Xcode Navigator. The name for this project is SwiftUICallingKit, but yours may be different.
- Head to the Info tab and click any of the + icons for the items under Key to add a new privacy item.
- Search through the list and choose Privacy - Camera Usage Description. The Type is a string, so set its Value as SwiftUICallingKit would like to access your camera. Note: You should set the value of the string with your custom text.
- Repeat the previous step and set the privacy for the microphone usage privacy as SwiftUICallingKit would like to access your microphone.
When you run the app for the first time, you will see the message prompt shown above. Once you authorize the app to use your camera, it will show the iOS device camera when you run it in Xcode, as seen in the video below.
Setting Privacy to Access User’s Photos, Files, and Camera
The example in this section demonstrates what happens when a user tries to pick an attachment from the Photos Library on an iOS device and sends it in Stream Chat with and without adding an authorization message in the demo app. Download the demo SwiftUI chat messaging project from GitHub and test it by running the Xcode project with a simulator or iPhone. Without requesting the user's authorization Privacy - Photo Library Usage Description, in the Info tab, the app will cratch and display the warning message below in the Xcode console when you run the app.
Setting privacy to access photos and files is similar to the steps used to configure the camera access privacy described above.
- Click the project’s name in the Xcode Navigator PhotoFilesUsageDomo. Click the Info tab and make sure the name of the project is selected under TARGETS.
- Click the (+) icon under Key, find and add Privacy - Photo Library Usage Description, and specify a custom message for the prompt.
- Repeat the steps to set the privacy for the camera usage.
- Run the app using a simulator or iPhone. Bravo!!!. You can now access the photos, files, and camera for the attachment button in Stream Chat SwiftUI as shown below.
Where Do I Learn More?
This tutorial covered background modes and protected resource privacy settings for iOS projects. It demonstrated the concepts using the following three practical example projects. You can download them all from GitHub.
- CallKit: Audio/video calling demo for background modes
- Photos and files privacy demo
- Camera Usage Privacy Demo
Check out Stream Chat iOS if you plan to integrate real-time messaging into your apps. If you want to build a VoIP app, consider using Stream Video. You can sign up for early access today.
- Using PushKit Notification: How To Show an Incoming Call on a Device
- Real-World Xcode Project Using Tuist
- Linting Documentation with Vale to Increase Quality & Consistency
- SwiftUI Animation: How To Add Facebook Live Reactions to Livestream Chats
- Learning to Build Twitter in a Weekend
- Building a Video Chat App: WebRTC in Jetpack Compose (Part2)