Open the Xcode project ios/Runner/Runner.xcworkspace
- Enable the background modes:
- Location updates
- Background fetch
- Audio (optional for debug-mode sound FX)
- Add the following permissions to
Info.plist
:
Key | Type | Value |
---|---|---|
Privacy - Location Always and When in Use Usage Description | String |
CHANGEME: Location required in background |
Privacy - Location When in Use Usage Description | String |
CHANGEME: Location required when app is in use |
Privacy - Motion Usage Description | String |
CHANGEME: Motion permission helps detect when device in in-motion |
📂 ios/Runner/Info.plist
<dict>
+ <key>NSMotionUsageDescription</key>
+ <string>Motion usage description</string>
+ <key>NSLocationWhenInUseUsageDescription</key>
+ <string>When in use description</string>
+ <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
+ <string>Always/When in use description</string>
+ <key>UIBackgroundModes</key>
+ <array>
+ <string>fetch</string>
+ <string>location</string>
+ </array>
</dict>
</plist>
Apple now requires apps provide a Privacy Manifest for "sensitive" APIs which could be abused for "fingerprinting" a user for malicious marketing activity.
If your app does not yet have a Privacy Manifest (PrivacyInfo.xcprivacy
), create one now:
ℹ️ Click here for detailed instructions...
- In XCode,
File -> New -> File...
:
- Be sure to enable your
Targets: [x] YourApp
:
It's best to edit this file's XML manually.
- 📂
ios/PrivacyInfo.xcprivacy
- Add the following 4 blocks within the
NSPrivacyAccessedAPITypes
<array>
container:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<!-- [1] background_fetch: UserDefaults -->
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
<!-- [2] background_geolocation: UserDefaults -->
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
<string>1C8F.1</string>
</array>
</dict>
<!-- [3] background_geolocation (CocoaLumberjack): FileTimestamp -->
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
<string>0A2A.1</string>
</array>
</dict>
<!-- [4] background_geolocation (CocoaLumberjack): DiskSpace -->
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>E174.1</string>
</array>
</dict>
</array>
</dict>
</plist>
The BackgroundGeolocation SDK makes use internally on background_fetch
(also created by Transistor Software). Regardless of whether you instend to implement the BackgroundFetch Dart API in your app, you must perform the Background Fetch iOS Setup at the background_fetch
repo.
Tip
background_fetch
is helpful for executing a periodic task (eg: every 15 minutes). You could use background_fetch
to periodically request the current location:
// Execute a task about every 15 minutes:
BackgroundFetch.configure(BackgroundFetchConfig(
minimumFetchInterval: 15
), (String taskId) async { // <-- This is your periodic-task callback
var location = await BackgroundGeolocation.getCurrentPosition(
samples: 3,
extras: { // <-- your own arbitrary meta-data
"event": "getCurrentPosition"
}
);
print('[getCurrentPosition] $location');
BackgroundFetch.finish(taskId); // <-- signal that your task is complete
})