SwiftNSCacheシングルトン

Aug 31 2020

コードで依存性注入を使用するために、NSCacheをシングルトンでラップしたいと思います。これにより、残念ながら、型を関数パラメーターに渡すことになりました。シングルトンインスタンスであるため、成功と失敗のために2つのモックが必要です。

もっと良い方法があるかもしれないと思いますが、コメントはありがたいです!

ImageCacheとプロトコル

protocol ImageCacheProtocol {
    static var shared: Self { get }
    func getCache() -> NSCache<AnyObject, UIImage>
}

final class ImageCache: ImageCacheProtocol {
    var cache: NSCache<AnyObject, UIImage> = NSCache<AnyObject, UIImage>()

    public static let shared = ImageCache()
    private init() {}
    
    func getCache() -> NSCache<AnyObject, UIImage> {
        return cache
    }
}

MockImageCache&MockImageCacheFailure

final class MockImageCache: ImageCacheProtocol {
    var cache: NSCache<AnyObject, UIImage> = MockNSCache(shouldReturnImage: true)

    public static let shared = MockImageCache()
    private init() {}

    func getCache() -> NSCache<AnyObject, UIImage> {
        return cache
    }
}


final class MockImageCacheFailure: ImageCacheProtocol {
    var cache: NSCache<AnyObject, UIImage> = MockNSCache(shouldReturnImage: false)

    public static let shared = MockImageCacheFailure()
    private init() {}

    func getCache() -> NSCache<AnyObject, UIImage> {
        return cache
    }
}

ビューモデルのインスタンス化(スニペット)

class ViewModel<U: ImageCacheProtocol> {

    private var cache: U.Type
    init<T: NetworkManagerProtocol>(networkManager: T, data: DisplayContent, imageCache: U.Type) {
        self.networkManager = AnyNetworkManager(manager: networkManager)
        
        cache = imageCache

回答

WishIHadThreeGuns Sep 02 2020 at 14:29

はい、これは標準的な方法ではありません。私の解決策は、使用せずSelf、代わりに共有に集中することです。

あれは:

protocol ImageCacheProtocol {
    func getCache() -> NSCache<AnyObject, UIImage>
}

final class ImageCache: ImageCacheProtocol {
    var cache: NSCache<AnyObject, UIImage> = NSCache<AnyObject, UIImage>()
    static var shared = ImageCache()
    
    private init() {}
    
    func getCache() -> NSCache<AnyObject, UIImage> {
        return cache
    }
}

次に、モックを変更できます。

final class MockImageCache: ImageCacheProtocol {
    var cache: NSCache<AnyObject, UIImage> = MockNSCache(shouldReturnImage: true)
    public static var shared: ImageCacheProtocol! = MockImageCache()
    func getCache() -> NSCache<AnyObject, UIImage> {
        return cache
    }
}