React Native iOS Pipeline
Issue #12876 - CI/CD implementation tracking
iOS development requires a macOS environment and enrollment in the Apple Developer Program ($99/year) to deploy applications to physical devices and distribute through the App Store. This guide covers code signing, provisioning profiles, CI/CD setup, and best practices for building iOS applications at KBVE.
Our React Native iOS applications use Expo for streamlined development and deployment workflows, with custom native modules when needed for advanced features.
Apple’s code signing system ensures app integrity and prevents unauthorized modifications. All iOS apps must be signed before deployment to devices or the App Store.
Apple Developer Account
Development Environment
xcode-select --installsudo gem install cocoapodsBundle Identifier
com.kbve.appiOS App Development Certificate
Used for testing on physical devices during development.
# Generate via Xcode (automatic)# Or manually via Keychain Access → Certificate Assistant → Request from CA
# Export as .p12 (for CI/CD)# Keychain Access → Right-click certificate → ExportApple Distribution Certificate
Required for App Store and ad-hoc distribution.
# Generate via Apple Developer portal or Xcode# Export as .p12 file with password for GitHub secrets
# Export to base64 for GitHub Actionsbase64 -i certificate.p12 | pbcopyProvisioning profiles link certificates, app IDs, and device UDIDs together.
| Type | Use Case | Device Registration |
|---|---|---|
| Development | Testing on registered devices | Required |
| Ad Hoc | Beta testing outside TestFlight | Required (max 100 devices) |
| App Store | App Store distribution | Not required |
# Export provisioning profile to base64base64 -i profile.mobileprovision | pbcopyAdd these secrets to your repository for CI/CD workflows.
| Secret Name | Description | How to Generate |
|---|---|---|
APPLE_CERT_DATA | Base64-encoded .p12 certificate | base64 -i certificate.p12 | pbcopy |
APPLE_CERT_PASSWORD | Password for .p12 file | Set when exporting certificate |
PROVISIONING_PROFILE_DATA | Base64-encoded .mobileprovision | base64 -i profile.mobileprovision | pbcopy |
Our React Native iOS builds use GitHub Actions with macOS runners.
Located at .github/workflows/ci-react-native-ios.yml
For development and CI testing (no certificates required)
# Trigger via GitHub Actions# task: build# skip_signing: trueProduces unsigned simulator build (x86_64) for testing purposes.
For device testing and App Store distribution
# Requires GitHub secrets configured# task: build# skip_signing: falseProduces signed IPA for TestFlight or App Store submission.
Verify macOS runner environment
# task: mac-setupValidates Xcode, Node.js, CocoaPods installation.
The exportOptions.plist file controls how the IPA is packaged.
exportOptions.plist Template:
<?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>method</key> <string>app-store</string> <key>teamID</key> <string>YOUR_TEAM_ID</string> <key>uploadBitcode</key> <false/> <key>compileBitcode</key> <false/> <key>uploadSymbols</key> <true/> <key>signingStyle</key> <string>manual</string> <key>provisioningProfiles</key> <dict> <key>com.kbve.app</key> <string>YOUR_PROVISIONING_PROFILE_NAME</string> </dict></dict></plist>- name: Import signing certificate env: APPLE_CERT_DATA: ${{ secrets.APPLE_CERT_DATA }} APPLE_CERT_PASSWORD: ${{ secrets.APPLE_CERT_PASSWORD }} run: | # Create temporary keychain KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db KEYCHAIN_PASSWORD=$(uuidgen)
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH security set-keychain-settings -lut 21600 $KEYCHAIN_PATH security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# Import certificate echo "$APPLE_CERT_DATA" | base64 --decode > certificate.p12 security import certificate.p12 \ -P "$APPLE_CERT_PASSWORD" \ -A \ -t cert \ -f pkcs12 \ -k $KEYCHAIN_PATH security list-keychain -d user -s $KEYCHAIN_PATH- name: Install provisioning profile env: PROVISIONING_PROFILE_DATA: ${{ secrets.PROVISIONING_PROFILE_DATA }} run: | mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles echo "$PROVISIONING_PROFILE_DATA" | base64 --decode > \ ~/Library/MobileDevice/Provisioning\ Profiles/profile.mobileprovision- name: Build signed app run: | xcodebuild \ -workspace *.xcworkspace \ -scheme "kbvereactnative" \ -configuration Release \ -sdk iphoneos \ -archivePath ./build/App.xcarchive \ archive
xcodebuild \ -exportArchive \ -archivePath ./build/App.xcarchive \ -exportPath ./build \ -exportOptionsPlist exportOptions.plistVerify builds work locally before pushing to CI/CD.
# Navigate to React Native appcd apps/kbve/kbve-react-native
# Generate iOS native projectnpx expo prebuild --platform ios --clean
# Install CocoaPods dependenciescd iospod install
# Build for simulator (unsigned)xcodebuild \ -workspace *.xcworkspace \ -scheme kbvereactnative \ -configuration Release \ -sdk iphonesimulator \ build
# Build for device (requires signing)xcodebuild \ -workspace *.xcworkspace \ -scheme kbvereactnative \ -configuration Release \ -sdk iphoneos \ -archivePath ./build/App.xcarchive \ archiveSymptoms: errSecInternalComponent or certificate errors during build
Solutions:
APPLE_CERT_DATA is valid base64APPLE_CERT_PASSWORDSymptoms: No profiles for 'com.kbve.app' were found
Solutions:
com.kbve.appSymptoms: Code signing is required for product type 'Application'
Solutions:
Symptoms: pod install fails or missing native modules
Solutions:
# Clear CocoaPods cachecd iospod cache clean --allrm -rf Pods Podfile.lock
# Reinstallpod install --repo-updateKBVE also builds iOS applications using Unreal Engine 5. The UE5 iOS pipeline shares the same Apple Developer infrastructure (certificates, provisioning profiles, Team ID) as React Native builds.
Key Differences from React Native:
GenerateProjectFiles.sh or UE5 EditorThe UE5 iOS CI/CD pipeline is currently under development. See Issue #12875 for tracking.
Planned Tasks:
Shared Infrastructure:
Both React Native and UE5 iOS builds use the same:
APPLE_CERT_DATA, APPLE_CERT_PASSWORD)PROVISIONING_PROFILE_DATA)# Generate Xcode project from .uproject# (Run on macOS with UE5 installed)/Path/To/UE_5.X/Engine/Build/BatchFiles/Mac/GenerateProjectFiles.sh \ -project="/Path/To/YourProject.uproject" \ -platforms=iOS
# Build via UnrealBuildTool/Path/To/UE_5.X/Engine/Build/BatchFiles/RunUBT.sh \ YourProjectEditor iOS Development \ -project="/Path/To/YourProject.uproject"
# Package for distribution/Path/To/UE_5.X/Engine/Build/BatchFiles/RunUAT.sh BuildCookRun \ -project="/Path/To/YourProject.uproject" \ -platform=iOS \ -clientconfig=Shipping \ -cook -stage -archive -packageReact Native iOS Pipeline
Issue #12876 - CI/CD implementation tracking
UE5 iOS Builds
Issue #12875 - Shares Apple Developer setup
Unreal Engine Guide
Unreal Engine docs - KBVE UE5 development guide
Apple Developer Portal
developer.apple.com - Certificates and profiles
Expo iOS Builds
Expo iOS docs - Expo-specific build configuration
UE5 iOS Documentation
UE5 iOS Guide - Official Epic Games docs
Enroll in Apple Developer Program
Generate Certificates
Create Provisioning Profile
com.kbve.appConfigure GitHub Secrets
APPLE_CERT_DATA, APPLE_CERT_PASSWORD, PROVISIONING_PROFILE_DATAexportOptions.plist with Team ID and profile nameTest Build Workflow
skip_signing: true first (unsigned)skip_signing: false (signed)Optional: Setup Fastlane
match