'Unmanaged' is not convertible to 'SKIndex'; did you mean to use 'as!' to force downcast?
In this function below, doc is an Unmanaged<SKDocument> and the compiler is fine with the as. But it doesn't like a similar construction with skIndex: Unmanaged<SKIndex>. I tried changing as to as! but it crashes at runtime.
How do I pass the SKIndex to that function? (It's from Search Kit.)
func addCardToIndex(card: Card) {
guard let skIndex = self.skIndex else { fatalError() }
let doc = SKDocumentCreate("card" as CFString, nil, card.id.description as CFString)!
let contents = "foo bar baz"
let replace = true
SKIndexAddDocumentWithText(
skIndex as SKIndex /* error */,
doc as SKDocument, contents as CFString, replace)
}
The as compiled with SKDocument, but causes a failure at runtime. I needed to replace that with doc.takeUnretainedValue() as well, to get the function call to succeed.
Ideally, you should have already called takeRetainedValue() whenever
you've got that Unmanaged<SKIndex> passed to you by one of the SKIndexCreate* functions.
That’s exactly right. Your goal here should be to minimise the amount of unmanaged stuff that you do. In this case that means converting from an unmanaged reference to a managed reference as soon as possible. I often do that by writing a small wrapper, for example:
func SKDocumentCreateQ(_ scheme: String, parent: SKDocument?, name: String) -> SKDocument? {
guard let doc = SKDocumentCreate(scheme as NSString, parent, name as NSString) else {
// This returns `nil` on error but it might make more sense to throw.
return nil
}
return doc.takeRetainedValue()
}