I've used INIntent
object since Siri shortcut is added. For that I made an intent definition and it generated a INIntent
object automatically.
@available(iOS 12.0, watchOS 5.0, *)
@objc(SpotConditionIntent)
public class SpotConditionIntent: INIntent {
@NSManaged public var spotId: String?
@NSManaged public var spotName: String?
}
To customize the Siri shortcut voice record screen, I added a convenience initializer. It was basically to add suggestedInvocationPhrase
and the top icon image.
@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)
}
}
}
Today, I tried to convert the entire project to Swift 5 and there was no issue on building. (There was no actual change in the code.) However it crashes on runtime with very weird message.
Thread 1: Fatal error: could not detangle key path type from
XXXX9SpotConditionIntentCXD
and it pointed the setImage(inImage, forParameterNamed: \.spotName)
.
I just found that the setImage(,forParameterNamed)
doesn't exist in the documentation.
https://developer.apple.com/documentation/sirikit/inintent
Seems like I need to use func keyImage() -> INImage?
which is added in iOS 12.
But I have no idea why it works in Swift 4.X and can't find any documentation for the deprecation. Anyone knows about this issue?
As far as I checked...
The two methods are available in Objective-C.
And the generated interface for these methods shown as...
// 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?
The docs or code suggestion of Xcode will not show you these, but you can use them in Swift 5 code:
intent.__setImage(image, forParameterNamed: "spotName")
Though, using underscore-leaded methods may be taken as using private APIs when submitting your app to App Store.
This sort of things sometimes happens when Apple is swiftifying some methods and not completed yet.
As for now, what you can do are...
Send a bug report to Apple, immediately
Write an Objective-C wrapper for these methods and import it into Swift
or