Closed ilendemli closed 1 year ago
This looks like a bug in Xcode 14.3, considering this works correctly in Xcode 14.2.
For now if you need to use the Xcode 14.3 beta i'd suggest using lottie-ios instead of lottie-spm. I'll file a feedback with Apple to let them know about this regression.
Filed as FB11994464
what about Xcode 14.3 beta 2?
@SajjadKharrazi still fails to compile
Still fail with Xcode 14.3 beta 3.
I'll grant that it's not super intuitive, but when you see an error like
Failed to build module 'Lottie'; this SDK is not supported by the compiler (the SDK is built with 'Apple Swift version 5.5.2 (swiftlang-1300.0.47.5 clang-1300.0.29.30)', while this compiler is 'Apple Swift version 5.8 (swiftlang-5.8.0.117.11 clang-1403.0.22.8.60)'). Please select a toolchain which matches the SDK
It indicates that there's something wrong with the textual interface of the module. There should be other errors earlier in the build log that indicate the underlying problems. I reproduced this and all of the errors are duplicates of this:
/Users/allan/Library/Developer/Xcode/DerivedData/lottie-spm-main-blvyxsipwvcwbufoycfdhvhokztd/Build/Products/Debug/Lottie.framework/Modules/Lottie.swiftmodule/arm64-apple-macos.swiftinterface:260:17: 'MainActor' is only available in macOS 10.15 or newer
It looks like Lottie is missing @availability
annotations for its APIs that are annotated @MainActor
. Note that this will only reproduce when the client of Lottie has a deployment target that is lower than the lowest deployment target supported by Swift concurrency.
@tshortli, any clue why this is a problem in Xcode 14.3 but not a problem in Xcode 14.2? We're use the same Lottie.xcframework
in both cases (which was built by Xcode 13.2.1, so it can support consumers using Xcode 13.2 / Swift 5.5). Does this imply that Xcode 14.3 no longer supports .xframework
s built by Xcode 13.2.1, or is there a configuration change we'd need to make on our end?
No, it doesn't imply a general incompatibility. There's just a straightforward availability typechecking error in the interface of the framework. It's possible that this availability error was undiagnosed by previous compilers, but I don't think that would be the case. Regardless of the exact reason this has only been noticed now, it should be safe to just add the appropriate @available
annotations; they are needed to satisfy the type checker and to ensure that clients of Lottie don't try to use those declarations when back deploying to OSes that don't support concurrency.
It's possible that this availability error was undiagnosed by previous compilers
Ah ok, this makes sense to me. I understand how this could be an issue on our end that happened to not be diagnosed as an error in previous versions. Thanks for the info, I'll look in to fixing this!
This is in the known issues:
The Xcode “Strict Concurrency Checking” setting is not correctly passed to the compiler. If you set it to “Minimal” (the default), the compiler will still perform “Targeted” checks. (105637789)
Workaround: Add -Xfrontend -strict-concurrency=minimal to OTHER_SWIFT_FLAGS under your project’s Build Settings, or add -Xswiftc -strict-concurrency=minimal when running swift build.
Sorry, @tshortli, I took a look at this and don't really understand how we would work around this issue.
For example, our .swiftinterface
contains:
@objc @_inheritsConvenienceInitializers @IBDesignable @_Concurrency.MainActor(unsafe) open class LottieAnimationView : Lottie.LottieAnimationViewBase {
@_Concurrency.MainActor(unsafe) public init(animation: Lottie.LottieAnimation?, imageProvider: Lottie.AnimationImageProvider? = nil, textProvider: Lottie.AnimationTextProvider = DefaultTextProvider(), fontProvider: Lottie.AnimationFontProvider = DefaultFontProvider(), configuration: Lottie.LottieConfiguration = .shared, logger: Lottie.LottieLogger = .shared)
This @_Concurrency.MainActor(unsafe)
annotation seems to be the one causing a 'MainActor' is only available in iOS 13.0 or newer
error.
In the Lottie library itself, this initializer does not use any concurrency features. It's defined like this:
public init(
animation: LottieAnimation?,
imageProvider: AnimationImageProvider? = nil,
textProvider: AnimationTextProvider = DefaultTextProvider(),
fontProvider: AnimationFontProvider = DefaultFontProvider(),
configuration: LottieConfiguration = .shared,
logger: LottieLogger = .shared)
{ ... }
The declaration doesn't have any @available
annotations, because it doesn't need any. So it seems incorrect for Xcode to emit an error here. Is there something else I'm missing?
I assume you got here via the feedback I filed. I'm happy to create a standalone repro project if that would be helpful.
I see. Then I guess what's changed is that some part of the compiler is inferring those @MainActor
attributes based off of something about those declarations and then they are getting printed that way in the .swiftinterface
. I still think you ought to be able work around the error by adding explicit availability even though the compiler doesn't think you need it when building the framework from source, but now that I understand the issue better I agree there's some behavior of the compiler that does need to change. If you're able to put together a reproducer project that produces an .xcframework
with similar characteristics that would be helpful.
I believe the issue is caused by the fix in https://github.com/apple/swift/pull/60672.
In short, the compiler wasn't previously requiring APIs using @MainActor
to also have proper availability markup (e.g. @available(iOS 13, *)
) which is now being checked in 5.8. I don't know what would happen at runtime when calling such an API from an older OS but probably nothing good. The solution is to rebuild Lottie with the new compiler, as the current version is invalid (and likely unsafe). This can be done by either setting the deployment target to the right levels, or marking up all API using @MainActor
with the proper availability.
Hm, we are intentionally building Lottie's distributed xcframework
with Xcode 13.2.1 so it can be used by consumers still running Swift 5.5 / Swift 5.6 (which doesn't work if we build the xcframework
with Xcode 14.2). Is there another way to do this? BUILD_LIBRARY_FOR_DISTRIBUTION=YES
doesn't help with that specific problem.
For reference, here's a really simple sample project that demonstrates the issue:
I created a trivial library that includes a public UIView
subclass:
import UIKit
public class FB11994464_Library: UIView {
public init() {
super.init(frame: .zero)
}
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
I built an XCFramework for the library (using a shell script in the zip archive) and then used that .xcframework
in a trivial app target that consumes the UIView subclass:
import UIKit
import FB11994464_Library
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let subview: UIView = FB11994464_Library()
view.addSubview(subview)
}
}
In Xcode 14.2, the app target builds as expected. In Xcode 14.3 beta, the app target fails to build and emits this 'MainActor' is only available in iOS 13.0 or newer
error.
I would suppose the new compiler isn't a requirement there, you just need to rebuild in a way that adds the availability to generated interface. Marking up these APIs with availability may do what you want.
Beyond the issue I posted I don't know much more. I narrowly avoided this issue with an SDK I built where I was using @MainActor
with a deployment target of iOS 12 and wondering why the compiler wasn't complaining. I got pointed to the issue I posted and manually worked around the issue by bifurcating the entry point so that newer OSes trampoline through Task
to get the @MainActor
for later calls. It seems that, in fixing that issue, the compiler now requires all global actors to be availability checked, even auto imported ones from Apple's frameworks.
I don't think this is related to using concurrency features in my library's source code -- the sample code I shared above has this same issue when built as an XCFramework but doesn't use any concurrency features.
I believe the issue is caused by the fix in apple/swift#60672.
Yup, Jon is right. It's been long enough that I had forgotten that global actor typechecking was missing some key checks prior to Swift 5.8. I need to confirm, but I think the fix will be to relax availability checking for MainActor(unsafe)
because it has no ABI effect and therefore shouldn't be constraining availability.
Fixing with https://github.com/apple/swift/pull/64412.
Thank you @tshortli!
Thanks for fixing this @tshortli. Is the fix going to be included in Xcode 14.3 final release?
Not fixed with Xcode 14.3 RC1.
Not fixed with Xcode 14.3 RC1.
Yeah, I was going to comment the same thing. We saw last night on Xcode Cloud how our builds started to fail due to this:
Failed to build module 'Lottie'; this SDK is not supported by the compiler (the SDK is built with 'Apple Swift version 5.5.2 (swiftlang-1300.0.47.5 clang-1300.0.29.30)', while this compiler is 'Apple Swift version 5.8 (swiftlang-5.8.0.124.1 clang-1403.0.22.11.100)'). Please select a toolchain which matches the SDK.
Are we all assuming that the final 14.3 will have this issue solved? We also faced the same issue with Giphy and they have a branch with a fix just for this, just sharing in case that it helps! https://github.com/Giphy/giphy-ios-sdk/issues/221
The best workaround for now is still to use lottie-ios
rather than lottie-spm
. I'd prefer not to have to drop support for iOS 11 / 12, but will consider that sort of workaround if this bug isn't fixed by the time Xcode 14.3 is released.
The best workaround for now is still to use
lottie-ios
rather thanlottie-spm
. I'd prefer not to have to drop support for iOS 11 / 12, but will consider that sort of workaround if this bug isn't fixed by the time Xcode 14.3 is released.
For now we'll keep using Xcode 14.2 since there's no rush to upgrade (and keep using lottie-spm
). But yeah, if we have to end up upgrading to 14.3 and the issue is still there, we'll revert to using lottie-ios
👍🏼
The Swift 5.8 version of the fix PR just went up: https://github.com/apple/swift/pull/64538. Unfortunately Apple's Xcode release process takes long enough it seems unlikely we'll see this in Xcode 14.3 even if they accept the PR today. Perhaps 14.3.1?
Reverting to lottie-ios
has unblocked us for now so I'll continue using that until the fix makes it into Xcode or some other change is made to this repo
This issue is resolved in Xcode 14.3 RC 2: https://github.com/apple/swift/pull/64412#issuecomment-1485621729
@calda Just a heads up, Apple is currently rejecting builds from Xcode 14.3 RC2 as "beta" if you try and ship to the store using it. I have a build on the store from RC1 so being "RC" isn't the issue.
I've already contacted developer support.
Which Version of Lottie are you using?
Lottie 4.1.3
Expected Behavior
Project to compile without errors
Actual Behavior
Project does not compile because of unsupported SDK by the compiler
Xcode 14.3 beta has been released and Lottie fails to compile with the following error:
Failed to build module 'Lottie'; this SDK is not supported by the compiler (the SDK is built with 'Apple Swift version 5.5.2 (swiftlang-1300.0.47.5 clang-1300.0.29.30)', while this compiler is 'Apple Swift version 5.8 (swiftlang-5.8.0.117.11 clang-1403.0.22.8.60)'). Please select a toolchain which matches the SDK.
Might be a solution for future releases: https://stackoverflow.com/a/70562356/3928565
PS: I am using the lottie-spm integration in my project