Skip to content

Commit 019cb93

Browse files
authored
feat(apple): declare entitlements in app manifest (#2010)
1 parent 2f6784b commit 019cb93

File tree

14 files changed

+83
-65
lines changed

14 files changed

+83
-65
lines changed

ios/ReactTestApp.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
196C22612490CB7600449D3C /* React+Compatibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "React+Compatibility.h"; sourceTree = "<group>"; };
5151
196C7207232EF5DC006556ED /* ReactTestApp-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ReactTestApp-Bridging-Header.h"; sourceTree = "<group>"; };
5252
196C7214232F1788006556ED /* ReactInstance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactInstance.swift; sourceTree = "<group>"; };
53-
196C7216232F6CD9006556ED /* ReactTestApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ReactTestApp.entitlements; sourceTree = "<group>"; };
53+
196C7216232F6CD9006556ED /* App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = App.entitlements; sourceTree = SOURCE_ROOT; };
5454
196C724023319A85006556ED /* QRCodeScannerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeScannerViewController.swift; sourceTree = "<group>"; };
5555
197827F927710D3400AEC655 /* Manifest+Embedded.g.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Manifest+Embedded.g.swift"; sourceTree = SOURCE_ROOT; };
5656
1988282224105BCC005057FF /* UIViewController+ReactTestApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+ReactTestApp.h"; sourceTree = "<group>"; };
@@ -131,10 +131,10 @@
131131
196C22602490CB7600449D3C /* React+Compatibility.m */,
132132
1988282224105BCC005057FF /* UIViewController+ReactTestApp.h */,
133133
1988284424105BEC005057FF /* UIViewController+ReactTestApp.m */,
134+
196C7216232F6CD9006556ED /* App.entitlements */,
134135
19ECD0DB232ED427003D8557 /* Assets.xcassets */,
135136
19ECD0E3232ED427003D8557 /* Info.plist */,
136137
191A67832BDFCD5C0094F246 /* PrivacyInfo.xcprivacy */,
137-
196C7216232F6CD9006556ED /* ReactTestApp.entitlements */,
138138
192F052724AD3CC500A48456 /* ReactTestApp.common.xcconfig */,
139139
192F052824AD3CC500A48456 /* ReactTestApp.debug.xcconfig */,
140140
192F052624AD3CC500A48456 /* ReactTestApp.release.xcconfig */,
@@ -400,7 +400,7 @@
400400
buildSettings = {
401401
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
402402
CLANG_ENABLE_MODULES = YES;
403-
CODE_SIGN_ENTITLEMENTS = ReactTestApp/ReactTestApp.entitlements;
403+
CODE_SIGN_ENTITLEMENTS = App.entitlements;
404404
CODE_SIGN_STYLE = Automatic;
405405
DEVELOPMENT_ASSET_PATHS = "";
406406
DEVELOPMENT_TEAM = UBF8T346G9;
@@ -424,7 +424,7 @@
424424
buildSettings = {
425425
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
426426
CLANG_ENABLE_MODULES = YES;
427-
CODE_SIGN_ENTITLEMENTS = ReactTestApp/ReactTestApp.entitlements;
427+
CODE_SIGN_ENTITLEMENTS = App.entitlements;
428428
CODE_SIGN_STYLE = Automatic;
429429
DEVELOPMENT_ASSET_PATHS = "";
430430
DEVELOPMENT_TEAM = UBF8T346G9;

ios/ReactTestApp/ReactTestApp.entitlements

Lines changed: 0 additions & 10 deletions
This file was deleted.

ios/entitlements.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
require('cfpropertylist')
2+
3+
require_relative('pod_helpers')
4+
5+
DEFAULT_IOS_ENTITLEMENTS = {
6+
'keychain-access-groups' => [
7+
'$(AppIdentifierPrefix)com.microsoft.adalcache',
8+
],
9+
}.freeze
10+
11+
DEFAULT_MACOS_ENTITLEMENTS = {
12+
'com.apple.security.app-sandbox' => true,
13+
'com.apple.security.files.user-selected.read-only' => true,
14+
'com.apple.security.network.client' => true,
15+
}.freeze
16+
17+
def generate_entitlements!(project_root, target_platform, destination)
18+
user_entitlements = platform_config('codeSignEntitlements', project_root, target_platform)
19+
# If `codeSignEntitlements` is a string, set `CODE_SIGN_ENTITLEMENTS` instead
20+
return if user_entitlements.is_a? String
21+
22+
entitlements = target_platform == :macos ? DEFAULT_MACOS_ENTITLEMENTS : DEFAULT_IOS_ENTITLEMENTS
23+
24+
plist = CFPropertyList::List.new
25+
plist.value = CFPropertyList.guess(entitlements.merge(user_entitlements || {}))
26+
plist.save(File.join(destination, 'App.entitlements'),
27+
CFPropertyList::List::FORMAT_XML,
28+
{ :formatted => true })
29+
end

ios/test_app.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require('pathname')
44

55
require_relative('assets_catalog')
6+
require_relative('entitlements')
67
require_relative('info_plist')
78
require_relative('pod_helpers')
89
require_relative('privacy_manifest')
@@ -190,6 +191,7 @@ def make_project!(xcodeproj, project_root, target_platform, options)
190191
end
191192

192193
generate_assets_catalog!(project_root, target_platform, destination)
194+
generate_entitlements!(project_root, target_platform, destination)
193195
generate_info_plist!(project_root, target_platform, destination)
194196
generate_privacy_manifest!(project_root, target_platform, destination)
195197

macos/ReactTestApp.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
193EF066247A736300BE8C79 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = SOURCE_ROOT; };
4848
193EF069247A736300BE8C79 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
4949
193EF06B247A736300BE8C79 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
50-
193EF06C247A736300BE8C79 /* ReactTestApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ReactTestApp.entitlements; sourceTree = "<group>"; };
50+
193EF06C247A736300BE8C79 /* App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = App.entitlements; sourceTree = SOURCE_ROOT; };
5151
193EF071247A736300BE8C79 /* ReactTestAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReactTestAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
5252
193EF077247A736300BE8C79 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
5353
193EF07C247A736300BE8C79 /* ReactTestAppUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReactTestAppUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -128,11 +128,11 @@
128128
196C22632490CBAB00449D3C /* React+Compatibility.m */,
129129
193EF092247A830200BE8C79 /* UIViewController+ReactTestApp.h */,
130130
193EF091247A830200BE8C79 /* UIViewController+ReactTestApp.m */,
131+
193EF06C247A736300BE8C79 /* App.entitlements */,
131132
193EF066247A736300BE8C79 /* Assets.xcassets */,
132133
193EF068247A736300BE8C79 /* Main.storyboard */,
133134
193EF06B247A736300BE8C79 /* Info.plist */,
134135
191A67872BDFD9E90094F246 /* PrivacyInfo.xcprivacy */,
135-
193EF06C247A736300BE8C79 /* ReactTestApp.entitlements */,
136136
19B368BC24B12C24002CCEFF /* ReactTestApp.common.xcconfig */,
137137
19B368BD24B12C24002CCEFF /* ReactTestApp.debug.xcconfig */,
138138
19B368BE24B12C24002CCEFF /* ReactTestApp.release.xcconfig */,
@@ -391,7 +391,7 @@
391391
buildSettings = {
392392
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
393393
CLANG_ENABLE_MODULES = YES;
394-
CODE_SIGN_ENTITLEMENTS = ReactTestApp/ReactTestApp.entitlements;
394+
CODE_SIGN_ENTITLEMENTS = App.entitlements;
395395
CODE_SIGN_IDENTITY = "-";
396396
CODE_SIGN_STYLE = Automatic;
397397
COMBINE_HIDPI_IMAGES = YES;
@@ -412,7 +412,7 @@
412412
buildSettings = {
413413
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
414414
CLANG_ENABLE_MODULES = YES;
415-
CODE_SIGN_ENTITLEMENTS = ReactTestApp/ReactTestApp.entitlements;
415+
CODE_SIGN_ENTITLEMENTS = App.entitlements;
416416
CODE_SIGN_IDENTITY = "-";
417417
CODE_SIGN_STYLE = Automatic;
418418
COMBINE_HIDPI_IMAGES = YES;

macos/ReactTestApp/ReactTestApp.entitlements

Lines changed: 0 additions & 12 deletions
This file was deleted.

schema.json

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,16 @@
6262
]
6363
},
6464
"codeSignEntitlements": {
65-
"description": "Specifies the path to a custom [Entitlements](https://developer.apple.com/documentation/bundleresources/entitlements) file. The path should be relative to `app.json`.",
66-
"markdownDescription": "Specifies the path to a custom\n[Entitlements](https://developer.apple.com/documentation/bundleresources/entitlements)\nfile. The path should be relative to `app.json`.\n\nThis is the same as setting `CODE_SIGN_ENTITLEMENTS` in Xcode.\n\nIntroduced in\n[0.9.7](https://github.com/microsoft/react-native-test-app/releases/tag/0.9.7).",
67-
"type": "string"
65+
"description": "Declare entitlements for capabilities used by the app.",
66+
"markdownDescription": "Declare entitlements for capabilities used by the app.\n\nExample:\n\n```json\n{\n \"ios\": {\n \"codeSignEntitlements\": {\n \"com.apple.developer.game-center\": true\n }\n }\n}\n```\n\nFor more details, read Apple's documentation on\n[Entitlements](https://developer.apple.com/documentation/bundleresources/entitlements).\n\nAlternatively, specify a path to a custom `.entitlements` file. The path should\nbe relative to `app.json`. This is equivalent to setting\n`CODE_SIGN_ENTITLEMENTS` in Xcode.",
67+
"oneOf": [
68+
{
69+
"type": "string"
70+
},
71+
{
72+
"type": "object"
73+
}
74+
]
6875
},
6976
"codeSignIdentity": {
7077
"description": "Sets the <a href='https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html#//apple_ref/doc/uid/TP40005929-CH4-SW1'>code signing identity</a> to use when signing code.",
@@ -78,7 +85,7 @@
7885
},
7986
"privacyManifest": {
8087
"description": "The privacy manifest is a property list that records the information regarding the types of data collected and the required reasons APIs your app or third-party SDK use.",
81-
"markdownDescription": "The privacy manifest is a property list that records the information regarding\nthe types of data collected and the required reasons APIs your app or\nthird-party SDK use.\n\n- The types of data collected by your app or third-party SDK must be provided on\n all platforms.\n- The required reasons APIs your app or third-party SDK uses must be provided on\n iOS, iPadOS, tvOS, visionOS, and watchOS.\n\nBy default, a `PrivacyInfo.xcprivacy` is always generated with the following\nvalues:\n\n```json\n{\n \"NSPrivacyTracking\": false,\n \"NSPrivacyTrackingDomains\": [],\n \"NSPrivacyCollectedDataTypes\": [],\n \"NSPrivacyAccessedAPITypes\": [\n {\n \"NSPrivacyAccessedAPIType\": \"NSPrivacyAccessedAPICategoryFileTimestamp\",\n \"NSPrivacyAccessedAPITypeReasons\": [\"C617.1\"]\n },\n {\n \"NSPrivacyAccessedAPIType\": \"NSPrivacyAccessedAPICategorySystemBootTime\",\n \"NSPrivacyAccessedAPITypeReasons\": [\"35F9.1\"]\n },\n {\n \"NSPrivacyAccessedAPIType\": \"NSPrivacyAccessedAPICategoryUserDefaults\",\n \"NSPrivacyAccessedAPITypeReasons\": [\"CA92.1\"]\n }\n ]\n}\n```\n\nFor more details, read Apple's documentation on\n[Privacy manifest files](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files).",
88+
"markdownDescription": "The privacy manifest is a property list that records the information regarding\nthe types of data collected and the required reasons APIs your app or\nthird-party SDK use.\n\n- The types of data collected by your app or third-party SDK must be provided on\n all platforms.\n- The required reasons APIs your app or third-party SDK uses must be provided on\n iOS, iPadOS, tvOS, visionOS, and watchOS.\n\nBy default, a `PrivacyInfo.xcprivacy` is always generated with the following\nvalues:\n\n<!-- prettier-ignore-start -->\n```json\n{\n \"NSPrivacyTracking\": false,\n \"NSPrivacyTrackingDomains\": [],\n \"NSPrivacyCollectedDataTypes\": [],\n \"NSPrivacyAccessedAPITypes\": [\n {\n \"NSPrivacyAccessedAPIType\":\n \"NSPrivacyAccessedAPICategoryFileTimestamp\",\n \"NSPrivacyAccessedAPITypeReasons\": [\"C617.1\"]\n },\n {\n \"NSPrivacyAccessedAPIType\":\n \"NSPrivacyAccessedAPICategorySystemBootTime\",\n \"NSPrivacyAccessedAPITypeReasons\": [\"35F9.1\"]\n },\n {\n \"NSPrivacyAccessedAPIType\":\n \"NSPrivacyAccessedAPICategoryUserDefaults\",\n \"NSPrivacyAccessedAPITypeReasons\": [\"CA92.1\"]\n }\n ]\n}\n```\n<!-- prettier-ignore-end -->\n\nFor more details, read Apple's documentation on\n[Privacy manifest files](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files).",
8289
"type": "object"
8390
}
8491
}

scripts/config-plugins/plugins/withIosBaseMods.mjs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@ const defaultProviders = {
3030
"ReactTestApp.xcodeproj/project.pbxproj"
3131
),
3232
infoPlist: modifyFilePath(expoProviders.infoPlist, "Info.plist"),
33-
entitlements: modifyFilePath(
34-
expoProviders.entitlements,
35-
"ReactTestApp/ReactTestApp.entitlements"
36-
),
33+
entitlements: nullProvider,
3734
podfileProperties: nullProvider,
3835
};
3936

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
1-
Specifies the path to a custom
2-
[Entitlements](https://developer.apple.com/documentation/bundleresources/entitlements)
3-
file. The path should be relative to `app.json`.
1+
Declare entitlements for capabilities used by the app.
42

5-
This is the same as setting `CODE_SIGN_ENTITLEMENTS` in Xcode.
3+
Example:
64

7-
Introduced in
8-
[0.9.7](https://github.com/microsoft/react-native-test-app/releases/tag/0.9.7).
5+
```json
6+
{
7+
"ios": {
8+
"codeSignEntitlements": {
9+
"com.apple.developer.game-center": true
10+
}
11+
}
12+
}
13+
```
14+
15+
For more details, read Apple's documentation on
16+
[Entitlements](https://developer.apple.com/documentation/bundleresources/entitlements).
17+
18+
Alternatively, specify a path to a custom `.entitlements` file. The path should
19+
be relative to `app.json`. This is equivalent to setting
20+
`CODE_SIGN_ENTITLEMENTS` in Xcode.

scripts/docs/ios.privacyManifest.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,32 @@ third-party SDK use.
1010
By default, a `PrivacyInfo.xcprivacy` is always generated with the following
1111
values:
1212

13+
<!-- prettier-ignore-start -->
1314
```json
1415
{
1516
"NSPrivacyTracking": false,
1617
"NSPrivacyTrackingDomains": [],
1718
"NSPrivacyCollectedDataTypes": [],
1819
"NSPrivacyAccessedAPITypes": [
1920
{
20-
"NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryFileTimestamp",
21+
"NSPrivacyAccessedAPIType":
22+
"NSPrivacyAccessedAPICategoryFileTimestamp",
2123
"NSPrivacyAccessedAPITypeReasons": ["C617.1"]
2224
},
2325
{
24-
"NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategorySystemBootTime",
26+
"NSPrivacyAccessedAPIType":
27+
"NSPrivacyAccessedAPICategorySystemBootTime",
2528
"NSPrivacyAccessedAPITypeReasons": ["35F9.1"]
2629
},
2730
{
28-
"NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryUserDefaults",
31+
"NSPrivacyAccessedAPIType":
32+
"NSPrivacyAccessedAPICategoryUserDefaults",
2933
"NSPrivacyAccessedAPITypeReasons": ["CA92.1"]
3034
}
3135
]
3236
}
3337
```
38+
<!-- prettier-ignore-end -->
3439

3540
For more details, read Apple's documentation on
3641
[Privacy manifest files](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files).

0 commit comments

Comments
 (0)