LoginSignup
2
2

More than 5 years have passed since last update.

Swift.Any as? CFType

Last updated at Posted at 2016-12-15

Objective-C の API を Swift から使うとき、次のようにオプション項目を Dictionary 型で指定することがよくある。

open class AVPlayerItemVideoOutput : AVPlayerItemOutput {

    public init(pixelBufferAttributes: [String : Any]? = nil)

}

普通に Swift 側から API に値を投げる分には何も問題ないのだけど、自分で Any から CoreFoundation 由来の型にキャストする場合にちょっと手間取った。具体的には、↑ の API に渡される [String : Any]AnyCFAllocator として取り出したい。

普通に as? でキャストすればいいのでは?

Screen Shot 2016-12-15 at 17.22.51.jpg

🤔
これならわかる:

Screen Shot 2016-12-15 at 19.03.40.jpg

同じ CoreFoundation 由来の型でも CFStringCFNumber は Swift の StringInt などに as で安全にキャストできるので、特に困ることはない。

let value: Any? = "🤔"

guard let string = value as? String else { return }

let cfString = string as CFString

ただ CFAllocator などは対応する Swift や Objective-C の型がないので、何かしら別の手段で型をきちんと確認してから as! でキャストすることになる。

CFGetTypeID(_:) で型をチェックする

というわけで:

let value: Any? = attributes[kCVPixelBufferMemoryAllocatorKey as String]

let allocator: CFAllocator?

if CFGetTypeID(value as CFTypeRef!) == CFAllocatorGetTypeID() {
    allocator = (value as! CFAllocator)
} else {
    allocator = nil
}

これで Any から CFAllocator にキャストすることができた。 CFGetTypeID(_:) へは Swift の型を投げ入れても例外で止まるようなことはないので、型の一致判定に使う分には問題無さそう。

参考

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2