INIntent `setImage` 使运行时崩溃 Swift 5

INIntent `setImage` make runtime crash in Swift 5

我使用了 INIntent 对象,因为添加了 Siri 快捷方式。为此,我做了一个意图定义,它自动生成了一个 INIntent 对象。

@available(iOS 12.0, watchOS 5.0, *)
@objc(SpotConditionIntent)
public class SpotConditionIntent: INIntent {

    @NSManaged public var spotId: String?
    @NSManaged public var spotName: String?

}

为了自定义 Siri 快捷语音录制屏幕,我添加了一个便捷的初始化程序。基本上就是添加suggestedInvocationPhrase和顶部图标图像。

@available(iOS 12, *)
extension SpotConditionIntent {
    convenience init(spotId: String, spotName: String) {
        self.init()
        self.spotId = spotId
        self.spotName = spotName
        self.suggestedInvocationPhrase = "\(NSLocalizedString("how_are_waves_text", comment: "How are the waves at")) \(spotName)?"
        if let uiimage = UIImage(named: "check-surf-icon"), let data = uiimage.pngData() {
            let inImage = INImage(imageData: data)
            setImage(inImage, forParameterNamed: \.spotName)
        }
    }
}

今天,我尝试将整个项目转换为Swift 5,构建没有问题。 (代码中没有实际更改。)但是它在运行时崩溃并显示非常奇怪的消息。

Thread 1: Fatal error: could not detangle key path type from XXXX9SpotConditionIntentCXD

它指向 setImage(inImage, forParameterNamed: \.spotName)

我刚刚发现 setImage(,forParameterNamed) 不存在于文档中。

https://developer.apple.com/documentation/sirikit/inintent

看来我需要使用在 iOS 12.

中添加的 func keyImage() -> INImage?

但我不知道为什么它在 Swift 4.X 中有效,并且找不到任何关于弃用的文档。有人知道这个问题吗?

据我检查...

这两种方法在Objective-C中可用。

- imageForParameterNamed:

- setImage:forParameterNamed:

并且为这些方法生成的接口显示为...

// Set an image associated with a parameter on the receiver. This image will be used in display of the receiver throughout the system.
@available(iOS 12.0, *)
open func __setImage(_ image: INImage?, forParameterNamed parameterName: String)

@available(iOS 12.0, *)
open func __image(forParameterNamed parameterName: String) -> INImage?

Xcode 的文档或代码建议不会向您显示这些,但您可以在 Swift 5 代码中使用它们:

    intent.__setImage(image, forParameterNamed: "spotName")

不过,在将您的应用程序提交到 App Store 时,使用下划线引导的方法可能会被视为使用私有 API。

当 Apple swiftifying 某些方法尚未完成时,有时会发生这种情况。

至于现在,你能做的是...

  • 立即向 Apple 发送错误报告

  • 为这些方法编写一个Objective-C包装器并将其导入Swift

  • 延迟提交您的更新,直到提供修复了此问题的新 SDK (可以是几年...)