123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- //
- // ImageDataProvider.swift
- // Kingfisher
- //
- // Created by onevcat on 2018/11/13.
- //
- // Copyright (c) 2019 Wei Wang <onevcat@gmail.com>
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- import Foundation
- /// Represents a data provider to provide image data to Kingfisher when setting with
- /// `Source.provider` source. Compared to `Source.network` member, it gives a chance
- /// to load some image data in your own way, as long as you can provide the data
- /// representation for the image.
- public protocol ImageDataProvider {
-
- /// The key used in cache.
- var cacheKey: String { get }
-
- /// Provides the data which represents image. Kingfisher uses the data you pass in the
- /// handler to process images and caches it for later use.
- ///
- /// - Parameter handler: The handler you should call when you prepared your data.
- /// If the data is loaded successfully, call the handler with
- /// a `.success` with the data associated. Otherwise, call it
- /// with a `.failure` and pass the error.
- ///
- /// - Note:
- /// If the `handler` is called with a `.failure` with error, a `dataProviderError` of
- /// `ImageSettingErrorReason` will be finally thrown out to you as the `KingfisherError`
- /// from the framework.
- func data(handler: @escaping (Result<Data, Error>) -> Void)
- /// The content URL represents this provider, if exists.
- var contentURL: URL? { get }
- }
- public extension ImageDataProvider {
- var contentURL: URL? { return nil }
- func convertToSource() -> Source {
- .provider(self)
- }
- }
- /// Represents an image data provider for loading from a local file URL on disk.
- /// Uses this type for adding a disk image to Kingfisher. Compared to loading it
- /// directly, you can get benefit of using Kingfisher's extension methods, as well
- /// as applying `ImageProcessor`s and storing the image to `ImageCache` of Kingfisher.
- public struct LocalFileImageDataProvider: ImageDataProvider {
- // MARK: Public Properties
- /// The file URL from which the image be loaded.
- public let fileURL: URL
- private let loadingQueue: ExecutionQueue
- // MARK: Initializers
- /// Creates an image data provider by supplying the target local file URL.
- ///
- /// - Parameters:
- /// - 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.
- /// - 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.localFileCacheKey
- self.loadingQueue = loadingQueue
- }
- // MARK: Protocol Conforming
- /// The key used in cache.
- public var cacheKey: String
- public func data(handler:@escaping (Result<Data, Error>) -> Void) {
- loadingQueue.execute {
- handler(Result(catching: { try Data(contentsOf: fileURL) }))
- }
- }
-
- #if swift(>=5.5)
- #if canImport(_Concurrency)
- @available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
- public var data: Data {
- get async throws {
- try await withCheckedThrowingContinuation { continuation in
- loadingQueue.execute {
- do {
- let data = try Data(contentsOf: fileURL)
- continuation.resume(returning: data)
- } catch {
- continuation.resume(throwing: error)
- }
- }
- }
- }
- }
- #endif
- #endif
- /// The URL of the local file on the disk.
- public var contentURL: URL? {
- return fileURL
- }
- }
- /// Represents an image data provider for loading image from a given Base64 encoded string.
- public struct Base64ImageDataProvider: ImageDataProvider {
- // MARK: Public Properties
- /// The encoded Base64 string for the image.
- public let base64String: String
- // MARK: Initializers
- /// Creates an image data provider by supplying the Base64 encoded string.
- ///
- /// - Parameters:
- /// - base64String: The Base64 encoded string for an image.
- /// - cacheKey: The key is used for caching the image data. You need a different key for any different image.
- public init(base64String: String, cacheKey: String) {
- self.base64String = base64String
- self.cacheKey = cacheKey
- }
- // MARK: Protocol Conforming
- /// The key used in cache.
- public var cacheKey: String
- public func data(handler: (Result<Data, Error>) -> Void) {
- let data = Data(base64Encoded: base64String)!
- handler(.success(data))
- }
- }
- /// Represents an image data provider for a raw data object.
- public struct RawImageDataProvider: ImageDataProvider {
- // MARK: Public Properties
- /// The raw data object to provide to Kingfisher image loader.
- public let data: Data
- // MARK: Initializers
- /// Creates an image data provider by the given raw `data` value and a `cacheKey` be used in Kingfisher cache.
- ///
- /// - Parameters:
- /// - data: The raw data reprensents an image.
- /// - cacheKey: The key is used for caching the image data. You need a different key for any different image.
- public init(data: Data, cacheKey: String) {
- self.data = data
- self.cacheKey = cacheKey
- }
- // MARK: Protocol Conforming
-
- /// The key used in cache.
- public var cacheKey: String
- public func data(handler: @escaping (Result<Data, Error>) -> Void) {
- handler(.success(data))
- }
- }
|