A solution: roll your own wrapper class conforming to Codable.
One solution, since extensions to UIImage
are out, is to wrap the image in a new class you own. Otherwise, your attempt is basically straight on. I saw this done beautifully in a caching framework by Hyper Interactive called, well, Cache.
Though you'll need to visit the library to drill down into the dependencies, you can get the idea from looking at their ImageWrapper
class, which is built to be used like so:
let wrapper = ImageWrapper(image: starIconImage)
try? theCache.setObject(wrapper, forKey: "star")
let iconWrapper = try? theCache.object(ofType: ImageWrapper.self, forKey: "star")
let icon = iconWrapper.image
Here is their wrapper class:
// Swift 4.0
public struct ImageWrapper: Codable {
public let image: Image
public enum CodingKeys: String, CodingKey {
case image
}
// Image is a standard UI/NSImage conditional typealias
public init(image: Image) {
self.image = image
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let data = try container.decode(Data.self, forKey: CodingKeys.image)
guard let image = Image(data: data) else {
throw StorageError.decodingFailed
}
self.image = image
}
// cache_toData() wraps UIImagePNG/JPEGRepresentation around some conditional logic with some whipped cream and sprinkles.
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
guard let data = image.cache_toData() else {
throw StorageError.encodingFailed
}
try container.encode(data, forKey: CodingKeys.image)
}
}
I'd love to hear what you end up using.
UPDATE: It turns out the OP wrote the code that I referenced (the Swift 4.0 update to Cache) to solve the problem. The code deserves to be up here, of course, but I'll also leave my words unedited for the dramatic irony of it all. :)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…