Prepare iOS Publication
Prerequisites
- Apple Developer account
- Bundle identifier for the application
- Provisioning profile for the AppStore bound to the bundle identifier mentioned above
- Xcode
Process
- Set the following Capabilities for the Bundle identifier in the Apple Developer Portal:
- Associated Domains is used for deep linking / mobile-only feature.
- Data Protection: Complete Protection indicates the level of protection the iOS should utilize for files stored by the Access App.
- Push Notifications indicates a push notification feature.
- Download the provisioning profile from the Apple Developer Account. Name it
embedded.mobileprovision
. - Copy the provisioning profile into the provided
.xcarchive
file:
cp embedded.mobileprovision AccessApp.xcarchive/Products/Applications/Access.app/
- Create the
.entitlements
file for the code signing.
Use the example in the next code block, but replace the following placeholders:
Placeholder | Description |
---|---|
<TEAM_ID> | Your team ID. |
<BUNDLE_ID> | Application bundle identifier. |
<DEEP_LINK_DOMAIN> | Domain where the AASA file is served. If the AASA file is served here: http://test.com/.well-known/apple-app-site-association , the <DEEP_LINK_DOMAIN> is test.com . Ensure that an entry exists for every deep link domain the app must support. Refer to the official documentation for more details. |
Application entitlements and capabilities:
<?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>aps-environment</key>
<string>production</string>
<key>application-identifier</key>
<string><TEAM_ID>.<BUNDLE_ID></string>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:<DEEP_LINK_DOMAIN></string>
</array>
<key>com.apple.developer.default-data-protection</key>
<string>NSFileProtectionComplete</string>
<key>com.apple.developer.team-identifier</key>
<string><TEAM_ID></string>
<key>get-task-allow</key>
<false/>
</dict>
</plist>
- Sign the
.xcarchive
by executing the following command. For the Team name and Team ID, see the membership details in the Developer portal:
codesign --entitlements AccessApp.entitlements -f -s "Apple Distribution: <Team name> (<Team ID>)" AccessApp.xcarchive/Products/Applications/Access.app
- Open
.xcarchive
in Xcode. - In the appearing window, select Distribute App on the right side.
- Select App Store Connect as the method of distribution.
- Select destination as Upload.
- Choose the App Store Connect distribution options.
- Choose the signing options, select the certificate and App Store profile.
- Verify that the
aps-environment
capability is listed before uploading to App Store Connect. - Click the Upload button to upload your configuration.
Privacy information
During the WWDC 2023 event, Apple revealed a significant update that from Spring 2024 onwards, developers will be mandated to disclose the rationale behind their utilization of specific APIs, termed Required Reason APIs, within privacy manifest files. These APIs have the potential to be exploited for gathering data concerning users' devices.
Privacy manifest files serve as a platform for developers to outline their privacy methodologies, detailing:
- The data collected by their application or SDK and the intended purpose.
- The Required Reason API integrated into their application or SDK and the justification for their incorporation.
In this article, we will provide a description about the privacy manifest file tailored for our Access App, elucidating its structure and content.
Privacy manifest file in the Nevis Access App
The iOS Nevis Access App contains a privacy manifest file from the 2.9.0 version onwards.
Every privacy manifest file must include the following keys as mandated by Apple.
NSPrivacyTracking
The Nevis Access App does not utilize the gathered data for tracking purposes, thus the NSPrivacyTracking
key is configured to false
.
<!-- Privacy manifest file for iOS Nevis Access App -->
<key>NSPrivacyTracking</key>
<false/>
NSPrivacyTrackingDomains
The NSPrivacyTrackingDomains
key is not utilized by our iOS app. This key is typically employed to declare the domains associated with tracking for the purpose of user consent in tracking scenarios. However, since our app does not engage in tracking activities, this key is unused.
<!-- Privacy manifest file for iOS Nevis Access App -->
<key>NSPrivacyTrackingDomains</key>
<array/>
NSPrivacyCollectedDataTypes
Apple has provided a list of data types which could potentially identify or track a user or device when gathered. The Nevis Access App utilizes several items from this list, including CrashData
, OtherDiagnosticData
, PerformanceData
, DeviceID
, and UserID
. Additionally, it is required to specify the purpose behind collecting this data. In the case of the Access App, the collected data serves the purpose of supporting app functionality and analytics. This information is documented in our privacy manifest file.
<!-- Privacy manifest file for iOS Nevis Access App -->
<key>NSPrivacyCollectedDataTypes</key>
<array>
<dict>
<!-- The value provided by Apple for 'Crash Data' data type -->
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeCrashData</string>
<!-- Nevis Access App does link the 'Crash Data' with user's identity -->
<key>NSPrivacyCollectedDataTypeLinked</key>
<true/>
<!-- Nevis Access App does not use the 'Crash Data' for tracking -->
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<!-- Nevis Access App uses 'Crash Data' for app functionality and analytics -->
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
<string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
</array>
</dict>
<dict>
<!-- The value provided by Apple for 'Other Diagnostic Data' data type -->
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeOtherDiagnosticData</string>
<!-- Nevis Access App does link the 'Other Diagnostic Data' with user's identity -->
<key>NSPrivacyCollectedDataTypeLinked</key>
<true/>
<!-- Nevis Access App does not use the 'Other Diagnostic Data' for tracking -->
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<!-- Nevis Access App uses 'Other Diagnostic Data' for app functionality and analytics -->
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
<string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
</array>
</dict>
<dict>
<!-- The value provided by Apple for 'Performance Data' data type -->
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypePerformanceData</string>
<!-- Nevis Access App does link the 'Performance Data' with user's identity -->
<key>NSPrivacyCollectedDataTypeLinked</key>
<true/>
<!-- Nevis Access App does not use the 'Performance Data' for tracking -->
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<!-- Nevis Access App uses 'Performance Data' for app functionality and analytics -->
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
<string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
</array>
</dict>
<dict>
<!-- The value provided by Apple for 'Device ID' data type -->
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeDeviceID</string>
<!-- Nevis Access App does link the 'Device ID' with user's identity -->
<key>NSPrivacyCollectedDataTypeLinked</key>
<true/>
<!-- Nevis Access App does not use the 'Device ID' for tracking -->
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<!-- Nevis Access App uses 'Device ID' for app functionality and analytics -->
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
<string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
</array>
</dict>
<dict>
<!-- The value provided by Apple for 'User ID' data type -->
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeUserID</string>
<!-- Nevis Access App does link the 'User ID' with user's identity -->
<key>NSPrivacyCollectedDataTypeLinked</key>
<true/>
<!-- Nevis Access App does not use the 'User ID' for tracking -->
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<!-- Nevis Access App uses 'User ID' for app functionality and analytics -->
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
<string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
</array>
</dict>
</array>
NSPrivacyAccessedAPITypes
The only Required Reason API that the Nevis Access App uses is the UserDefaults.
<!-- Privacy manifest file for iOS Nevis Access App -->
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
Problem solving
Change release version MARKETING_VERSION
of an .xcarchive
You cannot change a version already published in App Store.
To bypass the issue using the already delivered .xcarchive
package, you can manually change the marketing version as follows:
- Right-click on the
.xcarchive
file, and select Show Package Contents. - Find and open the
Info.plist
in the root folder with Xcode. - Change the value of the
CFBundleShortVersionString
property to the right marketing version. - Find the
.app
in theProducts/Applications/
folder. - Right-click on the
.app
file, and select Show Package Contents. - Find and open the
Info.plist
in the.app
folder with Xcode. - Change the value of the
CFBundleShortVersionString
property to the right marketing version. - Find the
.app.dSYM
in thedSYMs
folder. - Right-click on the
.app.dSYM
file, and select Show Package Contents. - Find and open the
Info.plist
in the.app.dSYM/Contents
folder with Xcode. - Change the value of the
CFBundleShortVersionString
property to the right marketing version. - Open the
.xcarchive
in the Xcode Organizer by double-click on it. - Check the version one last time.