Skip to content

Commit

Permalink
Add an option for local file loading
Browse files Browse the repository at this point in the history
  • Loading branch information
onevcat committed Aug 2, 2021
1 parent 5632aca commit 70ef0ba
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 2 deletions.
12 changes: 10 additions & 2 deletions Sources/General/ImageSource/ImageDataProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public struct LocalFileImageDataProvider: ImageDataProvider {

/// The file URL from which the image be loaded.
public let fileURL: URL
private let loadingQueue: ExecutionQueue

// MARK: Initializers

Expand All @@ -79,9 +80,16 @@ public struct LocalFileImageDataProvider: ImageDataProvider {
/// - fileURL: The file URL from which the image be loaded.
/// - cacheKey: The key is used for caching the image data. By default,
/// the `absoluteString` of `fileURL` is used.
public init(fileURL: URL, cacheKey: String? = nil) {
/// - loadingQueue: The queue where the file loading should happen. By default, the dispatch queue of
/// `.global(qos: .userInitiated)` will be used.
public init(
fileURL: URL,
cacheKey: String? = nil,
loadingQueue: ExecutionQueue = .dispatch(DispatchQueue.global(qos: .userInitiated))
) {
self.fileURL = fileURL
self.cacheKey = cacheKey ?? fileURL.absoluteString
self.loadingQueue = loadingQueue
}

// MARK: Protocol Conforming
Expand All @@ -90,7 +98,7 @@ public struct LocalFileImageDataProvider: ImageDataProvider {
public var cacheKey: String

public func data(handler:@escaping (Result<Data, Error>) -> Void) {
DispatchQueue.global(qos: .userInitiated).async {
loadingQueue.execute {
handler(Result(catching: { try Data(contentsOf: fileURL) }))
}
}
Expand Down
2 changes: 2 additions & 0 deletions Sources/Utility/CallbackQueue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

import Foundation

public typealias ExecutionQueue = CallbackQueue

/// Represents callback queue behaviors when an calling of closure be dispatched.
///
/// - asyncMain: Dispatch the calling to `DispatchQueue.main` with an `async` behavior.
Expand Down
20 changes: 20 additions & 0 deletions Tests/KingfisherTests/ImageDataProviderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,26 @@ class ImageDataProviderTests: XCTestCase {
waitForExpectations(timeout: 1, handler: nil)
}

func testLocalFileImageDataProviderMainQueue() {
let fm = FileManager.default
let document = try! fm.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let fileURL = document.appendingPathComponent("test")
try! testImageData.write(to: fileURL)

let provider = LocalFileImageDataProvider(fileURL: fileURL, loadingQueue: .mainCurrentOrAsync)
XCTAssertEqual(provider.cacheKey, fileURL.absoluteString)
XCTAssertEqual(provider.fileURL, fileURL)

var called = false
provider.data { result in
XCTAssertEqual(result.value, testImageData)
try! fm.removeItem(at: fileURL)
called = true
}

XCTAssertTrue(called)
}

func testBase64ImageDataProvider() {
let base64String = testImageData.base64EncodedString()
let provider = Base64ImageDataProvider(base64String: base64String, cacheKey: "123")
Expand Down

0 comments on commit 70ef0ba

Please sign in to comment.