diff --git a/Makefile b/Makefile index 773786633..6c81bb4f0 100644 --- a/Makefile +++ b/Makefile @@ -145,19 +145,22 @@ android-debug: .build/bundletool.jar android-keystore .PHONY: ios ios: app - xcodebuild \ - -workspace ./js/app/ios/Streamplace.xcworkspace \ + bash -eu -c ' \ + set -- ./js/app/ios/*.xcworkspace; \ + workspace="$$1"; \ + scheme="$${workspace##*/}"; \ + scheme="$${scheme%.xcworkspace}"; \ + xcodebuild \ + -workspace "$$workspace" \ -sdk iphoneos \ + -destination "generic/platform=iOS" \ -configuration Release \ - -scheme Streamplace \ + -scheme "$$scheme" \ -archivePath ./bin/streamplace-$(VERSION)-ios-release.xcarchive \ - CODE_SIGN_IDENTITY=- \ - AD_HOC_CODE_SIGNING_ALLOWED=YES \ - CODE_SIGN_STYLE=Automatic \ - DEVELOPMENT_TEAM=ZZZZZZZZZZ \ - clean archive | xcpretty \ + CODE_SIGNING_ALLOWED=NO \ + clean archive \ && cd bin \ - && tar -czvf streamplace-$(VERSION)-ios-release.xcarchive.tar.gz streamplace-$(VERSION)-ios-release.xcarchive + && tar -czvf streamplace-$(VERSION)-ios-release.xcarchive.tar.gz streamplace-$(VERSION)-ios-release.xcarchive' # _____ ____ # / ____|/ __ \ diff --git a/js/app/app.config.ts b/js/app/app.config.ts index 139c68fa5..9a41c3c82 100644 --- a/js/app/app.config.ts +++ b/js/app/app.config.ts @@ -3,6 +3,7 @@ import { withAndroidManifest, withDangerousMod, withEntitlementsPlist, + withPodfile, withXcodeProject, } from "expo/config-plugins"; import fs from "fs"; @@ -24,6 +25,30 @@ export const withoutNotificationsIOS: ConfigPlugin = (config) => { return config; }; +// React Native normalizes library targets, but not their privacy/resource bundles. +// Xcode 27 rejects those bundles' older deployment targets. +const withMinimumIOSDeploymentTarget: ConfigPlugin = (config) => + withPodfile(config, (config) => { + const hook = "post_install do |installer|"; + if (!config.modResults.contents.includes(hook)) { + throw new Error("Missing CocoaPods post_install hook"); + } + config.modResults.contents = config.modResults.contents.replace( + hook, + `${hook} + minimum = Gem::Version.new(min_ios_version_supported) + installer.pods_project.targets.each do |target| + target.build_configurations.each do |build_config| + current = build_config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] + if current && Gem::Version.new(current) < minimum + build_config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = minimum.to_s + end + end + end`, + ); + return config; + }); + const withAndroidProfileable = (config) => { return withAndroidManifest(config, (config) => { const androidManifest = config.modResults.manifest; @@ -297,6 +322,7 @@ export default function () { }, }, ], + withMinimumIOSDeploymentTarget, [ "expo-asset", { diff --git a/js/docs/src/content/docs/guides/start-contributing/streamplace-dev-setup.md b/js/docs/src/content/docs/guides/start-contributing/streamplace-dev-setup.md index f9495847e..1dd02c41d 100644 --- a/js/docs/src/content/docs/guides/start-contributing/streamplace-dev-setup.md +++ b/js/docs/src/content/docs/guides/start-contributing/streamplace-dev-setup.md @@ -109,6 +109,24 @@ pnpm run start #### iOS Build +iOS builds require full Xcode with the iOS SDK installed and CocoaPods on your +`PATH`. Select the intended Xcode installation with `xcode-select`. + +For a Release device archive, run `make ios`. It rebuilds the frontend and native +projects, selects the generated workspace and matching scheme (`Devplace` for +development, the configured brand name for production), and writes an unsigned +`.xcarchive` and `.xcarchive.tar.gz` under `bin/`. Set +`SP_PRODUCTION_RELEASE=true` for the production app. Signing/exporting the archive +for distribution is a separate step; installing on a physical device requires +your Apple development team and provisioning profile. + +Prebuild also raises pod deployment targets below React Native's minimum, +including privacy/resource bundles rejected by Xcode 27. Higher pod minimums are +preserved. Regenerate with `pnpm app prebuild` after changing native configuration; +do not edit generated Xcode projects or the Podfile. + +For a simulator or development-device build: + ```shell pnpm run app ios ```