GLM 4.5 Air

Titanium iOS Module Build Fix: Complete Guide

Fix Titanium iOS module build failures with simulator warnings. Learn why dependencies cause errors and how to resolve architecture mismatches when building for physical devices.

Question

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:

  1. Created a new Titanium iOS module
  2. Opened the generated .xcodeproj in Xcode
  3. Imported third-party Packages and .xcframeworks (copied to project root and added as dependencies)
  4. 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:

  1. Do I still need a physical device connected for a --build-only module build?
  2. 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)

GLM 4.5 Air

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

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:

  1. Titanium is detecting multiple build destinations (both simulators and devices)
  2. It’s defaulting to a simulator destination first, as shown by the warning: “Using the first of multiple matching destinations”
  3. Your dependencies only contain device slices (as noted by “SDK provider notes: no simulator slices provided”)
  4. 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:

  1. Development Workflow: Titanium’s default build configuration often includes simulators for testing purposes during development.

  2. Missing Device-Only Configuration: When no explicit device-only configuration is set, Titanium falls back to evaluating all available build destinations.

  3. 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.

  4. 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:

bash
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:

bash
# 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:

xcconfig
// 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:

python
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:

  1. Select your project in the Project Navigator
  2. Go to your target’s “Frameworks, Libraries, and Embedded Content”
  3. Verify the package dependencies are set to “Embed & Sign”
  4. 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:

swift
#if targetEnvironment(simulator)
    // Simulator-specific code
#else
    // Device-specific code
#endif

3. Architecture Validation

Add validation in your module to ensure proper architectures:

swift
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:

  1. Explicitly specify architectures
  2. Use proper SDK targets
  3. Handle both simulator and device configurations
  4. 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:

  1. Explicitly specify device-only builds using the --target-device iphone flag
  2. Ensure your dependencies include proper architecture slices
  3. Configure your module build settings for device-only architectures
  4. 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.