Reputation: 22487
I am having difficulty figuring out how to get an NSData
representation of an image from a CGImageRef
. All of the answers I've found make use of UIImage
or NSImage
, but my application is cross-platform, so I want to use only Core Graphics. Objective-C answers state simply that CFData
is toll-free bridged to NSData
and simply cast it, but Swift will not allow this. The closest I've got is:
var image: CGImageRef? = nil
//...
if let dataProvider: CGDataProviderRef = CGDataProviderCreateWithURL(url) {
image = CGImageCreateWithPNGDataProvider(dataProvider, nil, false, CGColorRenderingIntent.RenderingIntentDefault)
// works fine
//...
if let data = CGDataProviderCopyData(CGImageGetDataProvider(image)) as? NSData {
// Do something with data, if only it ever got here!
}
}
but the cast doesn't ever succeed...
Upvotes: 2
Views: 1350
Reputation: 539745
CGDataProviderCopyData()
returns the optional CFData?
, and that cannot be cast to the non-optional NSData
. But you can convert/bridge
it to NSData?
and use that in the optional binding:
if let data = CGDataProviderCopyData(CGImageGetDataProvider(image)) as NSData? {
// Do something with data ...
}
Here is a simpler example demonstrating the same issue with
CFString
and NSString
:
let cfstr : CFString? = "Hello world"
if let nsstr = cfstr as? NSString {
print("foo") // not printed
}
if let nsstr = cfstr as NSString? {
print("bar") // printed
}
But I admit that my explanation is not fully satisfying, because a similar optional cast works in other cases:
class MyClass { }
class MySubclass : MyClass { }
let mc : MyClass? = MySubclass()
if let msc = mc as? MySubclass {
print("yes") // printed
}
So this must be related to the toll-free bridging between CoreFoundation and Foundation types.
Upvotes: 4