Kingfisher使用方法

作者: 霸_霸霸 | 来源:发表于2023-03-08 17:10 被阅读0次

    1. 调用方法解析

    public func setImage(
            with resource: Resource?,
     placeholder: Placeholder? = nil
        options: KingfisherOptionsInfo? = nil,
     completionHandler: ((Result<RetrieveImageResult, KingfisherError>) -> Void)? = nil) -> DownloadTask?
    

    参数:

    • resource:目标资源;需实现Resource协议,URL继承了Resource协议,所以可以直接用URL对象
    • placeholder:站位图;需实现Placeholder协议,可自定义一个CustomView实现Placeholder协议,将这个CustomView作为站位图显示
    • options:设置图片的一些可选项的集合;
    • completionHandler:设置图片完成的回调

    使用案例:

    guard let url = URL(string: "https://pic.huitu.com/res/20221125/754309_20221125075727864209_1.jpg") else {
        return
    }
    
    let originalCache = ImageCache(name: "original_Cache")
    let targetCache = ImageCache(name: "target_Cache")
    
    let processor = RoundCornerImageProcessor(cornerRadius: 50) |> BlurImageProcessor(blurRadius: 5)
    
    let options: [KingfisherOptionsInfoItem] = [
            .transition(.flipFromBottom(0.3)),          // 从底部翻转动画
            .forceTransition,                           // 每次都要执行翻转动画
            .processor(processor),                  // 添加processor
            .onFailureImage(UIImage(named: "hot")), // 下载/找回图片失败,显示hot图片
            .targetCache(targetCache),              // 指定被处理后图片缓存
            .originalCache(originalCache),          // 指定原始图片缓存
            .cacheOriginalImage,                    // 缓存原始图片
            .waitForCache,                                                // 等待缓存结束后在执行completionBlock
            .memoryCacheExpiration(.seconds(20)),   // 设置该图片在内存缓存过期时间
            .diskCacheExpiration(.seconds(20))      // 设置该图片在磁盘缓存过期时间
    ]
    iv.kf.setImage(with: url, options: options) { result in
        switch result {
        case .success(let img):
                // ...
        case .failure(let error):
                // ...
        }
    }
    

    2. KingfisherOptionsInfoItem - 配置选项

    • targetCache(ImageCache)

      指定kingfisher使用的cache对象,会被用来找回缓存的图片和存储下载的图片。

    • originalCache(ImageCache)

      用来存储初始图片的cache对象,会被用来找回缓存的图片和存储下载的初始图片,如果没有设置originalCache(ImageCache),则会去targetCache(ImageCache)对象中查找初始图片。

      在下载和存储图片的过程中,如果设置了cacheOriginalImage这个option,就会将初始图片缓存在originalCache中;如果在targetCache对象中没有找到经过professor处理的图片,则会去originCache中查找原始图片,如果在originalCache中找到了原始图片,则会将该图片根据professor进行处理。这样能有效防止重复下载图片。

    • downloader(ImageDownloader)

      指定用来下载图片的ImageDownloader对象

    • transition(ImageTransition)

      如果该图片是需要从网络下载的,Kingfisher会根据设置的ImageTransition枚举对象来对这个图片进行动画。如果是从缓存或者磁盘中找回的,则无动画。如果想要每次都执行动画,则需要设置.forceRefresh选项,使图片永远是下载的;或者使用.forceTransition,哪怕是从缓存中获取的图片,也会执行动画。

    • downloadPriority(Float)

      设置该图片下载的优先级,值的范围是0 - 1,如果没有设置这个选项,则默认使用URLSessionTask.defaultPriority

    • forceRefresh

      忽略本地缓存,重新下载

    • fromMemoryCacheOrRefresh

      如果设置了这个选项,Kingfisher会优先从缓存中找回图片,如果在缓存中没找到,则会直接开始重新下载,不会再去磁盘中进行查找。

      当我们的图片资源发生变化,但是图片的url并没有发生变化时,可使用该选项,能有效防止多次重复下载。

    • cacheMemoryOnly

      只将图片存储在缓存中

    • waitForCache

      Kingfisher只会在缓存操作结束后再执行completion回调

    • onlyFromCache

      只会在缓存中找回图片,如果没找到,不会通过网络下载,而是直接报错:KingfisherError.cacheError(reason: .imageNotExisting(key: source.cacheKey))

    • backgroundDecode

      在使用图片前,会启用子线程对下载的图片进行解析,并且通过离屏渲染获取像素信息。这会使得展示的速度更快,但是要消耗更多的时间来做使用前的准备

    • callbackQueue(CallbackQueue)

      从缓存中找回图片后的回调,将会在该queue中进行操作,如果没有设置,则默认使用.mainCurrentOrAsync

      这个queue不会影响UI相关的扩展方法的回调所在的队列,UI类的扩展方法的回调都是在主队列中进行的。

    • scaleFactor(CGFloat)

      在将找回的data转换成图片时,使用这个关联值来设置图片的scale;比如加载2x和3x图片时,可以使用这个option来设置,如果不设置这个option,Kingfisher会按照scale为1.0去讲data转为image

    • preloadAllAnimationData

      整个的动图data是否被预加载。默认是不预加载整个的动图数据的,只是按需加载下一帧;如果设置为true,则会将整个动图的data加载并解码到内存中;

      这个option主要用于内部的向后兼容。开发时,不能直接设置这个option,而是应该选择imageView的相关类来控制data的加载。在Kingfisher中,有两个类用来展示动图,AnimatedImageViewUIImageViewAnimatedImageView不会预加载所有动图data,在加载动图的过程中,它消耗更少的内存,但会消耗更多的CPU。UIImageView会立即加载整个动图的data并解码存储到内存中,所以会消耗更多的内存,但只对所有的图片帧解码一次。

    • requestModifier(AsyncImageDownloadRequestModifier)

      可以通过关联值AsyncImageDownloadRequestModifier对象来设置request,这是最后一次修改下载图片request的机会。比如我们可以在这里为header添加auth token,url映射等。

    • redirectHandler(ImageDownloadRedirectHandler)

      关联值ImageDownloadRedirectHandler用来在重定向之前去设置request,比如:我们可以在这里为header添加auth token,url映射等。

    • processor(ImageProcessor)

      在图片下载完成后,关联值ImageProcessor会被用来将下载的data处理为image,并添加一些效果。如果下载器关联了某个cache对象(通过KingfisherManager或者UIImageView的扩展方法触发的下载都有cache对象),转换后的image也会被缓存下来。可联系上面的targetCache(ImageCache)originCache(ImageCache)两个option。

    • cacheSerializer(CacheSerializer)

      在关联值CacheSerializer会被用来将data处理为Image,以便从磁盘缓存中找回或从缓存到磁盘缓存中

    • imageModifier(ImageModifier)

      关联值ImageModifier用来在使用图片之前修改图片的。如果图片是从下载器中获取的,关联值modifier会在ImageProcessor之后被立即调用;如果是从缓存中找回的,关联值modifier将会在CacheSerializer之后被调用。

      当你需要改变图片,但是又不希望这些改变被和图片一起缓存起来,则可以通过这个option来设置,比如renderingModel(原色显示、根据tintColor显示)或者alignmentInsets(剔除装饰如阴影、徽章,圈定核心区域,自动布局也是根据核心区域去进行的)

    • keepCurrentImageWhileLoading

      在设置其它图片的过程中(如下载),保留当前图片。设置了这个属性之后,站位图会被忽略。

    • onlyLoadFirstFrame

      在加载动图时,只加载第一帧。因为加载动图时比较耗费内存的,所以可以加载第一帧作为预览图片。

      如果不是加载动图,这个option设置了也会被忽略。

    • cacheOriginalImage

      初始图片只会被缓存到磁盘存储。

      在下载时,如果设置了ImageProcessor并且该processor被使用到了,Kingfisher会缓存初始图片和经过处理的最终图片,因此,当其他processor对该图片进行处理时,就不需要从网络下载了。可以结合originalCache option来指定初始图片资源的缓存。

    • onFailureImage(KFCrossPlatformImage?)

      关联属性是个image,当下载或者从缓存中找回图片失败时,会使用这个image填充到ImageView中。

      适用于不想设置站位图,但是加载图片失败了,又想展示一个设定的图片的情况。

    • alsoPrefetchToMemory

      如果使用了ImagePrefetcher,预加载系统会主动将图片加载到内存中。预加载时如果图片已经被存放在磁盘中,从磁盘获取的图片也要缓存到内存中

    • loadDiskFileSynchronously

      同步加载磁盘图片文件。

      原本地盘加载图片在自己的异步队列中进行,但是如果imageView已经有图片了,再从磁盘读取image并设置给imageView,会导致闪烁。设置这个option,通常会让所有的加载在UI线程中进行,能防止产生闪烁,但会消耗性能。

    • diskStoreWriteOptions(Data.WritingOptions)

      在将data写入磁盘存储时,关联对象用来设置写入选项

    • memoryCacheExpiration(StorageExpiration)

      设置内存缓存的过期时间

    • memoryCacheAccessExtendingExpiration(ExpirationExtending)

      从内存读取图片时,设置延长过期时间的策略

      1. none:保持原来的过期时间

      2. `cacheTime:刷新过期时间,如原来是缓存成功3天后过期,本次访问过后,从当前时间开始,3天后过期

      3. expirationTime(_ expiration: StorageExpiration) :设置过期时间为指定的时间,如10秒后

    • diskCacheExpiration(StorageExpiration)

      设置磁盘缓存的过期时间

    • diskCacheAccessExtendingExpiration(ExpirationExtending)

      同上面的memoryCacheAccessExtendingExpiration(ExpirationExtending)

    • processingQueue(CallbackQueue)

      指定处理图片的队列。

      默认情况下,Kingfisher使用预定义的串行队列来处理图片。比如:使用.mainCurrentOrAsync来处理图片,能防止设置闪烁,但是如果处理图片耗时较长,会阻塞主线程UI。

    • progressiveJPEG(ImageProgressive)

      支持渐进式图片,关联值为针对渐进式图片的处理。

    • alternativeSources([Source])

      加载失败时,提供可替换的数据源。

      当初始请求失败,则会根据关联值[Source]开始新的加载请求。如果某一个请求成功,则不会继续请求后面的Source;如果所有的备用Source都请求失败了,则会抛出错误

    • retryStrategy(RetryStrategy)

      设置重试策略。

      当通过KingfisherManager找回图片时,如果发生了错误,会使用关联值进行重试。UIImageView和UIButton通过kf调用的的扩展方法都是通过KingfisherManager进行的,所以重试策略在这两个情况下可以生效。但是重试策略不支持ImageDownloader或者ImageCache

    • lowDataMode(Source?)

      设置低数据模式。

      当用户打开了低数据模式并且初始请求报错:NSURLErrorNetworkUnavailableReason.constrained,此时如果设置了这个option,关联值Source将会被用于进行低数据模式的请求,此外,可以让服务端提供低像素的图片来作为低数据模式获取的资源。

    3. ImageProcessor - 图片处理器

    通过processor(ImageProcessor)设置ImageProcessor会对下载的原始图片进行处理并被缓存。

    // 圆角
    // let processor = RoundCornerImageProcessor(cornerRadius: 20)
    
    // 降低采样率,会使图片变模糊
    // let processor = DownsamplingImageProcessor(size: CGSize(width: 50, height: 50))
    
    // 裁剪
    // let processor = CroppingImageProcessor(size: CGSize(width: 100, height: 100), anchor: CGPoint(x: 0.5, y: 0.5))
    
    // 毛玻璃
    // let processor = BlurImageProcessor(blurRadius: 10)
    
    // 在图片表面覆盖一层颜色
    // let processor = OverlayImageProcessor(overlay: .white, fraction: 0.7)
    
    // 用一种颜色进行着色,会覆盖原图
    // let processor = TintImageProcessor(tint: .blue)
    
     // 饱和度、对比度等调整
    // let processor = ColorControlsProcessor(brightness: 1.0, contrast: 0.7, saturation: 1.1, inputEV: 0.7)
    
    // 黑白图
    // let processor = BlackWhiteProcessor()
    
    // 混合颜色
    // let processor = BlendImageProcessor(blendMode: .colorBurn, alpha: 0.9, backgroundColor: .cyan)
    
    // 重设图片大小
    // let processor = ResizingImageProcessor(referenceSize: CGSize(width: 10, height: 10))
    

    设置方法:

    let processor = RoundCornerImageProcessor(cornerRadius: 20)
    let options = [.processor(processor)]
    iv.kf.setImage(with: url, options: options) { result in
            // ...                                             
    }
    

    多个processor结合使用

    let processor = RoundCornerImageProcessor(cornerRadius: 20) |> BlurImageProcessor(blurRadius: 10)
    let options = [.processor(processor)]
    iv.kf.setImage(with: url, options: options) { result in
            // ...                                             
    }
    

    4. Cache - 缓存

    Kingfisher使用ImageCache类来控制缓存,它采用混合缓存的模式,包含内存缓存和磁盘缓存。

    1. 指定图片的cacheKey

      let resource = ImageResource(downloadURL: url, cacheKey: "my_cache_key")
      imageView.kf.setImage(with: resource)
      
    2. 检查图片是否被缓存

      let cached = ImageCache.default.isCached(forKey: cacheKey)
      
    3. 检查图片被缓存的位置

      let cacheType = cache.imageCachedType(forKey: cacheKey)
      // .memory, .disk, .none
      
    4. 从缓存中找回图片

      cache.retrieveImage(forKey: "cacheKey") { result in
          switch result {
          case .success(let value):
              print(value.cacheType)
      
              // If the `cacheType is `.none`, `image` will be `nil`.
              print(value.image)
      
          case .failure(let error):
              print(error)
          }
      }
      
    1. 在下载或者从缓存找回图片时,使用processor对图片进行了一些处理,则经过处理的图片会被缓存下来,所以在获取该图片时,不仅需要图片的cacheKey,还需要processoridentifier,这样才能从缓存中找到经过处理的图片。

      let processor = RoundCornerImageProcessor(cornerRadius: 20)
      imageView.kf.setImage(with: url, options: [.processor(processor)])
      

      判断是否缓存了经过处理的图片

      cache.isCached(forKey: cacheKey, processorIdentifier: processor.identifier)
      

      找回经过处理的图片

      cache.retrieveImage(forKey: cacheKey, options: KingfisherParsedOptionsInfo([processor])) { result in
           switch result {
          case .success(let value):
              print(value.cacheType)
      
              // If the `cacheType is `.none`, `image` will be `nil`.
              print(value.image)
      
          case .failure(let error):
              print(error)
          }
      }
      
    2. 设置cache的内存大小

      设置内存缓存大小

      // 设置缓存内存最大为 300 MB.
      cache.memoryStorage.config.totalCostLimit = 300 * 1024 * 1024
      
      // 最多缓存150张图片 
      cache.memoryStorage.config.countLimit = 150
      

      设置磁盘缓存大小

      // 设置磁盘缓存内存最大 1 GB.
      cache.diskStorage.config.sizeLimit =  = 1000 * 1024 * 1024
      
    3. 设置缓存过期时间

      设置cache对象下的所有内存缓存过期时间

      // 内存缓存10分钟后过期
      cache.memoryStorage.config.expiration = .seconds(600)
      
      // 磁盘缓存永不过期
      cache.diskStorage.config.expiration = .never
      

      针对某张图片设置过期时间,内存缓存和磁盘缓存都可设置,还可以在访问缓存图片时设置memoryCacheAccessExtendingExpiration option来延长缓存时间

      imageView.kf.setImage(with: url, options: [.memoryCacheExpiration(.never)])
      
      // 在获取图片时延长缓存时间
      cache.retrieveImageInDiskCache(forKey: url.cacheKey, options: [.diskCacheAccessExtendingExpiration(.expirationTime(.seconds(100)))]) { result in
           // ...                    
      }
      
    4. 清理缓存

      1. 内存缓存每隔2分钟会清理一下缓存,如果想更频繁地清理缓存,可设置

        cache.memoryStorage.config.cleanInterval = 30
        
      2. 清理某一张图片

        cache.default.removeImage(forKey: cacheKey)
        

        或者调用更强大的方法

        cache.removeImage(
            forKey: cacheKey,
            processorIdentifier: processor.identifier,
            fromMemory: false,
            fromDisk: true)
        {
            print("Removed!")
        }
        
      3. 清理所有缓存

        cache.clearMemoryCache()
        cache.clearDiskCache { print("Done") }
        
      4. 清理过期缓存

        cache.cleanExpiredMemoryCache()
        cache.cleanExpiredDiskCache { print("Done") }
        
    5. 获取已用磁盘缓存大小

      ImageCache.default.calculateDiskStorageSize { result in
          switch result {
          case .success(let size):
              print("Disk cache size: \(Double(size) / 1024 / 1024) MB")
          case .failure(let error):
              print(error)
          }
      }
      
    6. 自定义cache

      let originalCache = ImageCache(name: "original_Cache")
      let targetCache = ImageCache(name: "target_Cache")
      

      结合option使用

      let options: [KingfisherOptionsInfoItem] = [
                          .cacheOriginalImage,                                        // 存储原始图片
                  .originalCache(originalCache),                  // 设置存储原始图片的cache
                            .targetCache(targetCache),                            // 设置目标cache,上面设置了originCache,这里会存放处理后的图片
                  .waitForCache,                                                  // 等待cache完成再执行completion closure
                  .memoryCacheExpiration(.seconds(200)),  // 设置内存缓存过期时间
                  .diskCacheExpiration(.seconds(400))         // 设置磁盘缓存过期时间
      ]
      

      上面的options实现了以下功能:

      • 存储原始图片并设置原始图片存储的cache对象为originCache,此时原始图片是存储在磁盘缓存中的;
      • 经过processor处理的图片是由targetCache负责存储的,可以结合processor.identifier在targetCache中找回图片
      • 设置了图片在内存和磁盘中缓存的过期时间

    5. Downloader - 下载器

    1. 一般情况下,建议使用UIImageView等的扩展方法或者KingfisherManager来加载图片,因为它们会将图片缓存到本地,防止重复下载;如果我们只是下载图片,不需要缓存图片,则可以这样:

      let downloader = ImageDownloader.default
      downloader.downloadImage(with: url) { result in
          switch result {
          case .success(let value):
              print(value.image)
          case .failure(let error):
              print(error)
          }
      }
      
    2. 取消下载

      如果在取消下载前,下载已经完成,则不会有任何影响。

      let task = downloader.downloadImage(with: url) { result in
          // ...
          case .failure(let error):
              print(error.isTaskCancelled) // true
          }
      
      }
      
      // 在下载完成前,取消下载
      task?.cancel()
      

      可以通过UI类的扩展方法来取消下载

      let task = imageView.kf.set(with: url)
      task?.cancel()
      

      还可以通过调用cancelDownloadTask方法来取消下载

      let task1 = imageView.kf.set(with: url1)
      let task2 = imageView.kf.set(with: url2)
      
      imageView.kf.cancelDownloadTask()
      

      task2会被取消,但是task1还是会执行。

      但是task1下载的图片不会被设置到ImageView上,因为ImageView期望的是通过url2返回的图片

    3. 自定义对服务端challenge的回应

      ImageDownloader有一个默认的.performDefaultHandling来应对服务端的挑战,我们也可以自定义对服务端挑战的回应

      // In ViewController
      ImageDownloader.default.authenticationChallengeResponder = self
      
      extension ViewController: AuthenticationChallengeResponsable {
      
          var disposition: URLSession.AuthChallengeDisposition { /* */ }
          let credential: URLCredential? { /* */ }
      
          func downloader(
              _ downloader: ImageDownloader,
              didReceive challenge: URLAuthenticationChallenge,
              completionHandler: (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
          {
              // Provide your `AuthChallengeDisposition` and `URLCredential`
              completionHandler(disposition, credential)
          }
      
          func downloader(
              _ downloader: ImageDownloader,
              task: URLSessionTask,
              didReceive challenge: URLAuthenticationChallenge,
              completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
          {
              // Provide your `AuthChallengeDisposition` and `URLCredential`
              completionHandler(disposition, credential)
          }
      }
      
    4. 设置下载超时时间

      // 设置超时时间为1分钟
      downloader.downloadTimeout = 60
      
    5. 对某一个特定的下载设置超时时间

      let modifier = AnyModifier { request in
          var r = request
          r.timeoutInterval = 60
          return r
      }
      downloader.downloadImage(with: url, options: [.requestModifier(modifier)])
      

    6. Serializer - 序列化

    序列化指的就是将Image转换成data以便进行缓存,或将data转换成Image以便展示在页面上。

    默认情况下使用的是DefaultCacheSerializer,它支持PNG,JPEG和GIF。如果我们想支持WEBP,可以通过实现CacheSerializer协议来自定义一个Serializer:

    struct WebpCacheSerializer: CacheSerializer {
        func data(with image: Image, original: Data?) -> Data? {
            return WebpFramework.webpData(of: image)
        }
        
        func image(with data: Data, options: KingfisherParsedOptionsInfo?) -> Image? {
            return WebpFramework.createImage(from: webpData)
        }
    }
    
    // 使用
    let serializer = WebpCacheSerializer()
    let url = URL(string: "https://yourdomain.com/example.webp")
    imageView.kf.setImage(with: url, options: [.cacheSerializer(serializer)])
    

    7. Prefetch - 预获取图片

    如果我们确定接下来将要使用一些图片 ,那么我们可以使用预获取功能

    let urls = ["https://example.com/image1.jpg", "https://example.com/image2.jpg"]
               .map { URL(string: $0)! }
    let prefetcher = ImagePrefetcher(urls: urls) {
        skippedResources, failedResources, completedResources in
        print("These resources are prefetched: \(completedResources)")
    }
    prefetcher.start()
    
    // 使用方法
    imageView.kf.setImage(with: urls[0])
    anotherImageView.kf.setImage(with: urls[1])
    

    可以结合iOS10以后提供的UICollectionViewDataSourcePrefetchingUITableViewDataSourcePrefetching来使用:

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView?.prefetchDataSource = self
    }
    
    extension ViewController: UICollectionViewDataSourcePrefetching {
        func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {
            let urls = indexPaths.flatMap { URL(string: $0.urlString) }
            ImagePrefetcher(urls: urls).start()
        }
    }
    

    8. ImageDataProvider - 以其它形式加载图片

    Kingfisher还支持从本地data获取图片,并结合processor来对图片进行加工处理。

    1. 从本地url获取图片

      let url = URL(fileURLWithPath: path)
      let provider = LocalFileImageDataProvider(fileURL: url)
      // 结合processor
      let processor = RoundCornerImageProcessor(cornerRadius: 20)
      imageView.kf.setImage(with: provider, options: [.processor(processor)])  
      
    2. 从base64获取图片

      let provider = Base64ImageDataProvider(base64String: "\/9j\/4AAQSkZJRgABAQA...", cacheKey: "some-cache-key")
      imageView.kf.setImage(with: provider)
      
    3. Video URLAVAsset的指定时间生成一张图片

      let provider = AVAssetImageDataProvider(
          assetURL: URL(string: "https://example.com/your_video.mp4")!,
          seconds: 15.0
      )
      
    4. 自定义ImageDataProvider

      遵守ImageDataProvider协议需要实现cacheKeydata(handler:)方法,data(handler:)方法的参数handler是一个闭包,闭包的参数是Result类型,所以,我们需要将经过处理的最终image data传递给Result。

      struct UserNameLetterIconImageProvider: ImageDataProvider {
          var cacheKey: String { return letter }
          let letter: String
          
          init(userNameFirstLetter: String) {
              self.letter = userNameFirstLetter
          }
          
          func data(handler: @escaping (Result<Data, Error>) -> Void) {
              
              // You can ignore these detail below.
              // It generates some data for an image with `letter` being rendered in the center.
      
              let letter = self.letter as NSString
              let rect = CGRect(x: 0, y: 0, width: 250, height: 250)
              let renderer = UIGraphicsImageRenderer(size: rect.size)
              let data = renderer.pngData { context in
                  UIColor.black.setFill()
                  context.fill(rect)
                  
                  let attributes = [
                      NSAttributedString.Key.foregroundColor: UIColor.white,
                                            .font: UIFont.systemFont(ofSize: 200)
                  ]
                  
                  let textSize = letter.size(withAttributes: attributes)
                  let textRect = CGRect(
                      x: (rect.width - textSize.width) / 2,
                      y: (rect.height - textSize.height) / 2,
                      width: textSize.width,
                      height: textSize.height)
                  letter.draw(in: textRect, withAttributes: attributes)
              }
      
              // Provide the image data in `handler`.
              handler(.success(data))
          }
      }
      
      // Set image for user "John"
      let provider = UserNameLetterIconImageProvider(userNameFirstLetter: "J")
      imageView.kf.setImage(with: provider)
      

    9. Indicator - 加载指示器

    1. 使用gif作为指示器

      let path = Bundle.main.path(forResource: "loader", ofType: "gif")!
      let data = try! Data(contentsOf: URL(fileURLWithPath: path))
      
      imageView.kf.indicatorType = .image(imageData: data)
      imageView.kf.setImage(with: url)
      
    2. 自定义的Indicator

      struct MyIndicator: Indicator {
          let view: UIView = UIView()
          
          func startAnimatingView() { view.isHidden = false }
          func stopAnimatingView() { view.isHidden = true }
          
          init() {
              view.backgroundColor = .red
          }
      }
      
      // 调用
      let i = MyIndicator()
      imageView.kf.indicatorType = .custom(indicator: i)
      
    3. 自定义Indicator结合progressBlock使用

      imageView.kf.setImage(with: url, progressBlock: {
          receivedSize, totalSize in
          let percentage = (Float(receivedSize) / Float(totalSize)) * 100.0
          print("downloading progress: \(percentage)%")
          myIndicator.percentage = percentage
      })
      

      注意:只有当服务端返回的response的header中包含Content-Length时,progressBlock才会执行。

    10. Retry - 重试

    // 最多重试5次,每次间隔3秒
    let retry = DelayRetryStrategy(maxRetryCount: 5, retryInterval: .seconds(3))
    // 结合option使用
    imageView.kf.setImage(with: url, options: [.retryStrategy(retry)])
    

    .second(3)DelayRetryStrategy.Interval的一个枚举项,还可以选择accumulated(3),这样重试的触发间隔时间就是3, 6, 9, 12, ...

    相关文章

      网友评论

        本文标题:Kingfisher使用方法

        本文链接:https://www.haomeiwen.com/subject/sveoldtx.html