问题描述
在创建Apple Watch扩展后,Xcode预览显示报错。

Xcode提示如下报错:
/Users/fangjunyu/Library/Developer/Xcode/DerivedData/piglet-ctfeczjsbemrfhhjuuixdytgqbjg/SourcePackages/checkouts/lottie-ios/Sources/Private/CoreAnimation/Animations/CAAnimation+TimingConfiguration.swift:4:8 No such module 'QuartzCore'
/Users/fangjunyu/Library/Developer/Xcode/DerivedData/piglet-ctfeczjsbemrfhhjuuixdytgqbjg/SourcePackages/checkouts/lottie-ios/Sources/Private/CoreAnimation/Animations/CAAnimation+TimingConfiguration.swift:4:8 QuartzCore is not available when building for watchOS Simulator. Consider using `#if canImport(QuartzCore)` to conditionally import this framework.
/Users/fangjunyu/Library/Developer/Xcode/DerivedData/piglet-ctfeczjsbemrfhhjuuixdytgqbjg/Build/Intermediates.noindex/Previews/watchsimulator/piglet/Intermediates.noindex/Lottie.build/Debug-watchsimulator/Lottie.build/Objects-normal/arm64/Lottie.swiftdoc /Users/fangjunyu/Library/Developer/Xcode/DerivedData/piglet-ctfeczjsbemrfhhjuuixdytgqbjg/Build/Intermediates.noindex/Previews/watchsimulator/piglet/Intermediates.noindex/Lottie.build/Debug-watchsimulator/Lottie.build/Objects-normal/arm64/Lottie.swiftdoc: No such file or directory
/Users/fangjunyu/Library/Developer/Xcode/DerivedData/piglet-ctfeczjsbemrfhhjuuixdytgqbjg/Build/Intermediates.noindex/Previews/watchsimulator/piglet/Intermediates.noindex/Lottie.build/Debug-watchsimulator/Lottie.build/Objects-normal/arm64/Lottie.swiftdoc /Users/fangjunyu/Library/Developer/Xcode/DerivedData/piglet-ctfeczjsbemrfhhjuuixdytgqbjg/Build/Intermediates.noindex/Previews/watchsimulator/piglet/Intermediates.noindex/Lottie.build/Debug-watchsimulator/Lottie.build/Objects-normal/arm64/Lottie.swiftdoc: No such file or directory
/Users/fangjunyu/Library/Developer/Xcode/DerivedData/piglet-ctfeczjsbemrfhhjuuixdytgqbjg/Build/Intermediates.noindex/Previews/watchsimulator/piglet/Intermediates.noindex/Lottie.build/Debug-watchsimulator/Lottie.build/Objects-normal/arm64/Lottie.swiftmodule /Users/fangjunyu/Library/Developer/Xcode/DerivedData/piglet-ctfeczjsbemrfhhjuuixdytgqbjg/Build/Intermediates.noindex/Previews/watchsimulator/piglet/Intermediates.noindex/Lottie.build/Debug-watchsimulator/Lottie.build/Objects-normal/arm64/Lottie.swiftmodule: No such file or directory
/Users/fangjunyu/Library/Developer/Xcode/DerivedData/piglet-ctfeczjsbemrfhhjuuixdytgqbjg/Build/Intermediates.noindex/Previews/watchsimulator/piglet/Intermediates.noindex/Lottie.build/Debug-watchsimulator/Lottie.build/Objects-normal/arm64/Lottie.swiftsourceinfo /Users/fangjunyu/Library/Developer/Xcode/DerivedData/piglet-ctfeczjsbemrfhhjuuixdytgqbjg/Build/Intermediates.noindex/Previews/watchsimulator/piglet/Intermediates.noindex/Lottie.build/Debug-watchsimulator/Lottie.build/Objects-normal/arm64/Lottie.swiftsourceinfo: No such file or directory
说明在编译过程中,Xcode 无法找到 QuartzCore 模块。QuartzCore 是 iOS 和 WatchOS 中的一个系统框架,通常用于处理动画和图形等操作。由于 Lottie(用于处理动画)库中引用了 QuartzCore,所以它在编译时无法找到该模块,导致错误。
点击Xcode报错内容,跳转到Lottie文件中。

Xcode报错提示:
No such module 'QuartzCore'
QuartzCore is not available when building for watchOS Simulator. Consider using `#if canImport(QuartzCore)` to conditionally import this framework.
解决方案
通过一系列查找,查找的的解决方案为,在WatchOS环境中,通过条件导入避免引入不兼容的框架:
#if canImport(QuartzCore)
import QuartzCore
#endif
实际的操作流程为,在Xcode项目中找到引入的Lottie包的路径,例如:
/Users/fangjunyu/Library/Developer/Xcode/DerivedData/piglet-ctfeczjsbemrfhhjuuixdytgqbjg/SourcePackages/checkouts/lottie-ios/
可以将该路径下的全部Swift文件使用条件导入,例如:
// Created by Cal Stephens on 12/13/21.
// Copyright © 2021 Airbnb Inc. All rights reserved.
#if canImport(QuartzCore)
import QuartzCore
... // 全部文件内容
#endif
使用条件导入包裹整个Swift代码。
因为我处理的Lottie包中的Swift代码比较多,还因为Xcode报错文件列表不全,用了将近一个半小时的时间,把报错Lottie中的全部Swift文件添加条件导入,最终Xcode不再报错。
如果是同类问题,可以查看我创建的lottie-ios分支,在4.5.1版本基础之上解决了WatchOS报错的问题。

总结
这一问题的原因,在于WatchOS环境不兼容QuartzCore框架导致的一系列报错。
通过条件导入可以避免在WatchOS中使用Lottie文件。还有其他的解决方案,例如寻找其他的Lottie包:
1、dotlottie-ios:https://github.com/lottiefiles/dotlottie-ios
2、lottie-web:https://github.com/airbnb/lottie-web
但因为修改Lottie包可能还需要修改动画的配置参数,因此没有选择其他的Lottie包来解决这一问题。
或者通过命令批量修改Swift文件,让Swift文件内容全部使用条件导入,到因为我在测试的过程中没能实现用命令设置条件导入,因此这边没有进一步阐述。
相关文章
1、Xcode Export Localizations for an iOS app using Swift Package Manager packages fails: No such module UIKit:https://developer.apple.com/forums/thread/725395
2、Package Manager Platform Deployment Settings:https://github.com/swiftlang/swift-evolution/blob/main/proposals/0236-package-manager-platform-deployment-settings.md#future-directions