The following code is almost exact replica from Apple Documentation and compiles without errors:
guard let firstItem = (rawItems! as? Array<Dictionary<String, Any>>)?.first else {
throw AnError()
}
let identityRef = firstItem[kSecImportItemIdentity as String]
as! SecIdentity? // !!!
guard let identity = identityRef else {
throw AnError()
}
The line marked with !!! contains forced downcast, while replacing as! with as quite obviously results in a compilation error 'Any?' is not convertible to 'SecIdentity?'... Indeed SecIdentity is a class while Any may not even be a class.
What I really cannot explain is the following. If I try to make the code safer, by using this
guard let idenity = firstItem[kSecImportItemIdentity as String] as? SecIdentity
else {
throw AnError()
}
or this
guard let idenityRef = firstItem[kSecImportItemIdentity as String] as? SecIdentity?
else {
throw AnError()
}
I get a compilation error: Conditional downcast to CoreFoundation type 'SecIdentity' will always succeed
SecIdentityis “an abstract Core Foundation-type object representing an identity, ” and the type of Core Foundation types can be checked withCFGetTypeID(). So you can check the type ID first. If it matches the type ID of anSecIdentitythen the forced cast is safe:See also the bug report SR-7015 The CoreFoundation conditional downcast diagnostic is not as helpful as it should be: