update
This commit is contained in:
148
Pods/Kingfisher/Sources/General/ImageSource/AVAssetImageDataProvider.swift
generated
Normal file
148
Pods/Kingfisher/Sources/General/ImageSource/AVAssetImageDataProvider.swift
generated
Normal file
@@ -0,0 +1,148 @@
|
||||
//
|
||||
// AVAssetImageDataProvider.swift
|
||||
// Kingfisher
|
||||
//
|
||||
// Created by onevcat on 2020/08/09.
|
||||
//
|
||||
// Copyright (c) 2020 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.
|
||||
|
||||
#if !os(watchOS)
|
||||
|
||||
import Foundation
|
||||
import AVKit
|
||||
|
||||
#if canImport(MobileCoreServices)
|
||||
import MobileCoreServices
|
||||
#else
|
||||
import CoreServices
|
||||
#endif
|
||||
|
||||
/// A data provider to provide thumbnail data from a given AVKit asset.
|
||||
public struct AVAssetImageDataProvider: ImageDataProvider {
|
||||
|
||||
/// The possible error might be caused by the `AVAssetImageDataProvider`.
|
||||
/// - userCancelled: The data provider process is cancelled.
|
||||
/// - invalidImage: The retrieved image is invalid.
|
||||
public enum AVAssetImageDataProviderError: Error {
|
||||
case userCancelled
|
||||
case invalidImage(_ image: CGImage?)
|
||||
}
|
||||
|
||||
/// The asset image generator bound to `self`.
|
||||
public let assetImageGenerator: AVAssetImageGenerator
|
||||
|
||||
/// The time at which the image should be generate in the asset.
|
||||
public let time: CMTime
|
||||
|
||||
private var internalKey: String {
|
||||
return (assetImageGenerator.asset as? AVURLAsset)?.url.absoluteString ?? UUID().uuidString
|
||||
}
|
||||
|
||||
/// The cache key used by `self`.
|
||||
public var cacheKey: String {
|
||||
return "\(internalKey)_\(time.seconds)"
|
||||
}
|
||||
|
||||
/// Creates an asset image data provider.
|
||||
/// - Parameters:
|
||||
/// - assetImageGenerator: The asset image generator controls data providing behaviors.
|
||||
/// - time: At which time in the asset the image should be generated.
|
||||
public init(assetImageGenerator: AVAssetImageGenerator, time: CMTime) {
|
||||
self.assetImageGenerator = assetImageGenerator
|
||||
self.time = time
|
||||
}
|
||||
|
||||
/// Creates an asset image data provider.
|
||||
/// - Parameters:
|
||||
/// - assetURL: The URL of asset for providing image data.
|
||||
/// - time: At which time in the asset the image should be generated.
|
||||
///
|
||||
/// This method uses `assetURL` to create an `AVAssetImageGenerator` object and calls
|
||||
/// the `init(assetImageGenerator:time:)` initializer.
|
||||
///
|
||||
public init(assetURL: URL, time: CMTime) {
|
||||
let asset = AVAsset(url: assetURL)
|
||||
let generator = AVAssetImageGenerator(asset: asset)
|
||||
generator.appliesPreferredTrackTransform = true
|
||||
self.init(assetImageGenerator: generator, time: time)
|
||||
}
|
||||
|
||||
/// Creates an asset image data provider.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - assetURL: The URL of asset for providing image data.
|
||||
/// - seconds: At which time in seconds in the asset the image should be generated.
|
||||
///
|
||||
/// This method uses `assetURL` to create an `AVAssetImageGenerator` object, uses `seconds` to create a `CMTime`,
|
||||
/// and calls the `init(assetImageGenerator:time:)` initializer.
|
||||
///
|
||||
public init(assetURL: URL, seconds: TimeInterval) {
|
||||
let time = CMTime(seconds: seconds, preferredTimescale: 600)
|
||||
self.init(assetURL: assetURL, time: time)
|
||||
}
|
||||
|
||||
public func data(handler: @escaping (Result<Data, Error>) -> Void) {
|
||||
assetImageGenerator.generateCGImagesAsynchronously(forTimes: [NSValue(time: time)]) {
|
||||
(requestedTime, image, imageTime, result, error) in
|
||||
if let error = error {
|
||||
handler(.failure(error))
|
||||
return
|
||||
}
|
||||
|
||||
if result == .cancelled {
|
||||
handler(.failure(AVAssetImageDataProviderError.userCancelled))
|
||||
return
|
||||
}
|
||||
|
||||
guard let cgImage = image, let data = cgImage.jpegData else {
|
||||
handler(.failure(AVAssetImageDataProviderError.invalidImage(image)))
|
||||
return
|
||||
}
|
||||
|
||||
handler(.success(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension CGImage {
|
||||
var jpegData: Data? {
|
||||
guard let mutableData = CFDataCreateMutable(nil, 0) else {
|
||||
return nil
|
||||
}
|
||||
#if os(xrOS)
|
||||
guard let destination = CGImageDestinationCreateWithData(
|
||||
mutableData, UTType.jpeg.identifier as CFString , 1, nil
|
||||
) else {
|
||||
return nil
|
||||
}
|
||||
#else
|
||||
guard let destination = CGImageDestinationCreateWithData(mutableData, kUTTypeJPEG, 1, nil) else {
|
||||
return nil
|
||||
}
|
||||
#endif
|
||||
|
||||
CGImageDestinationAddImage(destination, self, nil)
|
||||
guard CGImageDestinationFinalize(destination) else { return nil }
|
||||
return mutableData as Data
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
190
Pods/Kingfisher/Sources/General/ImageSource/ImageDataProvider.swift
generated
Normal file
190
Pods/Kingfisher/Sources/General/ImageSource/ImageDataProvider.swift
generated
Normal file
@@ -0,0 +1,190 @@
|
||||
//
|
||||
// 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))
|
||||
}
|
||||
}
|
||||
121
Pods/Kingfisher/Sources/General/ImageSource/Resource.swift
generated
Normal file
121
Pods/Kingfisher/Sources/General/ImageSource/Resource.swift
generated
Normal file
@@ -0,0 +1,121 @@
|
||||
//
|
||||
// Resource.swift
|
||||
// Kingfisher
|
||||
//
|
||||
// Created by Wei Wang on 15/4/6.
|
||||
//
|
||||
// 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 an image resource at a certain url and a given cache key.
|
||||
/// Kingfisher will use a `Resource` to download a resource from network and cache it with the cache key when
|
||||
/// using `Source.network` as its image setting source.
|
||||
public protocol Resource {
|
||||
|
||||
/// The key used in cache.
|
||||
var cacheKey: String { get }
|
||||
|
||||
/// The target image URL.
|
||||
var downloadURL: URL { get }
|
||||
}
|
||||
|
||||
extension Resource {
|
||||
|
||||
/// Converts `self` to a valid `Source` based on its `downloadURL` scheme. A `.provider` with
|
||||
/// `LocalFileImageDataProvider` associated will be returned if the URL points to a local file. Otherwise,
|
||||
/// `.network` is returned.
|
||||
public func convertToSource(overrideCacheKey: String? = nil) -> Source {
|
||||
let key = overrideCacheKey ?? cacheKey
|
||||
return downloadURL.isFileURL ?
|
||||
.provider(LocalFileImageDataProvider(fileURL: downloadURL, cacheKey: key)) :
|
||||
.network(KF.ImageResource(downloadURL: downloadURL, cacheKey: key))
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "This type conflicts with `GeneratedAssetSymbols.ImageResource` in Swift 5.9. Renamed to avoid issues in the future.", renamed: "KF.ImageResource")
|
||||
public typealias ImageResource = KF.ImageResource
|
||||
|
||||
|
||||
extension KF {
|
||||
/// ImageResource is a simple combination of `downloadURL` and `cacheKey`.
|
||||
/// When passed to image view set methods, Kingfisher will try to download the target
|
||||
/// image from the `downloadURL`, and then store it with the `cacheKey` as the key in cache.
|
||||
public struct ImageResource: Resource {
|
||||
|
||||
// MARK: - Initializers
|
||||
|
||||
/// Creates an image resource.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - downloadURL: The target image URL from where the image can be downloaded.
|
||||
/// - cacheKey: The cache key. If `nil`, Kingfisher will use the `absoluteString` of `downloadURL` as the key.
|
||||
/// Default is `nil`.
|
||||
public init(downloadURL: URL, cacheKey: String? = nil) {
|
||||
self.downloadURL = downloadURL
|
||||
self.cacheKey = cacheKey ?? downloadURL.cacheKey
|
||||
}
|
||||
|
||||
// MARK: Protocol Conforming
|
||||
|
||||
/// The key used in cache.
|
||||
public let cacheKey: String
|
||||
|
||||
/// The target image URL.
|
||||
public let downloadURL: URL
|
||||
}
|
||||
}
|
||||
|
||||
/// URL conforms to `Resource` in Kingfisher.
|
||||
/// The `absoluteString` of this URL is used as `cacheKey`. And the URL itself will be used as `downloadURL`.
|
||||
/// If you need customize the url and/or cache key, use `ImageResource` instead.
|
||||
extension URL: Resource {
|
||||
public var cacheKey: String { return isFileURL ? localFileCacheKey : absoluteString }
|
||||
public var downloadURL: URL { return self }
|
||||
}
|
||||
|
||||
extension URL {
|
||||
static let localFileCacheKeyPrefix = "kingfisher.local.cacheKey"
|
||||
|
||||
// The special version of cache key for a local file on disk. Every time the app is reinstalled on the disk,
|
||||
// the system assigns a new container folder to hold the .app (and the extensions, .appex) folder. So the URL for
|
||||
// the same image in bundle might be different.
|
||||
//
|
||||
// This getter only uses the fixed part in the URL (until the bundle name folder) to provide a stable cache key
|
||||
// for the image under the same path inside the bundle.
|
||||
//
|
||||
// See #1825 (https://github.com/onevcat/Kingfisher/issues/1825)
|
||||
var localFileCacheKey: String {
|
||||
var validComponents: [String] = []
|
||||
for part in pathComponents.reversed() {
|
||||
validComponents.append(part)
|
||||
if part.hasSuffix(".app") || part.hasSuffix(".appex") {
|
||||
break
|
||||
}
|
||||
}
|
||||
let fixedPath = "\(Self.localFileCacheKeyPrefix)/\(validComponents.reversed().joined(separator: "/"))"
|
||||
if let q = query {
|
||||
return "\(fixedPath)?\(q)"
|
||||
} else {
|
||||
return fixedPath
|
||||
}
|
||||
}
|
||||
}
|
||||
116
Pods/Kingfisher/Sources/General/ImageSource/Source.swift
generated
Normal file
116
Pods/Kingfisher/Sources/General/ImageSource/Source.swift
generated
Normal file
@@ -0,0 +1,116 @@
|
||||
//
|
||||
// Source.swift
|
||||
// Kingfisher
|
||||
//
|
||||
// Created by onevcat on 2018/11/17.
|
||||
//
|
||||
// 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 an image setting source for Kingfisher methods.
|
||||
///
|
||||
/// A `Source` value indicates the way how the target image can be retrieved and cached.
|
||||
///
|
||||
/// - network: The target image should be got from network remotely. The associated `Resource`
|
||||
/// value defines detail information like image URL and cache key.
|
||||
/// - provider: The target image should be provided in a data format. Normally, it can be an image
|
||||
/// from local storage or in any other encoding format (like Base64).
|
||||
public enum Source {
|
||||
|
||||
/// Represents the source task identifier when setting an image to a view with extension methods.
|
||||
public enum Identifier {
|
||||
|
||||
/// The underlying value type of source identifier.
|
||||
public typealias Value = UInt
|
||||
static private(set) var current: Value = 0
|
||||
static func next() -> Value {
|
||||
current += 1
|
||||
return current
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Member Cases
|
||||
|
||||
/// The target image should be got from network remotely. The associated `Resource`
|
||||
/// value defines detail information like image URL and cache key.
|
||||
case network(Resource)
|
||||
|
||||
/// The target image should be provided in a data format. Normally, it can be an image
|
||||
/// from local storage or in any other encoding format (like Base64).
|
||||
case provider(ImageDataProvider)
|
||||
|
||||
// MARK: Getting Properties
|
||||
|
||||
/// The cache key defined for this source value.
|
||||
public var cacheKey: String {
|
||||
switch self {
|
||||
case .network(let resource): return resource.cacheKey
|
||||
case .provider(let provider): return provider.cacheKey
|
||||
}
|
||||
}
|
||||
|
||||
/// The URL defined for this source value.
|
||||
///
|
||||
/// For a `.network` source, it is the `downloadURL` of associated `Resource` instance.
|
||||
/// For a `.provider` value, it is always `nil`.
|
||||
public var url: URL? {
|
||||
switch self {
|
||||
case .network(let resource): return resource.downloadURL
|
||||
case .provider(let provider): return provider.contentURL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Source: Hashable {
|
||||
public static func == (lhs: Source, rhs: Source) -> Bool {
|
||||
switch (lhs, rhs) {
|
||||
case (.network(let r1), .network(let r2)):
|
||||
return r1.cacheKey == r2.cacheKey && r1.downloadURL == r2.downloadURL
|
||||
case (.provider(let p1), .provider(let p2)):
|
||||
return p1.cacheKey == p2.cacheKey && p1.contentURL == p2.contentURL
|
||||
case (.provider(_), .network(_)):
|
||||
return false
|
||||
case (.network(_), .provider(_)):
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
switch self {
|
||||
case .network(let r):
|
||||
hasher.combine(r.cacheKey)
|
||||
hasher.combine(r.downloadURL)
|
||||
case .provider(let p):
|
||||
hasher.combine(p.cacheKey)
|
||||
hasher.combine(p.contentURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Source {
|
||||
var asResource: Resource? {
|
||||
guard case .network(let resource) = self else {
|
||||
return nil
|
||||
}
|
||||
return resource
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user