Titanium iOS Module Build Fails with xcodebuild Simulator Warnings Despite Physical Device Target
I’m encountering build errors when trying to generate a .zip file for a Titanium iOS module. The build fails only when dependencies (.xcframeworks / Packages) are included, but succeeds without them.
Environment:
- Titanium SDK: 12.7.1.GA
- Node.js: v22.17.0
- Xcode: 16.2
Steps Followed:
- Created a new Titanium iOS module
- Opened the generated .xcodeproj in Xcode
- Imported third-party Packages and .xcframeworks (copied to project root and added as dependencies)
- Attempted to build the module using:
ti build -p ios --build-only
Issue:
- Build fails only when dependencies (.xcframeworks / Packages) are included
- SDK provider notes: no simulator slices provided (device-only)
- Despite targeting a physical iPhone, the build still throws simulator-related architecture errors
Questions:
- Do I still need a physical device connected for a --build-only module build?
- Why does Titanium still reference simulator slices even when targeting a real device?
Error Message:
[ERROR] [xcode-sim] — xcodebuild: WARNING: Using the first of multiple matching destinations:
[ERROR] [xcode-sim] { platform:iOS Simulator, id:dvtdevice-DVTiOSDeviceSimulatorPlaceholder-iphonesimulator:placeholder, name:Any iOS Simulator Device }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:4F7BE224-2D3D-4702-B44B-937D9E36BF64, OS:18.3.1, name:iPad (10th generation) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:4F7BE224-2D3D-4702-B44B-937D9E36BF64, OS:18.3.1, name:iPad (10th generation) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:B97F0BA8-5249-4B1F-B54C-3753A4D7FB43, OS:18.3.1, name:iPad (A16) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:B97F0BA8-5249-4B1F-B54C-3753A4D7FB43, OS:18.3.1, name:iPad (A16) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:695ED476-5007-46FA-8BB4-DF40B2EF5F02, OS:18.3.1, name:iPad Air 11-inch (M2) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:695ED476-5007-46FA-8BB4-DF40B2EF5F02, OS:18.3.1, name:iPad Air 11-inch (M2) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:7373F603-6ED5-4484-8456-5229E724CBCE, OS:18.3.1, name:iPad Air 11-inch (M3) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:7373F603-6ED5-4484-8456-5229E724CBCE, OS:18.3.1, name:iPad Air 11-inch (M3) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:728B0D52-EE40-407D-BE1F-BD4B62D218D5, OS:18.3.1, name:iPad Air 13-inch (M2) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:728B0D52-EE40-407D-BE1F-BD4B62D218D5, OS:18.3.1, name:iPad Air 13-inch (M2) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:E154E704-3901-492B-A685-8F7CC1ECEBEB, OS:18.3.1, name:iPad Air 13-inch (M3) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:E154E704-3901-492B-A685-8F7CC1ECEBEB, OS:18.3.1, name:iPad Air 13-inch (M3) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:773FF7EA-C3FA-4705-A363-7CDFB482474D, OS:18.3.1, name:iPad Pro 11-inch (M4) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:773FF7EA-C3FA-4705-A363-7CDFB482474D, OS:18.3.1, name:iPad Pro 11-inch (M4) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:1A47D593-EE9E-4F7F-9C5D-6861DD476636, OS:18.3.1, name:iPad Pro 13-inch (M4) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:1A47D593-EE9E-4F7F-9C5D-6861DD476636, OS:18.3.1, name:iPad Pro 13-inch (M4) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:64A2762B-09D6-4F6C-9262-6346FB70030F, OS:18.3.1, name:iPad mini (A17 Pro) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:64A2762B-09D6-4F6C-9262-6346FB70030F, OS:18.3.1, name:iPad mini (A17 Pro) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:72E2FA73-C4D7-4D31-B89C-9D03DD95D467, OS:18.3.1, name:iPhone 16 }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:72E2FA73-C4D7-4D31-B89C-9D03DD95D467, OS:18.3.1, name:iPhone 16 }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:FCF33745-0970-43F9-BD88-C03EA31F439A, OS:18.3.1, name:iPhone 16 Plus }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:FCF33745-0970-43F9-BD88-C03EA31F439A, OS:18.3.1, name:iPhone 16 Plus }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:D8F785EE-D58A-4F22-AB7D-7A3985939361, OS:18.3.1, name:iPhone 16 Pro }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:D8F785EE-D58A-4F22-AB7D-7A3985939361, OS:18.3.1, name:iPhone 16 Pro }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:5331D689-16E8-47DD-BBC6-2F82D2355D8D, OS:18.3.1, name:iPhone 16 Pro Max }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:5331D689-16E8-47DD-BBC6-2F82D2355D8D, OS:18.3.1, name:iPhone 16 Pro Max }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:F30EBE5A-5E80-41C8-A922-1F694CC9172B, OS:18.3.1, name:iPhone 16e }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:F30EBE5A-5E80-41C8-A922-1F694CC9172B, OS:18.3.1, name:iPhone 16e }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:784A55D0-10F1-4134-B69F-5AD5EB2AD23E, OS:18.3.1, name:iPhone SE (3rd generation) }
[ERROR] [xcode-sim] { platform:iOS Simulator, id:784A55D0-10F1-4134-B69F-5AD5EB2AD23E, OS:18.3.1, name:iPhone SE (3rd generation) }
[ERROR] [xcode-sim] { platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Any iOS Device }
[ERROR] [xcode-sim] ** ARCHIVE FAILED **
[ERROR] [xcode-sim] The following build commands failed:
[ERROR] [xcode-sim] Archiving project TestModule with scheme ComSgaTest
[ERROR] [xcode-sim] (1 failure)
Titanium iOS Module Build Fails with Simulator Warnings Despite Physical Device Target
The build failure you’re experiencing occurs because your Titanium iOS module is attempting to build for simulators when you’ve specified device-only dependencies. Even though you’re targeting a physical device, the build process is still referencing simulator slices, which aren’t available in your dependencies. This mismatch causes the build to fail.
Contents
- Understanding the Core Issue
- Do You Need a Physical Device Connected?
- Why Titanium References Simulator Slices
- Solving the Build Failure
- Best Practices for Module Dependencies
- Troubleshooting Checklist
Understanding the Core Issue
When building a Titanium iOS module with external dependencies like .xcframeworks
or Swift Packages, the build process must generate slices for both simulators and physical devices. Your error message indicates that:
- Titanium is detecting multiple build destinations (both simulators and devices)
- It’s defaulting to a simulator destination first, as shown by the warning: “Using the first of multiple matching destinations”
- Your dependencies only contain device slices (as noted by “SDK provider notes: no simulator slices provided”)
- This architecture mismatch causes the build to fail
The key insight is that even when you specify --build-only
and intend to target a physical device, Titanium’s build system still evaluates all available destinations, including simulators.
Do You Need a Physical Device Connected?
For a Titanium module build with --build-only
flag, you do not need a physical device connected. The --build-only
flag specifically tells Titanium to:
- Generate the module package (.zip file)
- Not install it to a device or simulator
- Focus on the compilation and linking process
However, the issue isn’t about device connectivity—it’s about architecture compatibility. Titanium needs to know which architectures to build for, and when dependencies only provide device slices, the build process should default to device-only builds.
Why Titanium References Simulator Slices
Titanium references simulator slices for several reasons:
-
Development Workflow: Titanium’s default build configuration often includes simulators for testing purposes during development.
-
Missing Device-Only Configuration: When no explicit device-only configuration is set, Titanium falls back to evaluating all available build destinations.
-
Dependency Architecture: Your
.xcframeworks
or packages might be configured in a way that doesn’t properly communicate their device-only nature to the build system. -
Titanium’s Build System: The Titanium CLI might be defaulting to a “generic” build that checks all available destinations before determining the appropriate architecture.
Here’s what happens when you include dependencies without proper architecture configuration:
Titanium Build Process
|
v
Determine available destinations
|
v
[Simulators] [Devices]
| |
v v
Check dependencies Check dependencies
for slices for slices
| |
v v
Failure (no slices) Success (device slices)
Solving the Build Failure
Solution 1: Explicitly Specify Device-Only Build
Modify your build command to explicitly target a device:
ti build -p ios --build-only --target-device iphone
This tells Titanium to only consider device builds and ignore simulators.
Solution 2: Configure Your Dependencies Properly
For .xcframeworks
, ensure they contain the correct architecture slices. If you’re creating your own .xcframework
:
# Create device framework
xcodebuild -project YourProject.xcodeproj -scheme YourScheme -configuration Release -sdk iphoneos -arch arm64 -archivePath YourProject.xcarchive archive
# Create simulator framework
xcodebuild -project YourProject.xcodeproj -scheme YourScheme -configuration Release -sdk iphonesimulator -arch x86_64 -archivePath YourProject-sim.xcarchive archive
# Combine into universal xcframework
xcodebuild -create-xcframework -framework YourProject.xcarchive/Products/Library/Frameworks/YourProject.framework -framework YourProject-sim.xcarchive/Products/Library/Frameworks/YourProject.framework -output YourProject.xcframework
Solution 3: Modify Module Configuration
Update your module’s module.xcconfig
file to explicitly specify device-only architectures:
// module.xcconfig
ONLY_ACTIVE_ARCH = NO
VALID_ARCHS = arm64 arm64e
ARCHS = arm64 arm64e
Solution 4: Update Build Script in Your Module
In your Titanium module’s build.py
file, modify the build script to explicitly set device-only configuration:
def build titaniumSdk):
import os
import subprocess
# Get the path to the xcodeproj
xcodeproj_path = os.path.join(os.getcwd(), "YourModule.xcodeproj")
# Build for device only
cmd = ["xcodebuild", "-project", xcodeproj_path, "-scheme", "YourModule", "-configuration", "Release", "-sdk", "iphoneos", "archive"]
# Execute the command
subprocess.call(cmd)
Solution 5: Check and Update Your Package Dependencies
For Swift Package dependencies, ensure they’re properly configured to include device architectures. In Xcode:
- Select your project in the Project Navigator
- Go to your target’s “Frameworks, Libraries, and Embedded Content”
- Verify the package dependencies are set to “Embed & Sign”
- Check the “Platforms” section to ensure iOS is selected with appropriate architectures
Best Practices for Module Dependencies
1. Universal Frameworks
Always create universal .xcframeworks
that include:
- Device slices (arm64, arm64e)
- Simulator slices (x86_64, arm64 for Apple Silicon Macs)
2. Conditional Code
Use conditional compilation to separate simulator and device code:
#if targetEnvironment(simulator)
// Simulator-specific code
#else
// Device-specific code
#endif
3. Architecture Validation
Add validation in your module to ensure proper architectures:
import Foundation
public class ArchitectureValidator {
public static func validate() {
#if targetEnvironment(simulator)
print("Running on simulator")
#else
print("Running on device")
#endif
}
}
4. Proper Dependency Management
Use a dependency management tool like Swift Package Manager or CocoaPods to handle third-party libraries properly.
5. Build Script Best Practices
When creating Titanium modules, always:
- Explicitly specify architectures
- Use proper SDK targets
- Handle both simulator and device configurations
- Include error handling in build scripts
Troubleshooting Checklist
Before attempting to build your module, verify these items:
- [ ] Your
.xcframeworks
contain both simulator and device slices - [ ] Your Swift Packages are properly configured for iOS
- [ ] Your module’s
module.xcconfig
specifies correct architectures - [ ] You’re using the latest compatible versions of Titanium SDK and Xcode
- [ ] Your build script explicitly targets device-only builds
- [ ] All dependencies are correctly linked to your module target
- [ ] You’ve tried building with the
--target-device iphone
flag
Conclusion
The Titanium iOS module build failure with simulator warnings occurs because the build process is attempting to include simulator slices when your dependencies only provide device slices. To resolve this issue:
- Explicitly specify device-only builds using the
--target-device iphone
flag - Ensure your dependencies include proper architecture slices
- Configure your module build settings for device-only architectures
- Consider creating universal frameworks that include both simulator and device slices
By following these steps, you should be able to successfully build your Titanium iOS module with external dependencies, even when targeting physical devices. Remember that proper architecture configuration is essential when working with frameworks and packages in Titanium modules.