如何在Tuist中开启“仅在安装时复制”选项解决iOS应用安装失败?
问题描述
我正在用Tuist迁移一个包含2个扩展的iOS项目。用Tuist生成项目后,主应用目标必须手动开启“仅在安装时复制”选项才能成功编译运行。请问有没有办法通过tuist edit配置这个选项?折腾好几天都没搞定,求帮忙。
更新内容:扩展目标的Tuist配置代码
private static func makeExtensionTargets( name: String, appBundleId: String, bundleIdPostFix: String) -> [Target] { if name == "ext-notiservice" { let source = Target.target( name: name, destinations: .iOS, product: .appExtension, bundleId: "\(appBundleId).\(bundleIdPostFix)", deploymentTargets: .iOS("14.0"), infoPlist: .file(path: .relativeToRoot("Targets/\(name)/Supporting Files/Info.plist")), sources: ["Targets/\(name)/Sources/**"], entitlements: .file(path: .relativeToRoot("Targets/\(name)/Supporting Files/\(name).entitlements")), dependencies: [ .xcframework(path: .relativeToRoot("Targets/\(name)/frameworks/BrazeNotificationService.xcframework")), ] ) return [source] } else if name == "ext-noticontent" { let sources = Target.target( name: name, destinations: .iOS, product: .appExtension, bundleId: "\(appBundleId).\(bundleIdPostFix)", deploymentTargets: .iOS("14.0"), infoPlist: .file(path: .relativeToRoot("Targets/\(name)/Supporting Files/Info.plist")), sources: ["Targets/\(name)/Sources/**"], resources: ["Targets/\(name)/Resources/**/*.*"], dependencies: [.xcframework(path: .relativeToRoot("Targets/\(name)/frameworks/BrazePushStory.xcframework"))] ) return [sources] } return [] }
更新内容:错误信息
无法安装"MYAPP" Domain: com.apple.dt.MobileDeviceErrorDomain 代码: -402653081 恢复建议: 请检查项目设置,确保已构建有效的产品。 用户信息: { DVTErrorCreationDateKey = "2024-09-09 01:36:56 +0000"; IDERunOperationFailingWorker = IDEInstalliPhoneLauncher; } -- 无法安装"MYAPP" Domain: com.apple.dt.MobileDeviceErrorDomain 代码: -402653081 恢复建议: 请检查项目设置,确保已构建有效的产品。 用户信息: { IDERunOperationFailingWorker = IDEInstalliPhoneLauncher; } -- 发生内部API错误。 Domain: com.apple.dt.MobileDeviceErrorDomain 代码: -402653081 用户信息: { DVTRadarComponentKey = 261622; MobileDeviceErrorCode = "(0xE8000067)"; "com.apple.dtdevicekit.stacktrace" = ( 0 DTDeviceKitBase 0x000000010eb07670 DTDKCreateNSErrorFromAMDErrorCode + 300 1 DTDeviceKitBase 0x000000010eb342e0 __90-[DTDKMobileDeviceToken installApplicationBundleAtPath:withOptions:andError:withCallback:]_block_invoke + 136 2 DVTFoundation 0x0000000101f1799c DVTInvokeWithStrongOwnership + 76 3 DTDeviceKitBase 0x000000010eb34064 -[DTDKMobileDeviceToken installApplicationBundleAtPath:withOptions:andError:withCallback:] + 1168 4 IDEiOSSupportCore 0x0000000111f1f41c __118-[DVTiOSDevice(DVTiPhoneApplicationInstallation) processAppInstallSet:appUninstallSet:installOptions:completionBlock:]_block_invoke.151 + 2344 5 DVTFoundation 0x0000000102028578 __DVT_CALLING_CLIENT_BLOCK__ + 16 6 DVTFoundation 0x0000000102028fa0 __DVTDispatchAsync_block_invoke + 152 7 libdispatch.dylib 0x0000000184a0c750 _dispatch_call_block_and_release + 32 8 libdispatch.dylib 0x0000000184a0e3e8 _dispatch_client_callout + 20 9 libdispatch.dylib 0x0000000184a15a14 _dispatch_lane_serial_drain + 748 10 libdispatch.dylib 0x0000000184a16544 _dispatch_lane_invoke + 380 11 libdispatch.dylib 0x0000000184a212d0 _dispatch_root_queue_drain_deferred_wlh + 288 12 libdispatch.dylib 0x0000000184a20b44 _dispatch_workloop_worker_thread + 404 13 libsystem_pthread.dylib 0x0000000184bbb00c _pthread_wqthread + 288 14 libsystem_pthread.dylib 0x0000000184bb9d28 start_wqthread + 8 ); } -- 事件元数据: com.apple.dt.IDERunOperationWorkerFinished : { "device_model" = "iPhone15,2"; "device_osBuild" = "16.2 (20C65)"; "device_platform" = "com.apple.platform.iphoneos"; "dvt_coredevice_version" = "397.3.5.1"; "dvt_mobiledevice_version" = "1757.0.0.101.1"; "launchSession_schemeCommand" = Run; "launchSession_state" = 1; "launchSession_targetArch" = arm64; "operation_duration_ms" = 12228; "operation_errorCode" = "-402653081"; "operation_errorDomain" = "com.apple.dt.MobileDeviceErrorDomain"; "operation_errorWorker" = IDEInstalliPhoneLauncher; "operation_name" = IDEiPhoneRunOperationWorkerGroup; "param_debugger_attachToExtensions" = 0; "param_debugger_attachToXPC" = 1; "param_debugger_type" = 5; "param_destination_isProxy" = 0; "param_destination_platform" = "com.apple.platform.iphoneos"; "param_diag_MainThreadChecker_stopOnIssue" = 0; "param_diag_MallocStackLogging_enableDuringAttach" = 0; "param_diag_MallocStackLogging_enableForXPC" = 1; "param_diag_allowLocationSimulation" = 1; "param_diag_checker_tpc_enable" = 1; "param_diag_gpu_frameCapture_enable" = 0; "param_diag_gpu_shaderValidation_enable" = 0; "param_diag_gpu_validation_enable" = 0; "param_diag_memoryGraphOnResourceException" = 0; "param_diag_queueDebugging_enable" = 1; "param_diag_runtimeProfile_generate" = 0; "param_diag_sanitizer_asan_enable" = 0; "param_diag_sanitizer_tsan_enable" = 0; "param_diag_sanitizer_tsan_stopOnIssue" = 0; "param_diag_sanitizer_ubsan_stopOnIssue" = 0; "param_diag_showNonLocalizedStrings" = 0; "param_diag_viewDebugging_enabled" = 1; "param_diag_viewDebugging_insertDylibOnLaunch" = 1; "param_install_style" = 0; "param_launcher_UID" = 2; "param_launcher_allowDeviceSensorReplayData" = 0; "param_launcher_kind" = 0; "param_launcher_style" = 0; "param_launcher_substyle" = 0; "param_runnable_appExtensionHostRunMode" = 0; "param_runnable_productType" = "com.apple.product-type.application"; "param_structuredConsoleMode" = 1; "param_testing_launchedForTesting" = 0; "param_testing_suppressSimulatorApp" = 0; "param_testing_usingCLI" = 0; "sdk_canonicalName" = "iphoneos17.5"; "sdk_osVersion" = "17.5"; "sdk_variant" = iphoneos; } -- 系统信息 macOS版本 14.5 (Build 23F79) Xcode 15.4 (22622) (Build 15F31d) 时间戳: 2024-09-09T10:36:56+09:00
解决方案
1. 配置主应用的“仅在安装时复制”选项
“仅在安装时复制”对应Xcode Build Setting中的ONLY_INSTALL_ON_ACTIVE_DEVICE,可以通过Tuist在主应用Target的settings字段中配置:
let mainAppTarget = Target.target( name: "MYAPP", destinations: .iOS, product: .app, bundleId: "你的主应用Bundle ID", deploymentTargets: .iOS("14.0"), infoPlist: .file(path: .relativeToRoot("Targets/MainApp/Supporting Files/Info.plist")), sources: ["Targets/MainApp/Sources/**"], resources: ["Targets/MainApp/Resources/**"], entitlements: .file(path: .relativeToRoot("Targets/MainApp/Supporting Files/MainApp.entitlements")), // 添加以下配置开启“仅在安装时复制” settings: .settings( base: [ "ONLY_INSTALL_ON_ACTIVE_DEVICE": true ] ), dependencies: [ // 你的其他依赖 ] )
2. 修复扩展的xcframework嵌入配置
你的错误代码0xE8000067通常和框架未正确嵌入有关,需要为扩展中的xcframework依赖添加embed: .yes配置,确保Tuist自动处理嵌入和签名:
修改ext-notiservice的依赖配置
dependencies: [ .dependency( .xcframework(path: .relativeToRoot("Targets/\(name)/frameworks/BrazeNotificationService.xcframework")), embed: .yes ), ]
修改ext-noticontent的依赖配置
dependencies: [ .dependency( .xcframework(path: .relativeToRoot("Targets/\(name)/frameworks/BrazePushStory.xcframework")), embed: .yes ) ]
3. 验证与生效
- 运行
tuist generate重新生成项目 - 检查主应用Target的Build Settings,确认
ONLY_INSTALL_ON_ACTIVE_DEVICE已设为YES - 检查扩展Target的
Frameworks, Libraries, and Embedded Content,确认xcframework的Embed状态为“Embed & Sign” - 重新编译安装应用即可解决问题
内容的提问来源于stack exchange,提问作者NakCheon Owen Jung
相关产品推荐
相关产品推荐

