diff --git a/packages/config/src/ios/BundleIdentifier.ts b/packages/config/src/ios/BundleIdentifier.ts index 69ce6ec3bb..16cc341030 100644 --- a/packages/config/src/ios/BundleIdentifier.ts +++ b/packages/config/src/ios/BundleIdentifier.ts @@ -8,12 +8,8 @@ import { ExpoConfig } from '../Config.types'; import { InfoPlist } from './IosConfig.types'; import { ConfigurationSectionEntry, - Pbxproj, - getXCBuildConfigurationSection, - getXCConfigurationLists, - isBuildConfig, - isNotComment, - isNotTestHost, + findFirstNativeTarget, + getBuildConfigurationForId, } from './utils/Xcodeproj'; function getBundleIdentifier(config: ExpoConfig): string | null { @@ -56,10 +52,29 @@ function getBundleIdentifierFromPbxproj(projectRoot: string): string | null { } const project = Project(pbxprojPath); project.parseSync(); - for (const [, item] of getBuildConfigurationSectionEntires(project)) { - const bundleIdentifier = item.buildSettings.PRODUCT_BUNDLE_IDENTIFIER; - if (bundleIdentifier) { - return bundleIdentifier[0] === '"' ? bundleIdentifier.slice(1, -1) : bundleIdentifier; + + const nativeTarget = findFirstNativeTarget(project); + + for (const [, item] of getBuildConfigurationForId(project, nativeTarget.buildConfigurationList)) { + const bundleIdentifierRaw = item.buildSettings.PRODUCT_BUNDLE_IDENTIFIER; + if (bundleIdentifierRaw) { + const bundleIdentifier = + bundleIdentifierRaw[0] === '"' ? bundleIdentifierRaw.slice(1, -1) : bundleIdentifierRaw; + // it's possible to use interpolation for the bundle identifier + // the most common case is when the last part of the id is set to `$(PRODUCT_NAME:rfc1034identifier)` + // in this case, PRODUCT_NAME should be replaced with its value + // the `rfc1034identifier` modifier replaces all non-alphanumeric characters with dashes + const bundleIdentifierParts = bundleIdentifier.split('.'); + if ( + bundleIdentifierParts[bundleIdentifierParts.length - 1] === + '$(PRODUCT_NAME:rfc1034identifier)' && + item.buildSettings.PRODUCT_NAME + ) { + bundleIdentifierParts[ + bundleIdentifierParts.length - 1 + ] = item.buildSettings.PRODUCT_NAME.replace(/[^a-zA-Z0-9]/g, '-'); + } + return bundleIdentifierParts.join('.'); } } return null; @@ -79,32 +94,26 @@ function updateBundleIdentifierForPbxproj( ): void { const project = Project(pbxprojPath); project.parseSync(); - getBuildConfigurationSectionEntires(project).forEach(([, item]: ConfigurationSectionEntry) => { - if (item.buildSettings.PRODUCT_BUNDLE_IDENTIFIER === bundleIdentifier) { - return; - } - item.buildSettings.PRODUCT_BUNDLE_IDENTIFIER = `"${bundleIdentifier}"`; + const nativeTarget = findFirstNativeTarget(project); - if (updateProductName) { - const productName = bundleIdentifier.split('.').pop(); - if (!productName?.includes('$')) { - item.buildSettings.PRODUCT_NAME = productName; + getBuildConfigurationForId(project, nativeTarget.buildConfigurationList).forEach( + ([, item]: ConfigurationSectionEntry) => { + if (item.buildSettings.PRODUCT_BUNDLE_IDENTIFIER === bundleIdentifier) { + return; } - } - }); - fs.writeFileSync(pbxprojPath, project.writeSync()); -} -function getBuildConfigurationSectionEntires(project: Pbxproj): ConfigurationSectionEntry[] { - const configurationLists = getXCConfigurationLists(project); - const buildConfigurations = configurationLists[0].buildConfigurations.map(i => i.value); + item.buildSettings.PRODUCT_BUNDLE_IDENTIFIER = `"${bundleIdentifier}"`; - return Object.entries(getXCBuildConfigurationSection(project)) - .filter(isNotComment) - .filter(isBuildConfig) - .filter(isNotTestHost) - .filter(([key]: ConfigurationSectionEntry) => buildConfigurations.includes(key)); + if (updateProductName) { + const productName = bundleIdentifier.split('.').pop(); + if (!productName?.includes('$')) { + item.buildSettings.PRODUCT_NAME = productName; + } + } + } + ); + fs.writeFileSync(pbxprojPath, project.writeSync()); } /** diff --git a/packages/config/src/ios/ProvisioningProfile.ts b/packages/config/src/ios/ProvisioningProfile.ts index 7674491bbf..f9f6d5af3a 100644 --- a/packages/config/src/ios/ProvisioningProfile.ts +++ b/packages/config/src/ios/ProvisioningProfile.ts @@ -3,13 +3,11 @@ import fs from 'fs-extra'; import { ConfigurationSectionEntry, ProjectSectionEntry, + findFirstNativeTarget, + getBuildConfigurationForId, getPbxproj, getProjectSection, - getXCBuildConfigurationSection, - getXCConfigurationLists, - isBuildConfig, isNotComment, - isNotTestHost, } from './utils/Xcodeproj'; type ProvisioningProfileSettings = { @@ -22,17 +20,10 @@ function setProvisioningProfileForPbxproj( { profileName, appleTeamId }: ProvisioningProfileSettings ): void { const project = getPbxproj(projectRoot); + const nativeTarget = findFirstNativeTarget(project); - const configurationLists = getXCConfigurationLists(project); - // TODO(dsokal): figure out if configuring only the entries from the first configuration list is fine - const buildConfigurations = configurationLists[0].buildConfigurations.map(i => i.value); - - Object.entries(getXCBuildConfigurationSection(project)) - .filter(isNotComment) - .filter(isBuildConfig) - .filter(isNotTestHost) + getBuildConfigurationForId(project, nativeTarget.buildConfigurationList) .filter(([, item]: ConfigurationSectionEntry) => item.buildSettings.PRODUCT_NAME) - .filter(([key]: ConfigurationSectionEntry) => buildConfigurations.includes(key)) .forEach(([, item]: ConfigurationSectionEntry) => { item.buildSettings.PROVISIONING_PROFILE_SPECIFIER = `"${profileName}"`; item.buildSettings.DEVELOPMENT_TEAM = appleTeamId; diff --git a/packages/config/src/ios/__tests__/BundleIdentifier-test.ts b/packages/config/src/ios/__tests__/BundleIdentifier-test.ts index e6716f5748..5bedea4412 100644 --- a/packages/config/src/ios/__tests__/BundleIdentifier-test.ts +++ b/packages/config/src/ios/__tests__/BundleIdentifier-test.ts @@ -55,6 +55,19 @@ describe('BundleIdentifier module', () => { ); expect(getBundleIdentifierFromPbxproj(projectRoot)).toBe('org.name.testproject'); }); + + it('returns the bundle identifier for the first native target in project.pbxproj (project initialized with react-native init)', () => { + vol.fromJSON( + { + 'ios/testproject.xcodeproj/project.pbxproj': originalFs.readFileSync( + path.join(__dirname, 'fixtures/project-rni.pbxproj'), + 'utf-8' + ), + }, + projectRoot + ); + expect(getBundleIdentifierFromPbxproj(projectRoot)).toBe('org.reactjs.native.example.rni'); + }); }); describe(setBundleIdentifier, () => { diff --git a/packages/config/src/ios/__tests__/fixtures/project-rni.pbxproj b/packages/config/src/ios/__tests__/fixtures/project-rni.pbxproj new file mode 100644 index 0000000000..979c514e6b --- /dev/null +++ b/packages/config/src/ios/__tests__/fixtures/project-rni.pbxproj @@ -0,0 +1,970 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 00E356F31AD99517003FC87E /* rniTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* rniTests.m */; }; + 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; + 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; + 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; + 2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; + 2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; + 2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; + 2DCD954D1E0B4F2C00145EB5 /* rniTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* rniTests.m */; }; + 3D209D5DC7C6CACDC09AC8A4 /* libPods-rni-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A2390C992C475001DDD52CD /* libPods-rni-tvOSTests.a */; }; + 749B4FD657B6B6C59EFF2CE0 /* libPods-rni.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5DF65A22F9C7C006519F097 /* libPods-rni.a */; }; + 77AD55ED64C84E668F3D0E08 /* libPods-rni-rniTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 062FAD110C2894BA7D23A411 /* libPods-rni-rniTests.a */; }; + 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; + F217F9AB2C4EA0CEF5239E2C /* libPods-rni-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8645AACF4172ED4924707A76 /* libPods-rni-tvOS.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 13B07F861A680F5B00A75B9A; + remoteInfo = rni; + }; + 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2D02E47A1E0B4A5D006451C7; + remoteInfo = "rni-tvOS"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; + 00E356EE1AD99517003FC87E /* rniTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = rniTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 00E356F21AD99517003FC87E /* rniTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = rniTests.m; sourceTree = ""; }; + 062FAD110C2894BA7D23A411 /* libPods-rni-rniTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-rni-rniTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 108D851F9BAEFEEF140662F3 /* Pods-rni-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-rni-tvOS.release.xcconfig"; path = "Target Support Files/Pods-rni-tvOS/Pods-rni-tvOS.release.xcconfig"; sourceTree = ""; }; + 13B07F961A680F5B00A75B9A /* rni.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = rni.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = rni/AppDelegate.h; sourceTree = ""; }; + 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = rni/AppDelegate.m; sourceTree = ""; }; + 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = rni/Images.xcassets; sourceTree = ""; }; + 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = rni/Info.plist; sourceTree = ""; }; + 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = rni/main.m; sourceTree = ""; }; + 2D02E47B1E0B4A5D006451C7 /* rni-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "rni-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2D02E4901E0B4A5D006451C7 /* rni-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "rni-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6DB16D8BD99DA89989C888BF /* Pods-rni.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-rni.debug.xcconfig"; path = "Target Support Files/Pods-rni/Pods-rni.debug.xcconfig"; sourceTree = ""; }; + 785EEE6865A188FDFF567145 /* Pods-rni.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-rni.release.xcconfig"; path = "Target Support Files/Pods-rni/Pods-rni.release.xcconfig"; sourceTree = ""; }; + 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = rni/LaunchScreen.storyboard; sourceTree = ""; }; + 8645AACF4172ED4924707A76 /* libPods-rni-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-rni-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 86CE08887C95B6D8DA51702C /* Pods-rni-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-rni-tvOSTests.debug.xcconfig"; path = "Target Support Files/Pods-rni-tvOSTests/Pods-rni-tvOSTests.debug.xcconfig"; sourceTree = ""; }; + 890DFE3D9D81933EA73078BF /* Pods-rni-rniTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-rni-rniTests.release.xcconfig"; path = "Target Support Files/Pods-rni-rniTests/Pods-rni-rniTests.release.xcconfig"; sourceTree = ""; }; + 9A2390C992C475001DDD52CD /* libPods-rni-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-rni-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + B58A132EAC696A4F16277A0C /* Pods-rni-rniTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-rni-rniTests.debug.xcconfig"; path = "Target Support Files/Pods-rni-rniTests/Pods-rni-rniTests.debug.xcconfig"; sourceTree = ""; }; + D5DF65A22F9C7C006519F097 /* libPods-rni.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-rni.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + E2D036D902AB211F1D68525C /* Pods-rni-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-rni-tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-rni-tvOSTests/Pods-rni-tvOSTests.release.xcconfig"; sourceTree = ""; }; + ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; + ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; + EDE5B29BDC701F76BFEB920D /* Pods-rni-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-rni-tvOS.debug.xcconfig"; path = "Target Support Files/Pods-rni-tvOS/Pods-rni-tvOS.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 00E356EB1AD99517003FC87E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 77AD55ED64C84E668F3D0E08 /* libPods-rni-rniTests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 749B4FD657B6B6C59EFF2CE0 /* libPods-rni.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2D02E4781E0B4A5D006451C7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F217F9AB2C4EA0CEF5239E2C /* libPods-rni-tvOS.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2D02E48D1E0B4A5D006451C7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3D209D5DC7C6CACDC09AC8A4 /* libPods-rni-tvOSTests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 00E356EF1AD99517003FC87E /* rniTests */ = { + isa = PBXGroup; + children = ( + 00E356F21AD99517003FC87E /* rniTests.m */, + 00E356F01AD99517003FC87E /* Supporting Files */, + ); + path = rniTests; + sourceTree = ""; + }; + 00E356F01AD99517003FC87E /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 00E356F11AD99517003FC87E /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 13B07FAE1A68108700A75B9A /* rni */ = { + isa = PBXGroup; + children = ( + 008F07F21AC5B25A0029DE68 /* main.jsbundle */, + 13B07FAF1A68108700A75B9A /* AppDelegate.h */, + 13B07FB01A68108700A75B9A /* AppDelegate.m */, + 13B07FB51A68108700A75B9A /* Images.xcassets */, + 13B07FB61A68108700A75B9A /* Info.plist */, + 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */, + 13B07FB71A68108700A75B9A /* main.m */, + ); + name = rni; + sourceTree = ""; + }; + 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { + isa = PBXGroup; + children = ( + ED297162215061F000B7C4FE /* JavaScriptCore.framework */, + ED2971642150620600B7C4FE /* JavaScriptCore.framework */, + D5DF65A22F9C7C006519F097 /* libPods-rni.a */, + 062FAD110C2894BA7D23A411 /* libPods-rni-rniTests.a */, + 8645AACF4172ED4924707A76 /* libPods-rni-tvOS.a */, + 9A2390C992C475001DDD52CD /* libPods-rni-tvOSTests.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + 832341AE1AAA6A7D00B99B32 /* Libraries */ = { + isa = PBXGroup; + children = ( + ); + name = Libraries; + sourceTree = ""; + }; + 83CBB9F61A601CBA00E9B192 = { + isa = PBXGroup; + children = ( + 13B07FAE1A68108700A75B9A /* rni */, + 832341AE1AAA6A7D00B99B32 /* Libraries */, + 00E356EF1AD99517003FC87E /* rniTests */, + 83CBBA001A601CBA00E9B192 /* Products */, + 2D16E6871FA4F8E400B85C8A /* Frameworks */, + F98575023348D84326C5442C /* Pods */, + ); + indentWidth = 2; + sourceTree = ""; + tabWidth = 2; + usesTabs = 0; + }; + 83CBBA001A601CBA00E9B192 /* Products */ = { + isa = PBXGroup; + children = ( + 13B07F961A680F5B00A75B9A /* rni.app */, + 00E356EE1AD99517003FC87E /* rniTests.xctest */, + 2D02E47B1E0B4A5D006451C7 /* rni-tvOS.app */, + 2D02E4901E0B4A5D006451C7 /* rni-tvOSTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + F98575023348D84326C5442C /* Pods */ = { + isa = PBXGroup; + children = ( + 6DB16D8BD99DA89989C888BF /* Pods-rni.debug.xcconfig */, + 785EEE6865A188FDFF567145 /* Pods-rni.release.xcconfig */, + B58A132EAC696A4F16277A0C /* Pods-rni-rniTests.debug.xcconfig */, + 890DFE3D9D81933EA73078BF /* Pods-rni-rniTests.release.xcconfig */, + EDE5B29BDC701F76BFEB920D /* Pods-rni-tvOS.debug.xcconfig */, + 108D851F9BAEFEEF140662F3 /* Pods-rni-tvOS.release.xcconfig */, + 86CE08887C95B6D8DA51702C /* Pods-rni-tvOSTests.debug.xcconfig */, + E2D036D902AB211F1D68525C /* Pods-rni-tvOSTests.release.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 00E356ED1AD99517003FC87E /* rniTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "rniTests" */; + buildPhases = ( + B4DDD0DD499D616551F29E5A /* [CP] Check Pods Manifest.lock */, + 00E356EA1AD99517003FC87E /* Sources */, + 00E356EB1AD99517003FC87E /* Frameworks */, + 00E356EC1AD99517003FC87E /* Resources */, + 767EF98B5E9AD92FBD0366BB /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 00E356F51AD99517003FC87E /* PBXTargetDependency */, + ); + name = rniTests; + productName = rniTests; + productReference = 00E356EE1AD99517003FC87E /* rniTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 13B07F861A680F5B00A75B9A /* rni */ = { + isa = PBXNativeTarget; + buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "rni" */; + buildPhases = ( + CBEB0A65CD52E6DBC7F008AB /* [CP] Check Pods Manifest.lock */, + FD10A7F022414F080027D42C /* Start Packager */, + 13B07F871A680F5B00A75B9A /* Sources */, + 13B07F8C1A680F5B00A75B9A /* Frameworks */, + 13B07F8E1A680F5B00A75B9A /* Resources */, + 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, + C62BE4C575C9D06234A6EF69 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = rni; + productName = rni; + productReference = 13B07F961A680F5B00A75B9A /* rni.app */; + productType = "com.apple.product-type.application"; + }; + 2D02E47A1E0B4A5D006451C7 /* rni-tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "rni-tvOS" */; + buildPhases = ( + 507EC67E600D2A5E159987E2 /* [CP] Check Pods Manifest.lock */, + FD10A7F122414F3F0027D42C /* Start Packager */, + 2D02E4771E0B4A5D006451C7 /* Sources */, + 2D02E4781E0B4A5D006451C7 /* Frameworks */, + 2D02E4791E0B4A5D006451C7 /* Resources */, + 2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "rni-tvOS"; + productName = "rni-tvOS"; + productReference = 2D02E47B1E0B4A5D006451C7 /* rni-tvOS.app */; + productType = "com.apple.product-type.application"; + }; + 2D02E48F1E0B4A5D006451C7 /* rni-tvOSTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "rni-tvOSTests" */; + buildPhases = ( + 442E7174B20BEA5B10FD9B8D /* [CP] Check Pods Manifest.lock */, + 2D02E48C1E0B4A5D006451C7 /* Sources */, + 2D02E48D1E0B4A5D006451C7 /* Frameworks */, + 2D02E48E1E0B4A5D006451C7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */, + ); + name = "rni-tvOSTests"; + productName = "rni-tvOSTests"; + productReference = 2D02E4901E0B4A5D006451C7 /* rni-tvOSTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 83CBB9F71A601CBA00E9B192 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1130; + TargetAttributes = { + 00E356ED1AD99517003FC87E = { + CreatedOnToolsVersion = 6.2; + TestTargetID = 13B07F861A680F5B00A75B9A; + }; + 13B07F861A680F5B00A75B9A = { + LastSwiftMigration = 1120; + }; + 2D02E47A1E0B4A5D006451C7 = { + CreatedOnToolsVersion = 8.2.1; + ProvisioningStyle = Automatic; + }; + 2D02E48F1E0B4A5D006451C7 = { + CreatedOnToolsVersion = 8.2.1; + ProvisioningStyle = Automatic; + TestTargetID = 2D02E47A1E0B4A5D006451C7; + }; + }; + }; + buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "rni" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 83CBB9F61A601CBA00E9B192; + productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 13B07F861A680F5B00A75B9A /* rni */, + 00E356ED1AD99517003FC87E /* rniTests */, + 2D02E47A1E0B4A5D006451C7 /* rni-tvOS */, + 2D02E48F1E0B4A5D006451C7 /* rni-tvOSTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 00E356EC1AD99517003FC87E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 13B07F8E1A680F5B00A75B9A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */, + 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2D02E4791E0B4A5D006451C7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2D02E48E1E0B4A5D006451C7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Bundle React Native code and images"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; + }; + 2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Bundle React Native Code And Images"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; + }; + 442E7174B20BEA5B10FD9B8D /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-rni-tvOSTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 507EC67E600D2A5E159987E2 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-rni-tvOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 767EF98B5E9AD92FBD0366BB /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-rni-rniTests/Pods-rni-rniTests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-rni-rniTests/Pods-rni-rniTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + B4DDD0DD499D616551F29E5A /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-rni-rniTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + C62BE4C575C9D06234A6EF69 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-rni/Pods-rni-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-rni/Pods-rni-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + CBEB0A65CD52E6DBC7F008AB /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-rni-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + FD10A7F022414F080027D42C /* Start Packager */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Start Packager"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; + showEnvVarsInLog = 0; + }; + FD10A7F122414F3F0027D42C /* Start Packager */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Start Packager"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 00E356EA1AD99517003FC87E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 00E356F31AD99517003FC87E /* rniTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 13B07F871A680F5B00A75B9A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, + 13B07FC11A68108700A75B9A /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2D02E4771E0B4A5D006451C7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */, + 2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2D02E48C1E0B4A5D006451C7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2DCD954D1E0B4F2C00145EB5 /* rniTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 13B07F861A680F5B00A75B9A /* rni */; + targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; + }; + 2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 2D02E47A1E0B4A5D006451C7 /* rni-tvOS */; + targetProxy = 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 00E356F61AD99517003FC87E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B58A132EAC696A4F16277A0C /* Pods-rni-rniTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = rniTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + OTHER_LDFLAGS = ( + "-ObjC", + "-lc++", + "$(inherited)", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/rni.app/rni"; + }; + name = Debug; + }; + 00E356F71AD99517003FC87E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 890DFE3D9D81933EA73078BF /* Pods-rni-rniTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + COPY_PHASE_STRIP = NO; + INFOPLIST_FILE = rniTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + OTHER_LDFLAGS = ( + "-ObjC", + "-lc++", + "$(inherited)", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/rni.app/rni"; + }; + name = Release; + }; + 13B07F941A680F5B00A75B9A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6DB16D8BD99DA89989C888BF /* Pods-rni.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = 1; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = rni/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-lc++", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = rni; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 13B07F951A680F5B00A75B9A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 785EEE6865A188FDFF567145 /* Pods-rni.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = 1; + INFOPLIST_FILE = rni/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-lc++", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = rni; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; + 2D02E4971E0B4A5E006451C7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EDE5B29BDC701F76BFEB920D /* Pods-rni-tvOS.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "rni-tvOS/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-lc++", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.rni-tvOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Debug; + }; + 2D02E4981E0B4A5E006451C7 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 108D851F9BAEFEEF140662F3 /* Pods-rni-tvOS.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "rni-tvOS/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-lc++", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.rni-tvOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Release; + }; + 2D02E4991E0B4A5E006451C7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 86CE08887C95B6D8DA51702C /* Pods-rni-tvOSTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "rni-tvOSTests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-lc++", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.rni-tvOSTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/rni-tvOS.app/rni-tvOS"; + TVOS_DEPLOYMENT_TARGET = 10.1; + }; + name = Debug; + }; + 2D02E49A1E0B4A5E006451C7 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E2D036D902AB211F1D68525C /* Pods-rni-tvOSTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "rni-tvOSTests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-lc++", + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.rni-tvOSTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/rni-tvOS.app/rni-tvOS"; + TVOS_DEPLOYMENT_TARGET = 10.1; + }; + name = Release; + }; + 83CBBA201A601CBA00E9B192 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)"; + LIBRARY_SEARCH_PATHS = ( + "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", + "\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"", + "\"$(inherited)\"", + ); + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 83CBBA211A601CBA00E9B192 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)"; + LIBRARY_SEARCH_PATHS = ( + "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", + "\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"", + "\"$(inherited)\"", + ); + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "rniTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 00E356F61AD99517003FC87E /* Debug */, + 00E356F71AD99517003FC87E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "rni" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 13B07F941A680F5B00A75B9A /* Debug */, + 13B07F951A680F5B00A75B9A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "rni-tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2D02E4971E0B4A5E006451C7 /* Debug */, + 2D02E4981E0B4A5E006451C7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "rni-tvOSTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2D02E4991E0B4A5E006451C7 /* Debug */, + 2D02E49A1E0B4A5E006451C7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "rni" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 83CBBA201A601CBA00E9B192 /* Debug */, + 83CBBA211A601CBA00E9B192 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; +} diff --git a/packages/config/src/ios/utils/Xcodeproj.ts b/packages/config/src/ios/utils/Xcodeproj.ts index 383c1f4fd2..8416ec08a2 100644 --- a/packages/config/src/ios/utils/Xcodeproj.ts +++ b/packages/config/src/ios/utils/Xcodeproj.ts @@ -76,6 +76,7 @@ export type ProjectSectionItem = { targets: { value: string; }[]; + buildConfigurationList: string; }; export type ProjectSectionEntry = [string, ProjectSectionItem]; @@ -83,6 +84,29 @@ export function getProjectSection(project: Pbxproj): ProjectSection { return project.pbxProjectSection(); } +export type NativeTargetSection = Record; +export type NativeTargetSectionItem = { + isa: 'PBXNativeTarget'; + buildConfigurationList: string; +}; +export type NativeTargetSectionEntry = [string, NativeTargetSectionItem]; + +export function getNativeTargets(project: Pbxproj): NativeTargetSectionEntry[] { + const section = project.pbxNativeTargetSection() as NativeTargetSection; + return Object.entries(section).filter(isNotComment); +} + +export function findFirstNativeTarget(project: Pbxproj): NativeTargetSectionItem { + const { targets } = Object.values(getProjectSection(project))[0]; + const target = targets[0].value; + + const nativeTargets = getNativeTargets(project); + const nativeTarget = (nativeTargets.find( + ([key]) => key === target + ) as NativeTargetSectionEntry)[1]; + return nativeTarget; +} + export type ConfigurationLists = Record; export type ConfigurationList = { isa: string; @@ -90,13 +114,11 @@ export type ConfigurationList = { value: string; }[]; }; -export type ConfigurationListsEntry = [string, ConfigurationList]; +export type ConfigurationListEntry = [string, ConfigurationList]; -export function getXCConfigurationLists(project: Pbxproj): ConfigurationList[] { +export function getXCConfigurationListEntries(project: Pbxproj): ConfigurationListEntry[] { const lists = project.pbxXCConfigurationList() as ConfigurationLists; - return Object.entries(lists) - .filter(isNotComment) - .map(([, value]) => value); + return Object.entries(lists).filter(isNotComment); } export type ConfigurationSection = Record; @@ -118,6 +140,24 @@ export function getXCBuildConfigurationSection(project: Pbxproj): ConfigurationS return project.pbxXCBuildConfigurationSection(); } +export function getBuildConfigurationForId( + project: Pbxproj, + configurationListId: string +): ConfigurationSectionEntry[] { + const configurationListEntries = getXCConfigurationListEntries(project); + const [, configurationList] = configurationListEntries.find( + ([key]) => key === configurationListId + ) as ConfigurationListEntry; + + const buildConfigurations = configurationList.buildConfigurations.map(i => i.value); + + return Object.entries(getXCBuildConfigurationSection(project)) + .filter(isNotComment) + .filter(isBuildConfig) + .filter(isNotTestHost) + .filter(([key]: ConfigurationSectionEntry) => buildConfigurations.includes(key)); +} + export function isBuildConfig([, sectionItem]: ConfigurationSectionEntry): boolean { return sectionItem.isa === 'XCBuildConfiguration'; } @@ -129,6 +169,7 @@ export function isNotTestHost([, sectionItem]: ConfigurationSectionEntry): boole export function isNotComment([key]: | ConfigurationSectionEntry | ProjectSectionEntry - | ConfigurationListsEntry): boolean { + | ConfigurationListEntry + | NativeTargetSectionEntry): boolean { return !key.endsWith(`_comment`); } diff --git a/packages/expo-cli/src/commands/eas-build/build/action.ts b/packages/expo-cli/src/commands/eas-build/build/action.ts index 03f426fbfa..9787c8cb80 100644 --- a/packages/expo-cli/src/commands/eas-build/build/action.ts +++ b/packages/expo-cli/src/commands/eas-build/build/action.ts @@ -18,7 +18,11 @@ import { Build, BuildCommandPlatform, BuildStatus } from '../types'; import AndroidBuilder from './builders/AndroidBuilder'; import iOSBuilder from './builders/iOSBuilder'; import { Builder, BuilderContext } from './types'; -import { ensureGitStatusIsCleanAsync, makeProjectTarballAsync } from './utils/git'; +import { + ensureGitRepoExistsAsync, + ensureGitStatusIsCleanAsync, + makeProjectTarballAsync, +} from './utils/git'; import { printBuildResults, printLogsUrls } from './utils/misc'; interface BuildOptions { @@ -44,6 +48,7 @@ async function buildAction(projectDir: string, options: BuildOptions): Promise { + try { + await commandExists('git'); + } catch (err) { + throw new Error('git command has not been found, install it before proceeding'); + } + + if (await gitDoesRepoExistAsync()) { + return; + } + + log(log.chalk.yellow("It looks like you haven't initialized the git repository yet.")); + log(log.chalk.yellow('EAS Build requires you to use a git repository for your project.')); + + const { confirmInit } = await prompts({ + type: 'confirm', + name: 'confirmInit', + message: `Would you like to run 'git init' in the current directory?`, + }); + if (!confirmInit) { + throw new Error( + 'A git repository is required for building your project. Initialize it and run this command again.' + ); + } + await spawnAsync('git', ['init']); + + log("We're going to make an initial commit for you repository."); + + const { message } = await prompts({ + type: 'text', + name: 'message', + message: 'Commit message:', + initial: 'Initial commit', + validate: input => input !== '', + }); + await spawnAsync('git', ['add', '-A']); + await spawnAsync('git', ['commit', '-m', message]); +} + async function ensureGitStatusIsCleanAsync(): Promise { const changes = await gitStatusAsync(); if (changes.length > 0) { @@ -75,6 +115,7 @@ async function reviewAndCommitChangesAsync( export { DirtyGitTreeError, + ensureGitRepoExistsAsync, ensureGitStatusIsCleanAsync, makeProjectTarballAsync, reviewAndCommitChangesAsync, diff --git a/packages/expo-cli/src/git.ts b/packages/expo-cli/src/git.ts index de576dda83..211a36b5ed 100644 --- a/packages/expo-cli/src/git.ts +++ b/packages/expo-cli/src/git.ts @@ -4,21 +4,29 @@ interface GitStatusOptions { showUntracked?: boolean; } -export async function gitStatusAsync({ showUntracked }: GitStatusOptions = {}): Promise { +async function gitStatusAsync({ showUntracked }: GitStatusOptions = {}): Promise { return (await spawnAsync('git', ['status', '-s', showUntracked ? '-uall' : '-uno'])).stdout; } -export async function gitDiffAsync(): Promise { +async function gitDiffAsync(): Promise { await spawnAsync('git', ['--no-pager', 'diff'], { stdio: ['ignore', 'inherit', 'inherit'] }); } -export async function gitAddAsync( - file: string, - options?: { intentToAdd?: boolean } -): Promise { +async function gitAddAsync(file: string, options?: { intentToAdd?: boolean }): Promise { if (options?.intentToAdd) { await spawnAsync('git', ['add', '--intent-to-add', file]); } else { await spawnAsync('git', ['add', file]); } } + +async function gitDoesRepoExistAsync(): Promise { + try { + await spawnAsync('git', ['rev-parse', '--git-dir']); + return true; + } catch (err) { + return false; + } +} + +export { gitStatusAsync, gitDiffAsync, gitAddAsync, gitDoesRepoExistAsync };