I Need to load a raw image from a resource and convert it to a UIImage
that will be stored later in an image cache.
Every image has an identifier which is used as key in the cache.
When I try to solve that problem with generics, I get this strange error when trying to return a generic object in a completion.
Errorcode: Cannot invoke value of type '(T) -> ()' with argument list '(FrontImage)'
Below is a sample code to reproduce the error.
import UIKit
protocol CacheableImage {
static func getIdentifier() -> String
}
struct Image {
var imageData: Data = Data()
}
class BaseUIImage: CacheableImage {
class func getIdentifier() -> String {
return ""
}
var image: UIImage?
required init(){}
}
class FrontImage: BaseUIImage {
override class func getIdentifier() -> String {
return "FrontImage"
}
}
class BackImage: BaseUIImage {
override class func getIdentifier() -> String {
return "BackImage"
}
}
class ImageLoader<T: BaseUIImage> {
func loadImage(forId id: UUID, completion: ((T) -> ())?) {
let type = getType(forId: id)
switch type {
case .frontImage:
let image = FileSystemResourceLoader.loadResource(forId: id)
let frontUIImage: FrontImage = ImageConverter.convertToUIImage(image: image)
completion(frontUIImage)
case .backImage:
let image = FileSystemResourceLoader.loadResource(forId: id)
let backUIImage: BackImage = ImageConverter.convertToUIImage(image: image)
completion(backUIImage)
}
}
func getType(forId id: UUID) -> ImageType {
return .frontImage // simplified return value
}
}
class ImageConverter {
static func convertToUIImage<T: BaseUIImage>(image: Image) -> T {
return T() // simplified return value
}
}
class FileSystemResourceLoader {
static func loadResource(forId id: UUID) -> Image {
return Image()
}
}
enum ImageType {
case frontImage
case backImage
}