Thinking and Feeling of the Third Reading of Kingfisher Network Picture Cache Library

Next we will do hard disk caching, multiple picture loading, and multi-threaded processing of multiple picture caching.This section tries to get all this done as far as possible, because it's the idea of sdwebimage, or rather the Kingfisher library by name, which doesn't have much to do with it.So finish your thoughts as soon as possible and read Kingfisher on the basis of your familiarity

Requirement Start:

Now I want to store it on the hard disk. If it's the first time, then default is to store it on the hard disk. Otherwise, you can set an incoming parameter that tells you whether to store it on the hard disk or not. If it's in Objective-c, we'll write two methods

One: - (void)storeImage:(UIImage *)image forKey:(NSString *)key.

One: - (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk.In the first method, the second method is called by default and YES is passed.: [self storeImage:image for Key:key toDisk:YES];

Swift doesn't have to be that troublesome

Declare the optional parameters directly:

  //Singleton
    static let shared = ImageCache()
    //Store pictures
    func storeImage(url:URL,image:UIImage?,toDisk:Bool?=nil) -> Void {
        let urlStr = "\(url)"
        memoryDic?.setValue(image, forKey:urlStr)
        if toDisk ?? false {
            //Store in Hard Disk
            print("Storage Hard Disk")
        }
    }
//.Here?=nil, the parameter can be selected to pass in, the call can:
//            ImageCache.shared.storeImage(url: url, image: self.image!)
            ImageCache.shared.storeImage(url: url, image: self.image!, toDisk: true)

Both can be used directly without error.A function does that without having to write as many parameters as OC.There may be some problems with this writing, but use it slowly to understand. Next, let's look at Swift's native sandbox storage operation syntax

Try changing square brackets to point grammar first:

//Cache class-------
//Don't write here: Inherit class, what will it inherit by default?Object?
class ImageCache {
    //Declarations and Initializations
    var memoryDic:NSMutableDictionary? = [:]
    //Singleton
    static let shared = ImageCache()
    //Store pictures
    func storeImage(url:URL,image:UIImage?,toDisk:Bool?=nil) -> Void {
        let urlStr = "\(url)"
        memoryDic?.setValue(image, forKey:urlStr)
        if toDisk ?? false {
            //Store in Hard Disk
            print("Storage Hard Disk")
            //Create a storage folder first, then this creation code writes to the class when it is initialized. Note the slash when the path is written
            let myDirectory:String = NSHomeDirectory() + "/Documents/ImageCache/"
            let fileManager = FileManager.default
            //withIntermediateDirectories is ture indicating that any folder that does not exist in the middle of the path will be created
            try! fileManager.createDirectory(atPath: myDirectory,                                     withIntermediateDirectories: true, attributes: nil)
            //Here the path is also handled, file name do md5 to prevent duplication, there is a slight problem with md5 path writing, it is time to refer to Kingfisher's algorithm, but the md5 algorithm is OK, but I do not know the appropriate md5 using url string.
            let md5FileNamePath = myDirectory + urlStr.md5()
            fileManager.createFile(atPath: md5FileNamePath, contents: UIImageJPEGRepresentation(image!, 1.0), attributes: nil)
            
        }
    }
    //Take pictures
    func imageForKey(url:URL,formDisk:Bool?=nil) ->UIImage? {
        let urlStr = "\(url)"
        //If there is a direct display in memory
        if memoryDic?.allValues.count != 0 && memoryDic?.allValues.count != nil {
            let image:UIImage = memoryDic!.object(forKey: urlStr) as! UIImage
            return image
        }
        //If you don't find it on your hard drive anymore
//        image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfFile:[self cachePathForKey:key]]];
        let myDirectory:String = NSHomeDirectory() + "/Documents/ImageCache/"
        let md5FileNamePath = myDirectory + urlStr.md5()
        let img = UIImage.init(contentsOfFile: md5FileNamePath)
        if (img != nil) {
            return img
        }
        return nil
    }
   
 }
 //md5

 String+MD5.swift

 import Foundation
extension String {
    func md5() -> String {
        let str = self.cString(using: String.Encoding.utf8)
        let strLen = CUnsignedInt(self.lengthOfBytes(using: String.Encoding.utf8))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
        CC_MD5(str!, strLen, result)
        let hash = NSMutableString()
        for i in 0 ..< digestLen {
            hash.appendFormat("%02x", result[i])
        }
        result.deinitialize()

        return String(format: hash as String)
    }
}

#import <CommonCrypto/CommonDigest.h>

DIY_SFSCKingfisher-Bridging-Header.h

import Foundation
import UIKit
/// typealias is used to redefine the name of an existing type.
typealias ImageView = UIImageView
extension ImageView {
    func sfsc_setImage(url:URL?) -> Void {
        //--------- This part of the code, every need for network pictures will be used, so extract it---------
        /* guard let Syntax: The guard let must have a value after it is judged. If no value is returned directly in the {} of the guard let.
          If you need to guard multiple values, separate them directly from commas.
         
         */
        guard let url = url else {
            return
        }
        //Code execution to this url must have value!!
        if (ImageCache.shared.imageForKey(url: url) != nil) {
            //If you get a value from the memory cache, it will be displayed directly and returned directly without loading
            self.image = ImageCache.shared.imageForKey(url: url)
            return
        }
        
        //Convert to data type
        let data : NSData! = NSData(contentsOf: url)
        //Judging that the data is not empty, this is because swift is strict on types and crashes if it is not empty
        if data != nil {
            //Assignment Picture
            self.image = UIImage.init(data: data as Data, scale: 1)
//            ImageCache.shared.storeImage(url: url, image: self.image!)
            ImageCache.shared.storeImage(url: url, image: self.image!, toDisk: true)
        }else{
            // Otherwise assign a default picture
            self.image = UIImage.init(named: "005")
        }
    }
}


 

Tags: Swift encoding network

Posted on Thu, 07 Nov 2019 09:01:40 -0500 by mxicoders