Kingfisher is a powerful, pure-Swift library for downloading and caching images from the web

Overview

Kingfisher


Kingfisher is a powerful, pure-Swift library for downloading and caching images from the web. It provides you a chance to use a pure-Swift way to work with remote images in your next app.

Features

  • Asynchronous image downloading and caching.
  • Loading image from either URLSession-based networking or local provided data.
  • Useful image processors and filters provided.
  • Multiple-layer hybrid cache for both memory and disk.
  • Fine control on cache behavior. Customizable expiration date and size limit.
  • Cancelable downloading and auto-reusing previous downloaded content to improve performance.
  • Independent components. Use the downloader, caching system, and image processors separately as you need.
  • Prefetching images and showing them from the cache to boost your app.
  • View extensions for UIImageView, NSImageView, NSButton and UIButton to directly set an image from a URL.
  • Built-in transition animation when setting images.
  • Customizable placeholder and indicator while loading images.
  • Extensible image processing and image format easily.
  • Low Data Mode support.
  • SwiftUI support.

Kingfisher 101

The simplest use-case is setting an image to an image view with the UIImageView extension:

import Kingfisher

let url = URL(string: "https://example.com/image.png")
imageView.kf.setImage(with: url)

Kingfisher will download the image from url, send it to both memory cache and disk cache, and display it in imageView. When you set with the same URL later, the image will be retrieved from the cache and shown immediately.

It also works if you use SwiftUI:

var body: some View {
    KFImage(URL(string: "https://example.com/image.png")!)
}

A More Advanced Example

With the powerful options, you can do hard tasks with Kingfisher in a simple way. For example, the code below:

  1. Downloads a high-resolution image.
  2. Downsamples it to match the image view size.
  3. Makes it round cornered with a given radius.
  4. Shows a system indicator and a placeholder image while downloading.
  5. When prepared, it animates the small thumbnail image with a "fade in" effect.
  6. The original large image is also cached to disk for later use, to get rid of downloading it again in a detail view.
  7. A console log is printed when the task finishes, either for success or failure.
RoundCornerImageProcessor(cornerRadius: 20) imageView.kf.indicatorType = .activity imageView.kf.setImage( with: url, placeholder: UIImage(named: "placeholderImage"), options: [ .processor(processor), .scaleFactor(UIScreen.main.scale), .transition(.fade(1)), .cacheOriginalImage ]) { result in switch result { case .success(let value): print("Task done for: \(value.source.url?.absoluteString ?? "")") case .failure(let error): print("Job failed: \(error.localizedDescription)") } } ">
let url = URL(string: "https://example.com/high_resolution_image.png")
let processor = DownsamplingImageProcessor(size: imageView.bounds.size)
             |> RoundCornerImageProcessor(cornerRadius: 20)
imageView.kf.indicatorType = .activity
imageView.kf.setImage(
    with: url,
    placeholder: UIImage(named: "placeholderImage"),
    options: [
        .processor(processor),
        .scaleFactor(UIScreen.main.scale),
        .transition(.fade(1)),
        .cacheOriginalImage
    ])
{
    result in
    switch result {
    case .success(let value):
        print("Task done for: \(value.source.url?.absoluteString ?? "")")
    case .failure(let error):
        print("Job failed: \(error.localizedDescription)")
    }
}

It is a common situation I can meet in my daily work. Think about how many lines you need to write without Kingfisher!

Method Chaining

If you are not a fan of the kf extension, you can also prefer to use the KF builder and chained the method invocations. The code below is doing the same thing:

// Use `kf` extension
imageView.kf.setImage(
    with: url,
    placeholder: placeholderImage,
    options: [
        .processor(processor),
        .loadDiskFileSynchronously,
        .cacheOriginalImage,
        .transition(.fade(0.25)),
        .lowDataMode(.network(lowResolutionURL))
    ],
    progressBlock: { receivedSize, totalSize in
        // Progress updated
    },
    completionHandler: { result in
        // Done
    }
)

// Use `KF` builder
KF.url(url)
  .placeholder(placeholderImage)
  .setProcessor(processor)
  .loadDiskFileSynchronously()
  .cacheMemoryOnly()
  .fade(duration: 0.25)
  .lowDataModeSource(.network(lowResolutionURL))
  .onProgress { receivedSize, totalSize in  }
  .onSuccess { result in  }
  .onFailure { error in }
  .set(to: imageView)

And even better, if later you want to switch to SwiftUI, just make some trivial changes and you've done.

struct ContentView: View {
    var body: some View {
        KFImage.url(url)
          .placeholder(placeholderImage)
          .setProcessor(processor)
          .loadDiskFileSynchronously()
          .cacheMemoryOnly()
          .fade(duration: 0.25)
          .lowDataModeSource(.network(lowResolutionURL))
          .onProgress { receivedSize, totalSize in  }
          .onSuccess { result in  }
          .onFailure { error in }
    }
}

Learn More

To learn the use of Kingfisher by more examples, take a look at the well-prepared Cheat Sheet. T here we summarized the most common tasks in Kingfisher, you can get a better idea of what this framework can do. There are also some performance tips, remember to check them too.

Requirements

  • iOS 10.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+
  • Swift 4.0+

Installation

A detailed guide for installation can be found in Installation Guide.

Swift Package Manager

  • File > Swift Packages > Add Package Dependency
  • Add https://github.com/onevcat/Kingfisher.git
  • Select "Up to Next Major" with "6.0.0"

CocoaPods

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!

target 'MyApp' do
  pod 'Kingfisher', '~> 6.0'
end

Carthage

6.0 ">
github "onevcat/Kingfisher" ~> 6.0

Migrating

Kingfisher 6.0 Migration - Kingfisher 6.x is NOT fully compatible with the previous version. However, the migration is not difficult. Depending on your use cases, it may take no effect or several minutes to modify your existing code for the new version. Please follow the migration guide when you prepare to upgrade Kingfisher in your project.

If you are using an even earlier version, see the guides below to know the steps for migrating.

  • Kingfisher 5.0 Migration - If you are upgrading to Kingfisher 5.x from 4.x, please read this for more information.
  • Kingfisher 4.0 Migration - Kingfisher 3.x should be source compatible to Kingfisher 4. The reason for a major update is that we need to specify the Swift version explicitly for Xcode. All deprecated methods in Kingfisher 3 were removed, so please ensure you have no warning left before you migrate from Kingfisher 3 to Kingfisher 4. If you have any trouble when migrating, please open an issue to discuss.
  • Kingfisher 3.0 Migration - If you are upgrading to Kingfisher 3.x from an earlier version, please read this for more information.

Next Steps

We prepared a wiki page. You can find tons of useful things there.

  • Installation Guide - Follow it to integrate Kingfisher into your project.
  • Cheat Sheet- Curious about what Kingfisher could do and how would it look like when used in your project? See this page for useful code snippets. If you are already familiar with Kingfisher, you could also learn new tricks to improve the way you use Kingfisher!
  • API Reference - Lastly, please remember to read the full whenever you may need a more detailed reference.

Other

Future of Kingfisher

I want to keep Kingfisher lightweight. This framework focuses on providing a simple solution for downloading and caching images. This doesn’t mean the framework can’t be improved. Kingfisher is far from perfect, so necessary and useful updates will be made to make it better.

Developments and Tests

Any contributing and pull requests are warmly welcome. However, before you plan to implement some features or try to fix an uncertain issue, it is recommended to open a discussion first. It would be appreciated if your pull requests could build and with all tests green. :)

About the logo

The logo of Kingfisher is inspired by Tangram (七巧板), a dissection puzzle consisting of seven flat shapes from China. I believe she's a kingfisher bird instead of a swift, but someone insists that she is a pigeon. I guess I should give her a name. Hi, guys, do you have any suggestions?

Contact

Follow and contact me on Twitter or Sina Weibo. If you find an issue, open a ticket. Pull requests are warmly welcome as well.

Backers & Sponsors

Open-source projects cannot live long without your help. If you find Kingfisher is useful, please consider supporting this project by becoming a sponsor. Your user icon or company logo shows up on my blog with a link to your home page.

Become a sponsor through GitHub Sponsors or Open Collective. ❤️

License

Kingfisher is released under the MIT license. See LICENSE for details.

Comments
  • AnimatedImageView crash

    AnimatedImageView crash

    Check List

    Thanks for considering to open an issue. Before you submit your issue, please confirm these boxes are checked.

    Issue Description

    What

    Since the update to Kingfisher 7.0.0 users have been reporting several crashes inside our app. Our crash reporting software captured the stack traces and it seems to be inside the Kingfisher iOS SDK.

    • AnimatedImageView.Animator.loadFrame(at:) Stack Trace:

    Crashed: com.onevcat.Kingfisher.Animator.preloadQueue 0 libsystem_platform.dylib 0x1a44 _platform_memmove + 548 1 CoreFoundation 0xb32f8 CFDataGetBytes + 328 2 ImageIO 0x1500 CGImageGetImageSource + 152 3 UIKitCore 0x203024 -[_UIImageCGImageContent initWithCGImage:scale:] + 36 4 UIKitCore 0x18c3ec -[UIImage initWithCGImage:scale:orientation:] + 72 5 Woebot 0x266520 AnimatedImageView.Animator.loadFrame(at:) + 4336739616 (:4336739616) 6 Woebot 0x2667b8 AnimatedImageView.Animator.updatePreloadedFrames() + 575 (AnimatedImageView.swift:575) 7 Woebot 0x1d51f0 thunk for @escaping @callee_guaranteed () -> () + 4336144880 (:4336144880) 8 libdispatch.dylib 0x632ec _dispatch_call_block_and_release + 24 9 libdispatch.dylib 0x642f0 _dispatch_client_callout + 16 10 libdispatch.dylib 0x3f410 _dispatch_lane_serial_drain$VARIANT$armv81 + 596 11 libdispatch.dylib 0x3feb8 _dispatch_lane_invoke$VARIANT$armv81 + 388 12 libdispatch.dylib 0x4976c _dispatch_workloop_worker_thread + 616 13 libsystem_pthread.dylib 0xf38 _pthread_wqthread + 284 14 libsystem_pthread.dylib 0xaa4 start_wqthread + 8

    • AnimatedImageView.Animator.updatePreloadedFrames() Stack Trace:

    Crashed: com.onevcat.Kingfisher.Animator.preloadQueue 0 CoreFoundation 0xbc124 CFDataGetBytes + 156 1 ImageIO 0x2700 CGImageGetImageSource + 156 2 UIKitCore 0x215c74 -[_UIImageCGImageContent initWithCGImage:scale:] + 40 3 UIKitCore 0x19cee0 -[UIImage initWithCGImage:scale:orientation:] + 76 4 Woebot 0x266520 (Missing) 5 Woebot 0x2667b8 AnimatedImageView.Animator.updatePreloadedFrames() + 575 (AnimatedImageView.swift:575) 6 Woebot 0x1d51f0 thunk for @escaping @callee_guaranteed () -> () + 4309012976 (:4309012976) 7 libdispatch.dylib 0x1c04 _dispatch_call_block_and_release + 32 8 libdispatch.dylib 0x3950 _dispatch_client_callout + 20 9 libdispatch.dylib 0xb0ac _dispatch_lane_serial_drain + 664 10 libdispatch.dylib 0xbc10 _dispatch_lane_invoke + 392 11 libdispatch.dylib 0x16318 _dispatch_workloop_worker_thread + 656 12 libsystem_pthread.dylib 0x11b0 _pthread_wqthread + 288 13 libsystem_pthread.dylib 0xf50 start_wqthread + 8

    AnimatedImageView is used inside the app to display an image full screen.

    Reproduce

    class FullScreenImageViewController: UIViewController {
        private var imageView: AnimatedImageView!
        private var scrollView: UIScrollView!
    
        private static let animationDuration: TimeInterval = 0.15
    
        func showFullScreen(animatedImageView: AnimatedImageView) {
            self.setupScrollView()
    
            self.imageView = AnimatedImageView(image: animatedImageView.image)
            self.imageView.contentMode = .scaleAspectFit
    
            guard let delegate = UIApplication.shared.delegate,
                let wrappedWindow = delegate.window,
                let window = wrappedWindow,
                let rootViewController = window.rootViewController,
                let imageSize = animatedImageView.image?.size
            else { return }
    
            self.scrollView.addSubview(self.imageView)
            rootViewController.view.addSubview(self.scrollView)
    
            self.imageView.translatesAutoresizingMaskIntoConstraints = false
            self.imageView.widthAnchor.constraint(lessThanOrEqualTo: self.scrollView.widthAnchor).isActive = true
            self.imageView.heightAnchor.constraint(equalTo: self.imageView.widthAnchor, multiplier: imageSize.height / imageSize.width).isActive = true
            self.imageView.heightAnchor.constraint(lessThanOrEqualTo: self.scrollView.heightAnchor).isActive = true
            self.imageView.centerXAnchor.constraint(equalTo: self.scrollView.centerXAnchor).isActive = true
            self.imageView.centerYAnchor.constraint(equalTo: self.scrollView.centerYAnchor).isActive = true
    
            UIView.animate(withDuration: FullScreenImageViewController.animationDuration) {
                self.scrollView.alpha = 1
            }
        }
    
        private func setupScrollView() {
            self.scrollView = UIScrollView(frame: UIScreen.main.bounds)
            self.scrollView.maximumZoomScale = 2.0
            self.scrollView.delegate = self
            self.scrollView.backgroundColor = .black
            self.scrollView.alpha = 0
            self.scrollView.showsVerticalScrollIndicator = false
            self.scrollView.showsHorizontalScrollIndicator = false
    
            let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.dismissFullscreenImage))
            self.scrollView.addGestureRecognizer(tapGestureRecognizer)
            let swipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(self.dismissFullscreenImage))
            swipeGestureRecognizer.direction = .down
            self.scrollView.addGestureRecognizer(swipeGestureRecognizer)
            let doubleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.didDoubleTap))
            doubleTapGestureRecognizer.numberOfTapsRequired = 2
            self.scrollView.addGestureRecognizer(doubleTapGestureRecognizer)
            tapGestureRecognizer.require(toFail: doubleTapGestureRecognizer)
        }
    
        @objc private func dismissFullscreenImage(_ sender: UIGestureRecognizer) {
            UIView.animate(withDuration: FullScreenImageViewController.animationDuration, animations: {
                sender.view?.alpha = 0
            }, completion: { _ in
                sender.view?.removeFromSuperview()
                self.removeFromParent()
            })
        }
    
        @objc private func didDoubleTap(_ sender: UITapGestureRecognizer) {
            guard self.scrollView.zoomScale == 1 else {
                self.scrollView.setZoomScale(1, animated: true)
                return
            }
            let zoomRect = self.zoomRect(forScale: self.scrollView.maximumZoomScale, center: sender.location(in: sender.view))
            self.scrollView.zoom(to: zoomRect, animated: true)
        }
    
        private func zoomRect(forScale scale: CGFloat, center: CGPoint) -> CGRect {
            var zoomRect: CGRect = .zero
            zoomRect.size.height = imageView.frame.size.height / scale
            zoomRect.size.width = imageView.frame.size.width / scale
            let newCenter = self.scrollView.convert(center, from: imageView)
            zoomRect.origin.x = newCenter.x - (zoomRect.size.width / 2.0)
            zoomRect.origin.y = newCenter.y - (zoomRect.size.height / 2.0)
            return zoomRect
        }
    }
    

    Other Comment

    opened by MalcolmnDEV 39
  • No such module 'Kingfisher'

    No such module 'Kingfisher'

    Issue Description

    I am following steps https://github.com/onevcat/Kingfisher/wiki/Installation-Guide#manually. And getting 'No such module found 'Kingfisher' error.

    What

    I wish to add 'Kingfisher' as submodule under my project, and following the steps for manual installation, but getting this error. I have almost tried everything I could try, such as http://stackoverflow.com/questions/29500227/getting-error-no-such-module-using-xcode-but-the-framework-is-there; even I had re-installed latest Xcode (i.e. 8.3), but the issue still persists. I am trying to make it work since 3 days now, but no luck. I am attaching screenshots, just in case, those could help to figure out the error. This sample test app contains only the code visible on screen shot.

    Kindly help me out with this.

    Thanks. screen shot 2017-04-07 at 9 56 13 am screen shot 2017-04-07 at 9 56 25 am screen shot 2017-04-07 at 9 57 14 am screen shot 2017-04-07 at 10 20 36 am

    opened by KairaKrishna 31
  • ResizingImageProcessor return a low quality image

    ResizingImageProcessor return a low quality image

    Check List

    Thanks for considering to open an issue. Before you submit your issue, please confirm these boxes are checked.

    Issue Description

    ResizingImageProcessor return a low quality image.

    What

    Using ResizingImageProcessor the result is low quality image

    Reproduce

    Just use ResizingImageProcessor

    Other Comment

    Original Image: https://www.dropbox.com/s/l4rkyppkcjrd468/orginal.jpg?dl=0

    This is the code I used:

    let scale = UIScreen.main.scale
    let resizingProcessor = ResizingImageProcessor(referenceSize: CGSize(width: 100.0 * scale, height: 100.0 * scale))
    let url = URL(string: path)
    imageView.kf.indicatorType = .activity
    imageView.kf.setImage(with: url,
                          options: [.processor(resizingProcessor)],
                          completionHandler: { [ weak self] image, error, cacheType, imageURL in
                              self?.imageView.layer.shadowOpacity = 0.5
                          }
    )
    

    Result: https://www.dropbox.com/s/8b2dxmswd6z2y72/low_quality.PNG?dl=0 It seems like a blur effect is applied.

    For testing I had to use Toucan for resize the image and the result image is like expected even without using scale factor. Would be nice if you guys can fix this problem so I can avoid to use other library.

    let url = URL(string: path)
    imageView.kf.indicatorType = .activity
    imageView.kf.setImage(with: url,
                          options: nil,
                          completionHandler: { [ weak self] image, error, cacheType, imageURL in
                              guard let image = image else { return }
                              let resizedImage = Toucan(image: image).resize(CGSize(width: 100.0, height: 100.0),
                                                                             fitMode: .crop).image
                              self?.imageView.image = resizedImage
                              self?.imageView.layer.shadowOpacity = 0.5
                          }
    )
    

    Result: https://www.dropbox.com/s/q286gjh3jzuheo9/high_quality.PNG?dl=0

    opened by carmelogallo 28
  • app crashs on iOS 14 when use Kingfisher in List

    app crashs on iOS 14 when use Kingfisher in List

    Hello

    yes I know iOS 14 is still in beta but maybe it helps you ;-)

    I use kingfisher in a SwiftUI List to load pictures from urls. The initial state is shown as expected, but when I start scrolling the app crashs with a Bad Access- Error.

    If I delete the KFImage everything working well.

    If I use the same url for every cell it also works fine.

    Maybe there is some problem when SwiftUI tries to reuse the Cell and can't load the image somehow.

    Does anybody has an idea what to do ?

    opened by hassfers 26
  • UIImageView Flashing

    UIImageView Flashing

    Check List

    Thanks for considering to open an issue. Before you submit your issue, please confirm these boxes are checked.

    Issue Description

    UIImageView Flashing.

    Reproduce

    First exit the background, then return to the foreground, refresh the TableView, UIImageView flickerin.

    Other Comment

    Because Kingfisher's memory cache uses NSCache, Apple will clear the cache when the application exits to the background, which may cause flickering when the cell is refreshed. SDWebImage has made a layer of MapTable to handle this problem. I wonder if Kingfisher has a similar plan, sorry for the poor English, thank you.

    opened by liangdahong 25
  • Images don't show (sometimes, for round cornered image view)

    Images don't show (sometimes, for round cornered image view)

    I was using leancloud to store the images, the server always return some URLs like

    "http://ac-rkozbmni.clouddn.com/evvaTGCJTJwE6EDTZDLUGrA?imageView/2/w/300/h/300/q/100"

    these urls didn't work with kingfisher, and the normal ones with extension filenames did work. like "http://sb.com/sb.png".

    and i was using this to set the imageView " imageView.kf_setImageWithURL(NSURL(string: a))"

    how could this be resolved

    thanks a Lot!!!

    opened by duckjpsgaintas 25
  • Loading indicator disappears randomly.

    Loading indicator disappears randomly.

    I found the loading indicator can disappear sometimes in such a scenario, but I have not found a consistent repro yet.

    This happens in a table view with some chat messages. 1 fill the table view with about a dozen messages; 2 inert an image message whose image is managed by Kingfisher by calling: imageView?.kf_showIndicatorWhenLoading = true imageView?.kf_indicatorType = .Activity imageView?.kf_setImageWithURL(...) with a placeholder image; now the loading indicator shows up; 3 while the image is being loaded, scroll it out of the view port of the table, so that the image is not visible; 4 scroll the image back into the view port to make it visible; now the loading indicator could be missing even when the image is still being loaded.

    opened by hifall 24
  • Library not loaded: @rpath/libswiftAccelerate.dylib

    Library not loaded: @rpath/libswiftAccelerate.dylib

    Issue Description

    What

    When including Kingfisher using latest Carthage in a project which has subprojects as components, when running one of the subprojects tests we get the following error:

    2018-04-17 14:14:03.494908+0200 xctest[8052:65955] The bundle “MyProjectUITests” couldn’t be loaded because it is damaged or missing necessary resources. Try reinstalling the bundle.
    2018-04-17 14:14:03.495059+0200 xctest[8052:65955] (dlopen_preflight(/Users/Me/Library/Developer/Xcode/DerivedData/MyProjectiOS-cmerazywlpjaaidjguatkfroiqih/Build/Products/Debug-iphonesimulator/MyProjectUITests.xctest/FitterYouUITests): Library not loaded: @rpath/libswiftAccelerate.dylib
      Referenced from: /Users/Me/Code/Apple/MyProject/Carthage/Build/iOS/Kingfisher.framework/Kingfisher
      Reason: image not found)
    Program ended with exit code: 82
    

    Other Comment

    As you can see it seems there's an issue with the Accellerate framework which is included. I'm guessing that since the dependency isn't placed directly into the component project, Xcode has problems including the implicit dependency without explicitly stating where it is. The usual search paths (I know about @loader_path and @rpaths – already tried those approaches to fix this) seem not to be enough.

    opened by Jeehut 21
  • parse ImageProcessItem Data to raw value

    parse ImageProcessItem Data to raw value

    Hi, i am working with SVG i read about cheat sheet and found this

    func process(item: ImageProcessItem, options: KingfisherOptionsInfo) -> UIImage? {
         switch item {
         case .image(let image):
             print("already an image")
             return image
         case .data(let data):
    
         }
     }
    

    i want to ask, is it possible to parse data to svg raw value... i tried to parse using

    data.base64EncodedString()

    it's not raw svg content

    Thank you in advance

    opened by black-lotus 21
  • Update new image not work

    Update new image not work

    Check List

    Thanks for considering to open an issue. Before you submit your issue, please confirm these boxes are checked.

    Issue Description

    I have an avatar and want to update it, after I upload a new image and get a new URL, then the setImage function still gives me the old one. This code is triggered whenever it has a new URL.

    let url = URL(string: profile.avatar60 ?? "")
    avatarImageView.kf.setImage(with: url, placeholder: #imageLiteral(resourceName: "ic_profile_default"), options: [.transition(ImageTransition.fade(0.5))])
    

    Then I cheat with this way to work (but some time it does not work)

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
          let url = URL(string: profile.avatar60 ?? "")
          me.avatarImageView.kf.setImage(with: url, placeholder: #imageLiteral(resourceName: "ic_profile_default"), options: [.forceRefresh, .transition(ImageTransition.fade(0.5))])
    })
    

    So what is the exactly problem?

    opened by khuong291 20
  • Error when using Kingfisher with SPM and Xcode 11.4 beta 3

    Error when using Kingfisher with SPM and Xcode 11.4 beta 3

    Check List

    Issue Description

    What

    I'm using Kingfisher in both my containing app, and two other targets. I've added it using Swift Package Manager on Xcode. On Xcode 11.3 everything works fine, but when updating to Xcode 11.4 beta 3, I started to get the following error:

    Swift package product 'Kingfisher' is linked as a static library by {APP NAME} and 2 other targets. This will result in duplication of library code.

    Reproduce

    • Create a new project and add Kingfisher as a dependency using Swift Package Manager on Xcode
    • Create a new target and add Kingfisher in the Frameworks and Libraries section
    • Build the project using Xcode 11.4 beta 3

    Other Comment

    Is this something to do with the way my project is organized, or is something that needs to be fixed on the Kingfisher project? Or is bug in Xcode?

    Thanks!

    opened by marcosatanaka 19
  • KFImage doesn't allow to configure Image as a View (SwiftUI)

    KFImage doesn't allow to configure Image as a View (SwiftUI)

    Check List

    Thanks for considering to open an issue. Before you submit your issue, please confirm these boxes are checked.

    Issue Description

    What

    I want to apply a scaledToFill() modifier to the loaded Image and a scaledToFit() to the placeholder View but it is not possible because the KFImage.configure function requires to return an Image instead of a View.

    public func configure(_ block: @escaping (HoldingView) -> HoldingView) -> Self
    

    (Where HoldingView is an Image for KFImage)

    If we take the AsyncImage as an example, it allows to configure the Image and returns some View instead

    Reproduce

    Here is a code that reproduce the issue:

    import SwiftUI
    import Kingfisher
    
    struct ImageWrapper: View {
        var url: URL
        
        var body: some View {
            KFImage(url)
                .resizable()
                .configure({ image in
                    image
                        //.scaledToFill() // ⛔️ NOT ALLOWED
                })
                .placeholder {
                    Image(systemName: "arrow.triangle.2.circlepath")
                        .resizable()
                        .scaledToFit()
                }
        }
    }
    
    struct ContentView: View {
        var body: some View {
            VStack {
                // Image with correct URL (1000x1000)
                image(from: URL(string: "https://i.picsum.photos/id/106/1000/1000.jpg?hmac=iWNYUAKllk_GfeYH2QJNaFV7rimXMzblGILOLol7jPQ")!)
                
                // Image with bad URL so the placeholder will be visible
                image(from: URL(string: "https://i.picsum.photos/id/106/1000/1000.jpg?hmac=TEST")!)
            }
        }
        
        @ViewBuilder
        private func image(from url: URL) -> some View {
            ImageWrapper(url: url)
                .scaledToFill() // ⛔️ If I do that, it overrides the `scaledToFit()` of the placeholder
                .frame(width: 200, height: 100)
                .clipped()
        }
    }
    

    Other Comment

    I am working on a project that support iOS 14+

    opened by omar-belhaouss 0
  • AnimatedImageView crash in version6.3.1

    AnimatedImageView crash in version6.3.1

    Check List

    Thanks for considering to open an issue. Before you submit your issue, please confirm these boxes are checked.

    Issue Description

    What

    AnimatedImageView crash in version6.3.1 20230105142337

    Reproduce

    Other Comment

    My project need support iOS10+, so what should I do?

    opened by a7340103 1
  • Rare crash in KingfisherWrapper

    Rare crash in KingfisherWrapper

    Check List

    Issue Description

    What

    Recently we got a crash report on Firebase that KingfisherWrapper.draw have crashed couple of times. It is not common so it is not high priority but still we decided to report it. Crash is Crashed: EXC_BAD_ACCESS KERN_INVALID_ADDRESS on com.onevcat.Kingfisher.ImageDownloader.Process queue. The stack trace is:

    Crashed: com.onevcat.Kingfisher.ImageDownloader.Process
    0  CoreGraphics                   0xd6c8 img_data_lock + 5492
    1  CoreGraphics                   0x58e04 CGSImageDataLock + 1320
    2  CoreGraphics                   0x27ee4 ripc_AcquireRIPImageData + 772
    3  CoreGraphics                   0x47810 ripc_DrawImage + 804
    4  CoreGraphics                   0x3e058 CG::DisplayList::executeEntries(std::__1::__wrap_iter<std::__1::unique_ptr<CG::DisplayListEntry const, std::__1::default_delete<CG::DisplayListEntry const> >*>, std::__1::__wrap_iter<std::__1::unique_ptr<CG::DisplayListEntry const, std::__1::default_delete<CG::DisplayListEntry const> >*>, CGContextDelegate*, CGRenderingState*, CGGStack*, CGRect const*, __CFDictionary const*, bool) + 4948
    5  CoreGraphics                   0x322fc CGDisplayListDrawInContextDelegate + 268
    6  CoreGraphics                   0x75fa0 rip_auto_context_rasterization_loop + 1924
    7  CoreGraphics                   0xa36dc rip_auto_context_create_image + 56
    8  UIKitCore                      0x1ba064 -[UIGraphicsImageRendererContext currentImage] + 32
    9  UIKitCore                      0x1ba014 __44-[UIGraphicsImageRenderer imageWithActions:]_block_invoke + 28
    10 UIKitCore                      0x1ba400 -[UIGraphicsRenderer runDrawingActions:completionActions:format:error:] + 360
    11 UIKitCore                      0x1ba270 -[UIGraphicsRenderer runDrawingActions:completionActions:error:] + 92
    12 UIKitCore                      0x1ba19c -[UIGraphicsImageRenderer imageWithActions:] + 184
    13 Kingfisher                     0x4e384 specialized KingfisherWrapper<A>.draw(to:inverting:scale:refImage:draw:) + 598 (ImageDrawing.swift:598)
    14 Kingfisher                     0x50dc0 ResizingImageProcessor.process(item:options:) + 231 (ImageDrawing.swift:231)
    15 Kingfisher                     0x50e60 protocol witness for ImageProcessor.process(item:options:) in conformance ResizingImageProcessor + 40 (<compiler-generated>:40)
    16 CCCImages                      0x67bc SizeValidatingImageProcessor.process(item:options:) + 41 (SizeValidatingImageProcessor.swift:41)
    17 CCCImages                      0x6828 protocol witness for ImageProcessor.process(item:options:) in conformance SizeValidatingImageProcessor + 1064 (<compiler-generated>:1064)
    18 Kingfisher                     0x4f438 partial apply for closure #1 in ImageProcessor.append(another:) + 93 (ImageProcessor.swift:93)
    19 Kingfisher                     0x4f328 protocol witness for ImageProcessor.process(item:options:) in conformance GeneralProcessor + 20 (<compiler-generated>:20)
    20 CCCImages                      0x6764 SizeValidatingImageProcessor.process(item:options:) + 43 (SizeValidatingImageProcessor.swift:43)
    21 CCCImages                      0x6828 protocol witness for ImageProcessor.process(item:options:) in conformance SizeValidatingImageProcessor + 1064 (<compiler-generated>:1064)
    22 Kingfisher                     0x39344 ImageDataProcessor.doProcess() + 58 (ImageDataProcessor.swift:58)
    23 Kingfisher                     0x38fa4 implicit closure #2 in implicit closure #1 in ImageDataProcessor.process() + 20 (<compiler-generated>:20)
    24 Kingfisher                     0xeea0 partial apply for closure #1 in CallbackQueue.execute(_:) + 20 (<compiler-generated>:20)
    25 Kingfisher                     0xe964 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:28)
    26 libdispatch.dylib              0x24b4 _dispatch_call_block_and_release + 32
    27 libdispatch.dylib              0x3fdc _dispatch_client_callout + 20
    28 libdispatch.dylib              0xb694 _dispatch_lane_serial_drain + 672
    29 libdispatch.dylib              0xc1e0 _dispatch_lane_invoke + 384
    30 libdispatch.dylib              0x16e10 _dispatch_workloop_worker_thread + 652
    31 libsystem_pthread.dylib        0xdf8 _pthread_wqthread + 288
    32 libsystem_pthread.dylib        0xb98 start_wqthread + 8
    

    SizeValidatingImageProcessor is our simple wrapper for ResizingImageProcessor and it doesn't configure it in any way.

    Reproduce

    Unfortunately, we don't have steps of reproduction. The only thing what I can say is that the image was normal jpg, something like this.

    Other Comment

    Kingfisher version: 7.4.0 iOS version: 16.0.x

    opened by pwadowski 1
  • KFImage Placeholder modifier has progress value, but imageView.kf doesnt

    KFImage Placeholder modifier has progress value, but imageView.kf doesnt

    Issue Description

    Firstly, i'am using swiftui. in KFImage i can use progress value for showing loading indicator.

    { 
    KFImage.url(viewModel.url)
                        .placeholder { progress in
                            Image("imagePlaceholder")
                            VStack {
                                Image("imagePlaceholder")
                                    .padding()
                            }
                            .overlay(ZStack {
                                Circle()
                                    .stroke(
                                        HR.Color.General.primary.opacity(0.5),
                                        lineWidth: 1
                                    )
                                Circle()
                                    .trim(from: 0, to: progress.fractionCompleted)
                                    .stroke(
                                        HR.Color.General.primary,
                                        style: StrokeStyle(
                                            lineWidth: 1,
                                            lineCap: .round
                                        )
                                    )
                                    .rotationEffect(.degrees(-90))
                                    // 1
                                    .animation(.easeOut, value: progress.fractionCompleted)
    
                            })
                            
                        }
    }
    

    but there is nothing to do for gif images

    public struct KFAnimatedImage: UIViewRepresentable {
        var resource: Resource
        
        @Binding var isPlaying: Bool
        @Binding var shouldPause: Bool
        @Binding var isImageBroken: Bool
        
        
        public func makeUIView(context: Context) -> AnimatedImageView {
            let view = AnimatedImageView()
            view.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
            view.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
            return view
        }
        
        public func updateUIView(_ uiView: AnimatedImageView, context: Context) {
            uiView.autoPlayAnimatedImage = false
            let failureImage = UIImage(named: "brokenImage")
            uiView.kf.setImage(with: resource, placeholder: UIImage(named: "placeholder"), options: [.onFailureImage(failureImage), .retryStrategy(DelayRetryStrategy(maxRetryCount: 5,retryInterval: .accumulated(3)))]) { result in
                switch result {
                case .success(_):
                    if isPlaying {
                        uiView.startAnimating()
                    }
                default:
                    break
                }
            }
            if isPlaying {
                uiView.startAnimating()
            } else {
                uiView.stopAnimating()
            }
        }
    }
    
    opened by bilalmarifet 1
  • Crash when loading gif (Use the specified commit: 229f637beeb7b4ef81006e951a17a7cf2c52ccf0)

    Crash when loading gif (Use the specified commit: 229f637beeb7b4ef81006e951a17a7cf2c52ccf0)

    Check List

    Thanks for considering to open an issue. Before you submit your issue, please confirm these boxes are checked.

    Issue Description

    What

    Crash when loading gif, use the specified commit: 229f637beeb7b4ef81006e951a17a7cf2c52ccf0 (A rare crash from _UIImageCGImageContent when loading GIF files on iOS 15 or later. https://github.com/onevcat/Kingfisher/pull/2004)

    Reproduce

    Hard to reproduce. I reproduced it on the first installation.

    Other Comment

    Here is the crash log: Thread 2 name: Dispatch queue: com.onevcat.Kingfisher.Animator.preloadQueue Thread 2 Crashed: 0 libsystem_platform.dylib 0x1e2524a74 _platform_memmove + 420 1 CoreFoundation 0x195d66b74 CFDataGetBytes + 380 2 ImageIO 0x19ae2f888 CGImageGetImageSource + 156 3 UIKitCore 0x197fd9dc4 -[_UIImageCGImageContent initWithCGImage:scale:] + 40 4 UIKitCore 0x197fd9d5c -[UIImage initWithCGImage:scale:orientation:] + 68 5 Rolls-Royce Whispers Live 0x10331a3a0 AnimatedImageView.Animator.loadFrame(at:) + 7316384 (AnimatedImageView.swift:558) 6 Rolls-Royce Whispers Live 0x10331a75c AnimatedImageView.Animator.updatePreloadedFrames() + 7317340 (AnimatedImageView.swift:591) 7 Rolls-Royce Whispers Live 0x102f9fbb8 thunk for @escaping @callee_guaranteed () -> () + 3668920 (:0) 8 libdispatch.dylib 0x19d1144b4 _dispatch_call_block_and_release + 32 9 libdispatch.dylib 0x19d115fdc _dispatch_client_callout + 20 10 libdispatch.dylib 0x19d11d694 _dispatch_lane_serial_drain + 672 11 libdispatch.dylib 0x19d11e1e0 _dispatch_lane_invoke + 384 12 libdispatch.dylib 0x19d128e10 _dispatch_workloop_worker_thread + 652 13 libsystem_pthread.dylib 0x1e25b8df8 _pthread_wqthread + 288 14 libsystem_pthread.dylib 0x1e25b8b98 start_wqthread + 8

    opened by Goodman333 4
  • local cache missed when reinstall and start app during the development phase

    local cache missed when reinstall and start app during the development phase

    Problem: With the issue https://github.com/onevcat/Kingfisher/issues/1825 you fixed some issues, but i I found that there is still a problem.

    The original solution does not cover the situation of reinstall the app during the development phase. Every time i reintall and start the app from Xcode, the cache is missed due to dynamic sandbox path and there are tons of duplicate thumbnails in the sandbox.

    The new cacheKey may as follow: kingfisher.local.cacheKey/~/Documents/dir/file.ext

    opened by elijahdou 2
Releases(7.4.1)
  • 7.4.1(Oct 25, 2022)

    Fix

    • A rare crash from _UIImageCGImageContent when loading GIF files on iOS 15 or later. #2004
    • Now the dSYM symbols are contained inside the xcframework bundle instead of as standalone files. #1998
    • An issue that the processor is not applied to original image data when DefaultCacheSerializer.preferCacheOriginalData is set to true. #1999
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-7.4.1.zip(27.25 MB)
  • 7.4.0(Oct 4, 2022)

    Add

    • A data property in RetrieveImageResult for reading the original data when an image loading is done. #1986
    • An async data getter in ImageDataProvider. More async methods are on the way. #1989

    Fix

    • A workaround for some cases the KFImage does not load images when embedded in the SwiftUI List on iOS 16. This only alleviates the problem when shallow embedded. For deeper nested, waiting for Apple's fix. #1988 FB11564208
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-7.4.0.zip(32.86 MB)
  • 7.3.2(Aug 10, 2022)

    Fix

    • A regression introduced by the previous version, which changed the default layout behavior when setting a placeholder. Now the KFImage should have the same layout behavior as SwiftUI's AsyncImage while loading. if no placeholder is set, it takes all the proposed size while loading. If a placeholder is set, it propose size to the placeholder and follow placeholder's layout. #1975
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-7.3.2.zip(32.75 MB)
  • 7.3.1(Jul 31, 2022)

  • 7.3.0(Jul 5, 2022)

    Add

    • Added ImageProgressive now contains a delegate onImageUpdated which will notify you everytime the progressive scanner can decode an intermediate image. You also have a chance to choose an image update strategy to respond the delegate. #1957 @jyounus
    • Now the progressive option can work with KingfisherManager. Previously it only works when set in the view extension methods under kf. #1961 @onevcat

    Fix

    • A potential crash in AnimatedImageView that releasing on another thread. #1956 @ufosky
    • A few internal clean up and removal of unused code. #1958 @idrougge

    Remove

    • With the support of ImageProgressive.onImageUpdated, the semantic of ImageProgressive.default is conflicting with the behavior. ImageProgressive.default is now marked as deprecated. To initilize a default ImageProgressive, use ImageProgressive.init() instead.
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-7.3.0.zip(32.75 MB)
  • 7.2.4(Jun 15, 2022)

  • 7.2.3(Jun 9, 2022)

  • 7.2.2(May 8, 2022)

  • 7.2.1(Apr 10, 2022)

    Fix

    • Align requestModifier parameter with AsyncImageDownloadRequestModifier to allow async request changing. #1918 @KKirsten
    • Fix an issue that data downloading task callbacks are held even when the task is removed. #1913 @onevcat
    • Give correct cache key for local urls in its conformance of Resource. #1914 @onevcat
    • Reset placeholder image when loading fails. #1925 @PJ-LT
    • Fix several typos and grammar. #1926 @johnmckerrell #1927 @SunsetWan
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-7.2.1.zip(32.75 MB)
  • 7.2.0(Feb 26, 2022)

    Add

    • An option in memory cache that allows the cached images not be purged while the app is switchted to background. #1890

    Fix

    • Now the animated images are reset when deinit. This might fix some ocasional crash when destroying the AnimatedImageView. #1886
    • Fix wrong key override when a local resource created by ImageResource's initializer. #1903
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-7.2.0.zip(35.49 MB)
  • 7.1.2(Dec 7, 2021)

    Fix

    • Lacking of diskStoreWriteOptions from KFOptionSetter. Now it supports to be set in a chainable way. #1862 @ignotusverum
    • A duplicated nested Radius type which prevents the framework being used in Playground. #1872
    • An issue that sometimes KFImage does not load images correctly when a huge amount of images are being loaded due to animation setting. #1873 @tatsuz0u
    • Remove explicit usage of @Published to allow refering KFImage even under a deploy target below iOS 13. #1875
    • Now the image cache calculats the cost animated images correctly with all frames. #1881 @pal-aspringfield
    • Remove CarPlay support when building against macCatalyst, which is not properly conditionally supported. #1876
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-7.1.2.zip(35.40 MB)
  • 7.1.1(Oct 15, 2021)

  • 7.1.0(Oct 11, 2021)

    Add

    • Extension for CarPlay support. Now you can use Kingfisher's extension image setting methods on CPListItem. #1802 from @waynehartman

    Fix

    • An Xcode issue that not recognizes iOS 15 availability checking for Apple Silicon. #1822 from @enoktate
    • Add onFailureImage modifier back to KFImage, which was unexpected removed while upgrading. #1829 from @skellock
    • Start binder loading when body is evaluated. This fixes an unwanted flickering. This also adds a protection for internal loading state. #1828 from @JetForMe and @IvanShah
    • Use color description based on CGFloat style of a color instead of a hex value to allow extended color space when setting it to a processor. #1826 from @vonox7
    • An issue that the local file provided images are cached for multiple times when an app is updated. This is due to a changing main bundle location on the disk. Now Kingfisher uses a stable version of disk URL as the default cache key. #1831 from @iaomw
    • Now KFImage's internal rendered view is wrapped by a ZStack. This prevents a lazy container from recognizing different KFImages with a same URL as the same view. #1840 from @iOSappssolutions
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-7.1.0.zip(35.39 MB)
  • 7.0.0(Sep 21, 2021)

    Add

    • Rewrite SwiftUI support based on @StateObject instead of the old @ObservedObject. It provides a stable and better data model backs the image rendering in SwiftUI. For this, Kingfisher SwiftUI supports from iOS 14 now. #1707
    • Mark ImageCache.retrieveImageInMemoryCache(forKey:options:) as open to expose a correct override entry point to outside. #1703
    • The NSTextAttachment extension method now accepts closure instead of a evaluated view. This allows delaying the passing in view to the timing which actually it is needed. #1746
    • A KFAnimatedImage type to display a GIF image in SwiftUI. #1705
    • Add a progress parameter to the KFImage's placeholder closure. This allows you create a view based on the loading progress. #1707
    • Now KFAnimatedImage also supports configure modifier so you can set options to the underhood AnimatedImageView. #1768
    • Expose AnimatedImageView fields to allow consumers to observe GIF progress. #1789 @AttilaTheFun
    • An option to pass in an write option for writing data to the disk cache. This allows writing cache in a fine-tuned way, such as .atomic or .completeFileProtection. #1793 @ignotusverum

    Fix

    • Uses UIGraphicsImageRenderer on iOS and tvOS for better image drawing. #1706
    • An issue that prevents Kingfisher compiling on mac Catalyst target in some certain of Xcode versions. #1692 @kvyatkovskys
    • The KF.retry(:_) method now accepts an optional value. It allows to reset the retry strategy by passing in a nil value. #1729
    • The placeholder view builder of KFImage now works when it gets changed instead of using its initial value forever. #1707
    • Some minor performance improvement. #1739 @fuyoufang
    • The LocalFileImageDataProvider now loads data in a background queue by default. This prevents loading performance issue when the loading is created on main thread. #1764 @ConfusedVorlon
    • Respect transition for SwiftUI view when using KFImage. #1767
    • A type of AuthenticationChallengeResponsable. Now use AuthenticationChallengeResponsible instead. #1780 @fakerlogic
    • An issue that AnimatedImageView dose not change the tintColor for templated images. #1786 @leonpesdk
    • A crash when loading a GIF image in iOS 13 and below. #1805 @leonpesdk

    Remove

    • Drop support for iOS 10/11, macOS 10.13/10.14, tvOS 10/11 and watch OS 3/4. #1802
    • The workaround of KFImage.loadImmediately is not necessary anymore due to the model switching to @StateObject. The interface is kept for backward compatibility, but it does nothing in the new version. #1707
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-7.0.0.zip(35.07 MB)
  • 7.0.0-beta.4(Sep 15, 2021)

  • 7.0.0-beta.3(Aug 29, 2021)

    Add

    • Now KFAnimatedImage also supports configure modifier so you can set options to the underhood AnimatedImageView. #1768
    • Expose AnimatedImageView fields to allow consumers to observe GIF progress. #1789

    Fix

    • Respect transition for SwiftUI view when using KFImage. #1767
    • A type of AuthenticationChallengeResponsable. Now use AuthenticationChallengeResponsible instead. #1780
    • An issue that AnimatedImageView dose not change the tintColor for templated images. #1786
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-7.0.0-beta.3.zip(34.60 MB)
  • 6.3.1(Aug 3, 2021)

  • 7.0.0-beta.2(Aug 2, 2021)

  • 7.0.0-beta.1(Jul 26, 2021)

    Add

    • Rewrite SwiftUI support based on @StateObject instead of the old @ObservedObject. It provides a stable and better data model backs the image rendering in SwiftUI. For this, Kingfisher SwiftUI supports from iOS 14 now. #1707
    • Mark ImageCache.retrieveImageInMemoryCache(forKey:options:) as open to expose a correct override entry point to outside. #1703
    • The NSTextAttachment extension method now accepts closure instead of a evaluated view. This allows delaying the passing in view to the timing which actually it is needed. #1746
    • A KFAnimatedImage type to display a GIF image in SwiftUI. #1705
    • Add a progress parameter to the KFImage's placeholder closure. This allows you create a view based on the loading progress. #1707

    Fix

    • Uses UIGraphicsImageRenderer on iOS and tvOS for better image drawing. #1706
    • An issue that prevents Kingfisher compiling on mac Catalyst target in some certain of Xcode versions. #1692
    • The KF.retry(:_) method now accepts an optional value. It allows to reset the retry strategy by passing in a nil value. #1729
    • The placeholder view builder of KFImage now works when it gets changed instead of using its initial value forever. #1707
    • Some minor performance improvement. #1739

    Remove

    • Drop support for iOS 10, macOS 10.13, tvOS 10 and watch OS 3.
    • The workaround of KFImage.loadImmediately is not necessary anymore due to the model switching to @StateObject. The interface is kept for backward compatibility, but it does nothing in the new version. #1707
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-7.0.0-beta.1.zip(34.45 MB)
  • 6.3.0(Apr 21, 2021)

    Add

    • Mark SessionDelegate as public to allow a subclass to take over the delegate methods from session tasks. #1658
    • A new imageDownloader(_:didDownload:with:) in ImageDownloaderDelegate to pass not only Data but also the whole URLResponse to delegate method. Now you can determine how to handle these data based on the received response. #1676
    • An option autoExtAfterHashedFileName in DiskStorage.Config to allow appending the file extension extracted from the cache key. #1671

    Fix

    • Now the GIF continues to play in a collection view cell with highlight support. #1685
    • Fix a crash when loading GIF files with lots of frames in AnimatedImageView. Thanks for contribution from @wow-such-amazing #1686
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-6.3.0.zip(39.61 MB)
  • 6.2.1(Mar 9, 2021)

  • 6.2.0(Mar 8, 2021)

    Add

    • The backend of Kingfisher's cache solution, DiskStorage and MemoryStorage, are now marked as public. So you can use them standalone in your project. #1649
    • An imageFrameCount property in image view extensions. It holds the frame count of an animated image if available. #1647
    • A new extraSessionDelegateHandler in ImageDownloader. Now you can receive the related session task delegate method by registering an external delegate object. #1620
    • A new method loadImmediately for KFImage to start the load manually. It is useful if you want to load the image before onAppear is called.

    Fix

    • Drop the use of @State for keeping image across View update for KFImage. This should fix some SwiftUI internal crash when setting the image in KFImage. #1642
    • The image reference in ImageBinder now is marked with weak. This helps release memory quicker in some cases. #1640
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-6.2.0.zip(39.27 MB)
  • 6.1.1(Feb 16, 2021)

    Fix

    • Remove unnecessary queue dispatch when setting image result. This prevents image flickering when some situation. #1615
    • Now the KF builder methods also accept optional URL or Source. It aligns the syntax with the normal view extension methods. #1617
    • Fix an issue that wrong hash is calculated for ImageBinder. It might cause view state lost for a KFImage. #1624
    • Now the ImageCache will disable the disk storage when there is no free space on disk when creating the cache folder, instead of just crashing it. #1628
    • A workaround for @State lost when using a view inside another container in a Lazy stack or grid. #1631
    • Performance improvement for images with an non-up orientation in Exif when displaying in KFImage. #1629
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-6.1.1.zip(38.67 MB)
  • 6.1.0(Feb 1, 2021)

    Add

    • Rewrite state management for KFImage. Now the image reloading works in a more stable way without task dispatching. #1604
    • Add fade and forceTransition modifier to KFImage to support built-in fade in effect when loading image in SwiftUI. #1604

    Fix

    • When an ImageModifier is applied, the modified image is not cached to memory cache anymore. The ImageModifier is intended to be used just before setting the image to a view and now it works as expected. #1612
    • Now SwiftUI and Combine are declared as weak link in podspec. This is a workaround for some rare case build issue. It does not affect supported deploy version of Kingfisher. #1607
    • Remove header file from podspec to allow Kingfisher built as a static framework in a Swift-ObjC mixed project. #1608
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-6.1.0.zip(38.51 MB)
  • 6.0.1(Jan 5, 2021)

  • 6.0.0(Jan 3, 2021)

    Add

    • A KF shorthand to create image setting tasks and config them. It provides a cleaner and modern way to use Kingfisher. Now, instead of using imageView.kf.setImage(with:options:), you can perform chain-able invocation with KF helpers. For example, the code below is identical. #1546

      // Old way
      imageView.kf.setImage(
        with: url,
        placeholder: localImage,
        options: [.transition(.fade(1)), .loadDiskFileSynchronously],
        progressBlock: { receivedSize, totalSize in
            print("progressBlock")
        },
        completionHandler: { result in
            print(result)
        }
      )
      
      // New way
      KF.url(url)
        .placeholder(localImage)
        .fade(duration: 1)
        .loadDiskFileSynchronously()
        .onProgress { _ in print("progressBlock") }
        .onSuccess { result in print(result) }
        .onFailure { err in print("Error: \(err)") }
        .set(to: imageView)
      
    • Similar to KF, The KFImage for SwiftUI is now having the similar chain-able syntax to setup an image task and options. This makes the KFImage APIs closer to the way how SwiftUI code is written. #1586

    • Add support for TVMonogramView on tvOS. #1571

    • Some important properties and method in AnimatedImageView.Animator are marked as public now. It provides some useful information of the decoded GIF files. #1575

    • An AsyncImageDownloadRequestModifier to support modifying the request in an asynchronous way. #1589

    • Add a .lowDataMode option to support for Low Data Mode. When the .lowDataMode option is provided with an alternative source (usually a low-resolution version of the original image), Kingfisher will respect user's Low Data Mode setting and download the alternative image instead. #1590

    Fix

    • An issue that importing AppKit wrongly in a macCatalyst build. #1547

    Remove

    • Deprecated types, methods and properties are removed. If you are still using Kingfisher.Image, Kingfisher.ImageView or Kingfisher.Button, use the equivalent KFCrossPlatform types (such as KFCrossPlatformImage, etc) instead. Please make sure you do not have any warnings before migrate to Kingfisher v6. For more about the removed deprecated things, check #1525.
    • The standalone framework target of SwiftUI support is removed. Now the SwiftUI support is a part in the main Kingfisher library. To upgrade to v6, first remove Kingfisher/SwiftUI subpod (if you are using CocoaPods) or remove the KingfisherSwiftUI target (if you are using Carthage or Swift Package Manager), then reinstall Kingfisher. #1574
    Source code(tar.gz)
    Source code(zip)
    Kingfisher-6.0.0.zip(38.14 MB)
  • 5.15.8(Nov 27, 2020)

  • 5.15.7(Oct 29, 2020)

  • 5.15.6(Oct 11, 2020)

  • 5.15.5(Sep 29, 2020)

Owner
Wei Wang
Developer, creator, proud father.
Wei Wang
🍁🥓 Lightweight and fast Swift library for image downloading, caching and transformations

MapleBacon Introduction MapleBacon is a lightweight and fast Swift library for downloading and caching images. Example The folder Example contains a s

Jan Gorman 335 Nov 1, 2022
An extremely high-performance, lightweight, and energy-efficient pure Swift async web image loader with memory and disk caching for iOS and  Watch.

KFSwiftImageLoader KFSwiftImageLoader is an extremely high-performance, lightweight, and energy-efficient pure Swift async web image loader with memor

Kiavash Faisali 343 Oct 29, 2022
A Swift/SwiftUI utility for caching and displaying images in SwiftUI Views

A Swift/SwiftUI utility for caching and displaying images asynchronously. Built with Swift 5.5 and works with async/await.

王雪铮 Xuezheng Wang 1 May 5, 2022
Advanced framework for loading, caching, processing, displaying and preheating images.

Advanced framework for loading, caching, processing, displaying and preheating images. This framework is no longer maintained. Programming in Swift? C

Alexander Grebenyuk 1.2k Dec 23, 2022
AYImageKit is a Swift Library for Async Image Downloading, Show Name's Initials and Can View image in Separate Screen.

AYImageKit AYImageKit is a Swift Library for Async Image Downloading. Features Async Image Downloading. Can Show Text Initials. Can have Custom Styles

Adnan Yousaf 11 Jan 10, 2022
Media view which subclasses UIImageView, and can display & load images, videos, GIFs, and audio and from the web, and has functionality to minimize from fullscreen, as well as show GIF previews for videos.

I've built out the Swift version of this library! Screenshots Description ABMediaView can display images, videos, as well as now GIFs and Audio! It su

Andrew Boryk 80 Dec 20, 2022
Twitter Image Pipeline is a robust and performant image loading and caching framework for iOS clients

Twitter Image Pipeline (a.k.a. TIP) Background The Twitter Image Pipeline is a streamlined framework for fetching and storing images in an application

Twitter 1.8k Dec 17, 2022
Focus on avatar caching.

Navi Navi is designed for avatar caching, with style. The name of Navi from movie Avatar. Requirements Swift 3.1, iOS 8.0 Swift 2.3, use version 0.5.0

null 114 Jun 30, 2022
A Swift library for parsing and drawing SVG images to CoreGraphics contexts.

SwiftDraw A Swift library for parsing and drawing SVG images to CoreGraphics contexts. SwiftDraw can also convert an SVG into Swift source code. Usage

Simon Whitty 119 Jan 3, 2023
Style Art library process images using COREML with a set of pre trained machine learning models and convert them to Art style.

StyleArt Style Art is a library that process images using COREML with a set of pre trained machine learning models and convert them to Art style. Prev

iLeaf Solutions Pvt. Ltd. 222 Dec 17, 2022
iOS library for quickly displaying images while scrolling

Fast Image Cache is an efficient, persistent, and—above all—fast way to store and retrieve images in your iOS application. Part of any good iOS applic

Path Mobile Inc Pte. Ltd. 8.2k Jan 9, 2023
ThreeDCardView - Library that you can see images with a 3D card 🌌

?? ThreeDCardView Usage First you have to import 'ThreeDCardView' import 'ThreeDCardView' Create ThreeDCardView and set the frame let threeDCardView:T

Fomagran 4 Jul 9, 2022
React-native-image-generator - Library to generate images from layers

react-native-image-generator Library for generate images from other images Insta

Evgeny Usov 13 Nov 16, 2022
FlaneurImagePicker is an iOS image picker that allows users to pick images from different sources (ex: user's library, user's camera, Instagram...). It's highly customizable.

FlaneurImagePicker is a highly customizable iOS image picker that allows users to pick images from different sources (ex: device's library, device's c

FlaneurApp 17 Feb 2, 2020
AsyncImage before iOS 15. Lightweight, pure SwiftUI Image view, that displays an image downloaded from URL, with auxiliary views and local cache.

URLImage URLImage is a SwiftUI view that displays an image downloaded from provided URL. URLImage manages downloading remote image and caching it loca

Dmytro Anokhin 1k Jan 4, 2023
APNGKit is a high performance framework for loading and displaying APNG images in iOS and macOS.

APNGKit is a high performance framework for loading and displaying APNG images in iOS and macOS. It's built on top of a modified version of libpng wit

Wei Wang 2.1k Dec 30, 2022
Image viewer (or Lightbox) with support for local and remote videos and images

Table of Contents Features Focus Browse Rotation Zoom tvOS Setup Installation License Author Features Focus Select an image to enter into lightbox mod

Nes 534 Jan 3, 2023
Jogendra 113 Nov 28, 2022
A pure Swift high-performance asynchronous image loading framework. SwiftUI supported.

Longinus Longinus is a pure-Swift high-performance asynchronous web image loading,caching,editing framework. It was learned from Objective-C web image

Qitao Yang 290 Dec 17, 2022