Skip to content

Nuke 13 – Swift 6 #802

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 227 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
227 commits
Select commit Hold shift + click to select a range
cc2789f
Add ImagePipelineActor
kean Jul 28, 2024
ed5ae0b
Remove deprecated APIs from ImagePipeleine
kean Jul 28, 2024
d122647
Remove AsyncImageTask
kean Jul 28, 2024
3ce7e92
Remove ImagePipeline.Configuration.callbackQueue parameter
kean Jul 28, 2024
8422630
Add a note about ImagePipeline.Configuration
kean Jul 28, 2024
1a469cb
Remove onTaskCreated tests – this situation was eliminated
kean Jul 28, 2024
e793012
Safer testLoadDataDataLoaded
kean Jul 28, 2024
b72c56b
Add ImagePublisher back
kean Jul 28, 2024
8c6f7f2
Use Atomic for ImageTaskNonisolatedState
kean Jul 28, 2024
786bebc
Cleanup
kean Jul 28, 2024
6168ab1
Remove deprecated APIs
kean Jul 28, 2024
4b2f473
Update unit tests
kean Aug 3, 2024
287b1db
Rename Atomic to Mutex
kean Aug 3, 2024
f07a2e1
Make some of ImageTask properties nonislated
kean Aug 3, 2024
5a0c759
Make ImageTask/continuation private
kean Aug 3, 2024
8983d5d
Make ImageTask.State explicitly Sendable
kean Aug 3, 2024
796f5c6
Rework isolation in ImageTask
kean Aug 17, 2024
039b163
Remove nonisolated ImageTask.state
kean Aug 17, 2024
109621c
Remove ImageTaskExecutionContext
kean Aug 17, 2024
00d6f18
Cleanup ImageTask
kean Aug 17, 2024
a774d51
Revert imageTaskCreated removal
kean Aug 17, 2024
4b21e2e
Revert imageTaskCreated removal
kean Aug 17, 2024
c56dbae
Remove soft-deprecated APIs from ImagePipeline.Delegate
kean Aug 17, 2024
45c7fd6
Rename ImagePipelineDelegate to ImagePipeline.Delegate
kean Aug 17, 2024
a2bd2f7
Move Combine extensions
kean Aug 17, 2024
351be3a
Remove DataPublisher support
kean Aug 17, 2024
836cf75
Update warnings
kean Aug 17, 2024
f742a0c
Update DataLoading protocol to use Swift Concurrency
kean Aug 17, 2024
f4a4b74
Update ResumableDataStore to use generic namespace ID
kean Aug 17, 2024
a43d235
Revert DataLoader to use URLRequest as parameter for now
kean Aug 17, 2024
8befa46
Reimplement data loading with closure
kean Aug 18, 2024
2306a4e
Update ImagePrefetcher to use Swift Concurrency (partially)
kean Aug 18, 2024
83dc0eb
Update ImagePipeline callbacks to be main actor isolated
kean Aug 18, 2024
b8d190d
Remove UncheckedSendableBox
kean Aug 18, 2024
d650baf
Remove now redundant _loadData method
kean Aug 18, 2024
70b92f0
Fix a concurrency warning in RateLimiter
kean Aug 18, 2024
123586a
Fix RateLimiter tests
kean Aug 18, 2024
38dc11c
Remove one of the loadData variant
kean Aug 18, 2024
2e0e6b6
Rename makeImageTask
kean Aug 18, 2024
1b7547a
Rename imageTaskUpdatePriorityCalled
kean Aug 18, 2024
7e34b50
Soft-deprecate closure-based APIs
kean Aug 18, 2024
97c3ccd
Remove warning in isResumableDataEnabled
kean Aug 18, 2024
cd82f34
Remove Sendable conformance from AsyncPipelineTask
kean Aug 18, 2024
868da19
Remove unused isResumableDataEnabled
kean Aug 18, 2024
84400f0
Remove redundant @unchecked from ImageProcessingOptions.Border
kean Aug 18, 2024
0e5273b
Remove redundant @unchecked Sendable
kean Aug 18, 2024
8ab81b7
Update ImagePrefetcher
kean Oct 26, 2024
1c495bd
Update TaskTests
kean Oct 26, 2024
6df73d2
Update testCancelAsyncImageTask
kean Oct 26, 2024
6dadf6e
Simplify didComplete
kean Oct 26, 2024
3fbd5b0
Deprecate FetchImage.load with Publisher
kean Oct 26, 2024
2086dc6
Update tests
kean Oct 26, 2024
bf79725
Fix an issue with state being writable
kean Oct 27, 2024
bca4607
Sync ImageTask on ImagePipelineActor
kean Oct 27, 2024
b620989
Update how withLock is used
kean Oct 27, 2024
81e8412
ImageRequest.Container is no longer Sendable
kean Oct 27, 2024
072f732
Update ci.yml
kean Oct 27, 2024
9c025c6
Update performance tests
kean Oct 27, 2024
a4413f6
Bump macOS deployment target to macOS 11
kean Oct 27, 2024
de39ec1
Increase deployment targets
kean Oct 27, 2024
4878846
Remove @unchecked from ImagePipeline.Error Sendable conformance
kean Oct 27, 2024
2896769
Fix SwiftPM build on macOS
kean Nov 17, 2024
7e684d1
Add retroactive conformances in test targets
kean Nov 17, 2024
ef82a7d
Enable Swift 6
kean Nov 17, 2024
bec2101
Update RateLimiterTests to swift-testing
kean Nov 17, 2024
26487ea
Use expect instead of require
kean Nov 17, 2024
9f7eb9c
Enable complete concurrency checking in unit tests
kean Nov 17, 2024
13d363e
Update TaskTests
kean Nov 17, 2024
52771a0
Update ImageRequestTests
kean Nov 17, 2024
4e0bca9
Update ImageCacheTests
kean Nov 17, 2024
b62cc43
Update ImageDecoderTests
kean Nov 17, 2024
f9438e3
Update ImageDecoderRegistryTests
kean Nov 17, 2024
056d66f
Update ImageEncoderTests
kean Nov 17, 2024
5abfe24
Update some of the ImagePrefetcher tests
kean Jan 1, 2025
dfd86bd
Update copyright
kean Jan 1, 2025
890cd3b
Fix releaes notes
kean Jan 1, 2025
c364bc0
Add initial TaskQueue implementation
kean Jan 2, 2025
03c2fe2
Skip pendingTasks when possible
kean Jan 2, 2025
8e5d1ac
Make ScheduledTask private
kean Jan 2, 2025
ddcce7b
Fix formatting
kean Jan 2, 2025
f3cda93
Add cancelInFlightWork
kean Jan 2, 2025
caf48a8
Add support for cancelling pending tasks
kean Jan 2, 2025
59d43d7
Rename WorkQueue
kean Jan 2, 2025
1eb3e9f
Move WorkQueue to Internal
kean Jan 2, 2025
2004bfc
Add basic support for priorities in WorkQueue
kean Jan 2, 2025
9bed910
Add support for dynamically changing priority of work items
kean Jan 4, 2025
c9a4945
Add a convenience API for enqueuing work
kean Jan 4, 2025
c588953
Eagerly pop cancelled items from the queue
kean Jan 4, 2025
2b966b2
Integrate WorkQueue in ImagePrefetcher
kean Jan 4, 2025
b130abf
Add initial AsyncExpectation implementation
kean Jan 4, 2025
95671fc
Rewrite AsyncExpectation using Mutex
kean Jan 4, 2025
e646495
Fix WorkQueue not retaining WorkItem
kean Jan 4, 2025
67033d2
Update cancelInFlightWork to not require Work.Item init
kean Jan 4, 2025
d6db94f
Update WorkQueue API to not expose WorkItem int
kean Jan 4, 2025
cfd4014
Ensure retaing WorkQueue.Item never leads to retain cycles
kean Jan 4, 2025
34b3604
Add support for pausing the prefetcher
kean Jan 4, 2025
0483c5a
Fix an issue with ImagePrefetcher not deallocating in case there are …
kean Jan 5, 2025
b255543
Replace dataLoadingQueue with WorkQueue
kean Jan 5, 2025
126f6f9
Remove async Operation
kean Jan 5, 2025
82caa34
Remove obsolete TODO from ImagePrefetcher
kean Jan 5, 2025
1863cbd
Update some of the priority tests
kean Jan 14, 2025
603df05
Update DataCacheTests
kean Mar 30, 2025
a1b4fef
Update ResumableDataTests
kean Mar 30, 2025
2df8dac
Update LinkedListTests
kean Mar 30, 2025
cb6544d
Remove DeprecationTests
kean Mar 30, 2025
855b361
Update Sources to synchronized folders
kean Mar 30, 2025
f164752
Move Mocks to a synchronized folder
kean Mar 30, 2025
0929603
Move Extensions to Helpers
kean Mar 30, 2025
a22501b
Add Resources as a synchronized folder
kean Mar 30, 2025
3a411eb
Add other tests as synchronized folders
kean Mar 30, 2025
f026ead
Update Host
kean Mar 30, 2025
fbf8a87
Add Documentation as a synchronized folder
kean Mar 30, 2025
3421286
Async/Await tests are now standard
kean Mar 30, 2025
f1f2612
Update ImagePipelineTests
kean Mar 30, 2025
4f9dd09
Update minimum required versions
kean Mar 30, 2025
6e99e98
Require Swift 6
kean Mar 30, 2025
0d2f56f
Remove redundant #available checks
kean Mar 30, 2025
b4b4505
Update AsyncExpectation to support storing values
kean Mar 30, 2025
e51ff7c
Update WorkQueue.Item naming
kean Mar 30, 2025
c936eb1
Implement ImagePipelineTests.updatePriority
kean Mar 30, 2025
71c229c
Fix defaultPrioritySetToLow
kean Mar 31, 2025
e118453
Update ImagePipelineCacheTests
kean Mar 31, 2025
6d4fa16
Update imageDecodingQueue to be a WorkQueue
kean Mar 31, 2025
82c21c4
Update ImageProcessingQueue to use WorkQueue
kean Mar 31, 2025
6c2ce5f
Remove remaining OperationQueue usagse
kean Mar 31, 2025
0a86fdc
Update tests
kean Mar 31, 2025
d353726
Add dataLoadingOperationCancelled
kean Mar 31, 2025
fbeaba9
Add decodingOperationCancelled
kean Mar 31, 2025
1a233aa
Add decodingOperationCancelled
kean Mar 31, 2025
890862e
Add processingOperationCancelled
kean Mar 31, 2025
71fd921
Remove redundant @available
kean Mar 31, 2025
aa02047
Add DecompressionTests
kean Mar 31, 2025
0fd56ad
Add CacheKey tests
kean Mar 31, 2025
07e1fe1
Add pipeline invalidation tests
kean Mar 31, 2025
8b64acc
Add Error Handling tests
kean Mar 31, 2025
45b6521
Add remaining ImagePipelineTests
kean Mar 31, 2025
b04b6e9
Update ImagePipelineProcessingDeduplicationTests
kean Apr 5, 2025
46371cc
Update deduplicationGivenSameURLDifferentSameProcessors
kean Apr 6, 2025
2c294d3
Add TODO:
kean Apr 6, 2025
129104d
Update more ImagePipelineCoalescingTests
kean Apr 6, 2025
d8c3ef7
Start ImageTask in .suspended state
kean Apr 6, 2025
058af88
Move ImageTask extensions
kean Apr 6, 2025
821a309
Update ImageTask documentation
kean Apr 6, 2025
90670fc
Cleanup
kean Apr 6, 2025
5f185d0
Update more ImagePipelineCoalescingTests
kean Apr 6, 2025
65ce078
Fix some of the tests
kean Apr 6, 2025
e8e763e
Reimplement debugIsSyncImageEncoding
kean Apr 6, 2025
53f2f64
Update processingOperationPriorityUpdated
kean Apr 6, 2025
50d0bf3
Update processingOperationPriorityUpdatedWhenCancellingTask
kean Apr 6, 2025
0025c85
Update remaining ImagePipelineCoalescingTests
kean Apr 6, 2025
655725c
Update some of the ImagePipelineDataCachingTests
kean Apr 8, 2025
e77e214
Update remaining ImagePipelineDataCachingTests
kean Apr 9, 2025
7fd09c4
Update ImagePipelineDataCachePolicyTests
kean Apr 9, 2025
1aa8545
Update ImagePipelineDecodingTests
kean Apr 9, 2025
ace091b
Update ImagePipelineDelegateTests
kean Apr 9, 2025
5256078
Update ImagePipelineFormatsTests
kean Apr 9, 2025
55a87b6
Update ImagePipelineImageCacheTests
kean Apr 9, 2025
8ff95d4
Update ImagePipelineCacheLayerPriorityTests
kean Apr 9, 2025
c0c50e5
Extract loadDataProgressReported
kean Apr 9, 2025
29f48fb
Update ImagePipelineLoadDataTests
kean Apr 9, 2025
5154694
Update ImagePipelineProcessingDeduplicationTests
kean Apr 9, 2025
5a63e6b
Update ImagePipelineProcessorTests
kean Apr 9, 2025
768955e
Update ImagePipelineProgressiveDecodingTests
kean Apr 11, 2025
9f126a1
Rename Operation to OperationQueue
kean Apr 11, 2025
f5cd1f2
Update ImagePipelineResumableDataTests
kean Apr 12, 2025
bf5e2c9
Update pipeline to use type-safe throws
kean Apr 12, 2025
b143173
Update tests to use typed errors
kean Apr 12, 2025
0bfed33
Update ImageProcessorsTests
kean Apr 12, 2025
7e1d1c0
Remove now unused text expectation for ImagePipeline
kean Apr 12, 2025
2a197f5
Update FetchImageTests
kean Apr 12, 2025
9836944
Remove TestExpectationPublisher
kean Apr 12, 2025
9c7af54
Remove remaining publisher-specific expectations
kean Apr 12, 2025
a37293b
Update ImagePipelinePublisherTests
kean Apr 12, 2025
c6e03c3
Update ImagePipelinePublisherProgressiveDecodingTests
kean Apr 12, 2025
0ce7179
Update ImagePublisherTests
kean Apr 12, 2025
72d3815
ImagePipelineProgressiveDecodingTests
kean Apr 12, 2025
b402e19
Add async/await variants of loadImage methods in NukeExtensions
kean Apr 12, 2025
16687fa
Update ImageViewExtensions to used typed throws
kean Apr 12, 2025
97fbaec
Update remaining ImageViewExtensionsTests
kean Apr 12, 2025
524384f
Remove ImageViewIntegrationTests
kean Apr 12, 2025
cc4fc04
Update remaining ImageViewLoadingOptionsTests
kean Apr 12, 2025
247f331
Remove unused /NukeExtensionsTestsHelpers
kean Apr 12, 2025
5d6c138
Remove OperationThreadSafetyTests
kean Apr 12, 2025
f4de824
Update ThreadSafetyTests to Swift Concurrency
kean Apr 12, 2025
666aa50
Fix typos
kean Apr 12, 2025
2e4d6fe
Fix performance tests
kean Apr 12, 2025
c144786
Remove XCTestCaseExtensions
kean Apr 12, 2025
4a83c3c
Update defaultPriorityAffectsRequests
kean Apr 13, 2025
ce2455e
Update to use expectation.value when appropriate
kean Apr 13, 2025
c6c5c90
Extract actor-isolated _ImagePrefetcher
kean Apr 13, 2025
b69bee8
Remove nonisolated from ImagePrefetcher
kean Apr 13, 2025
284c070
Restrict AsyncExpectation publisher extensions to Sendable
kean Apr 13, 2025
e8fa1f7
Add missing Sendable
kean Apr 13, 2025
aac6e64
Fix redundant coalescing
kean Apr 13, 2025
33591c2
Optimize ImageTask/events and APIs derived from it
kean Apr 13, 2025
4cc5e68
Remove indirection from ImageTask.image
kean Apr 13, 2025
a994ba0
Switch to ContiguousArray
kean Apr 13, 2025
03ea79c
Cleanup
kean Apr 13, 2025
277cf7e
Remove unused onTaskStarted
kean Apr 13, 2025
b7168bb
Remove AsyncTask/onCancelled
kean Apr 13, 2025
ddde341
Remove unused extensions
kean Apr 13, 2025
334699c
Remove some duplicated TODO:
kean Apr 13, 2025
1c55322
Add heic magic numbers to AssetType
kean Apr 13, 2025
6758355
Eliminate Task in didFinishDecoding
kean Apr 13, 2025
3aba746
Remove redundant TODO:
kean Apr 13, 2025
027de98
Update remaining heic test
kean Apr 13, 2025
f13e165
Remove OperationHandle
kean Apr 13, 2025
eda0f6d
Rename AsyncTaskTests
kean Apr 13, 2025
f87ef52
Update WorkQueue exepctations naming
kean Apr 13, 2025
e21acf9
Update cancellation tests in AsyncTaskTests
kean Apr 13, 2025
a6361a1
Update remaining AsyncTaskTests
kean Apr 13, 2025
0a4686a
Update remaining ImagePrefetcherTests
kean Apr 13, 2025
7d32e33
Make maxConcurrentTaskCount nonisolated
kean Apr 13, 2025
0f0827b
Rename maxConcurrentOperationCount
kean Apr 13, 2025
e1e9588
Make queues public again
kean Apr 13, 2025
22e16f6
Remove legacy performance tests
kean Apr 13, 2025
8630243
Synchronize ResumableDataStorage on ImagePipelineActor
kean Apr 16, 2025
652d8f3
Remove redundant @unchecked Sendable from ImageEncodingContext
kean Apr 16, 2025
f2ea6db
Remove @unchecked Sendable from ImagePipeline.Configuration
kean Apr 16, 2025
766d6c5
Add inlinable where appropriate
kean Apr 16, 2025
34bfcab
Rework the internal AsyncTask infrastructure
kean Apr 20, 2025
9e207a1
Rename JobPriority and JobProgress
kean Apr 20, 2025
6f4b9f0
Remove priority from JobSubscription
kean Apr 20, 2025
f28d031
Remove jobs
kean Apr 20, 2025
698e0fe
Optimize initial priority setup
kean Apr 20, 2025
7441c2c
Add JobSubsciberSet
kean Apr 20, 2025
034957a
Introduce JobQueue and Operation
kean Apr 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ request.processors = [.resize(width: 320)]
- ``init(url:processors:priority:options:userInfo:)``
- ``init(urlRequest:processors:priority:options:userInfo:)``
- ``init(id:data:processors:priority:options:userInfo:)``
- ``init(id:dataPublisher:processors:priority:options:userInfo:)``
- ``init(stringLiteral:)``

### Options
Expand Down
64 changes: 28 additions & 36 deletions Nuke.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

30 changes: 3 additions & 27 deletions Sources/Nuke/Caching/DataCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,6 @@ public final class DataCache: DataCaching, @unchecked Sendable {
/// The time interval between cache sweeps. The default value is 1 hour.
public var sweepInterval: TimeInterval = 3600

// Deprecated in Nuke 12.2
@available(*, deprecated, message: "It's not recommended to use compression with the popular image formats that already compress the data")
public var isCompressionEnabled: Bool {
get { _isCompressionEnabled }
set { _isCompressionEnabled = newValue }
}
var _isCompressionEnabled = false

// Staging

private let lock = NSLock()
Expand Down Expand Up @@ -143,7 +135,7 @@ public final class DataCache: DataCaching, @unchecked Sendable {
guard let url = url(for: key) else {
return nil
}
return try? decompressed(Data(contentsOf: url))
return try? Data(contentsOf: url)
}

/// Returns `true` if the cache contains the data for the given key.
Expand Down Expand Up @@ -322,33 +314,17 @@ public final class DataCache: DataCaching, @unchecked Sendable {
switch change.type {
case let .add(data):
do {
try compressed(data).write(to: url)
try data.write(to: url)
} catch let error as NSError {
guard error.code == CocoaError.fileNoSuchFile.rawValue && error.domain == CocoaError.errorDomain else { return }
try? FileManager.default.createDirectory(at: self.path, withIntermediateDirectories: true, attributes: nil)
try? compressed(data).write(to: url) // re-create a directory and try again
try? data.write(to: url) // re-create a directory and try again
}
case .remove:
try? FileManager.default.removeItem(at: url)
}
}

// MARK: Compression

private func compressed(_ data: Data) throws -> Data {
guard _isCompressionEnabled else {
return data
}
return try (data as NSData).compressed(using: .lzfse) as Data
}

private func decompressed(_ data: Data) throws -> Data {
guard _isCompressionEnabled else {
return data
}
return try (data as NSData).decompressed(using: .lzfse) as Data
}

// MARK: Sweep

/// Synchronously performs a cache sweep and removes the least recently items
Expand Down
2 changes: 1 addition & 1 deletion Sources/Nuke/Decoding/ImageDecoderRegistry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public final class ImageDecoderRegistry: @unchecked Sendable {
}

/// Image decoding context used when selecting which decoder to use.
public struct ImageDecodingContext: @unchecked Sendable {
public struct ImageDecodingContext: Sendable {
public var request: ImageRequest
public var data: Data
/// Returns `true` if the download was completed.
Expand Down
2 changes: 1 addition & 1 deletion Sources/Nuke/Encoding/ImageEncoders+ImageIO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ extension ImageEncoders {
self.compressionRatio = compressionRatio
}

private static let availability = Atomic<[AssetType: Bool]>(value: [:])
private static let availability = Mutex<[AssetType: Bool]>([:])

/// Returns `true` if the encoding is available for the given format on
/// the current hardware. Some of the most recent formats might not be
Expand Down
2 changes: 1 addition & 1 deletion Sources/Nuke/Encoding/ImageEncoding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ extension ImageEncoding {
}

/// Image encoding context used when selecting which encoder to use.
public struct ImageEncodingContext: @unchecked Sendable {
public struct ImageEncodingContext: Sendable {
public let request: ImageRequest
public let image: PlatformImage
public let urlResponse: URLResponse?
Expand Down
2 changes: 1 addition & 1 deletion Sources/Nuke/ImageContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public typealias PlatformImage = NSImage
#endif

/// An image container with an image and associated metadata.
public struct ImageContainer: @unchecked Sendable {
public struct ImageContainer: Sendable {
#if os(macOS)
/// A fetched image.
public var image: NSImage {
Expand Down
60 changes: 8 additions & 52 deletions Sources/Nuke/ImageRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public struct ImageRequest: CustomStringConvertible, Sendable, ExpressibleByStri
switch ref.resource {
case .url(let url): return url.map { URLRequest(url: $0) } // create lazily
case .urlRequest(let urlRequest): return urlRequest
case .publisher: return nil
case .closure: return nil
}
}

Expand All @@ -80,7 +80,7 @@ public struct ImageRequest: CustomStringConvertible, Sendable, ExpressibleByStri
switch ref.resource {
case .url(let url): return url
case .urlRequest(let request): return request.url
case .publisher: return nil
case .closure: return nil
}
}

Expand Down Expand Up @@ -202,51 +202,7 @@ public struct ImageRequest: CustomStringConvertible, Sendable, ExpressibleByStri
// pipeline by using a custom DataLoader and passing an async function in
// the request userInfo. g
self.ref = Container(
resource: .publisher(DataPublisher(id: id, data)),
processors: processors,
priority: priority,
options: options,
userInfo: userInfo
)
}

/// Initializes a request with the given data publisher.
///
/// For example, here is how you can use it with the Photos framework (the
/// `imageDataPublisher` API is a custom convenience extension not included
/// in the framework).
///
/// ```swift
/// let request = ImageRequest(
/// id: asset.localIdentifier,
/// dataPublisher: PHAssetManager.imageDataPublisher(for: asset)
/// )
/// ```
///
/// - important: If you are using a pipeline with a custom configuration that
/// enables aggressive disk cache, fetched data will be stored in this cache.
/// You can use ``Options-swift.struct/disableDiskCache`` to disable it.
///
/// - parameters:
/// - id: Uniquely identifies the fetched image.
/// - data: A data publisher to be used for fetching image data.
/// - processors: Processors to be apply to the image. See <doc:image-processing> to learn more.
/// - priority: The priority of the request, ``Priority-swift.enum/normal`` by default.
/// - options: Image loading options.
/// - userInfo: Custom info passed alongside the request.
public init<P>(
id: String,
dataPublisher: P,
processors: [any ImageProcessing] = [],
priority: Priority = .normal,
options: Options = [],
userInfo: [UserInfoKey: Any]? = nil
) where P: Publisher, P.Output == Data {
// It could technically be implemented without any special change to the
// pipeline by using a custom DataLoader and passing a publisher in the
// request userInfo.
self.ref = Container(
resource: .publisher(DataPublisher(id: id, dataPublisher)),
resource: .closure(data, id: id),
processors: processors,
priority: priority,
options: options,
Expand Down Expand Up @@ -470,8 +426,8 @@ public struct ImageRequest: CustomStringConvertible, Sendable, ExpressibleByStri
(ref.userInfo?[.scaleKey] as? NSNumber)?.floatValue
}

var publisher: DataPublisher? {
if case .publisher(let publisher) = ref.resource { return publisher }
var closure: (@Sendable () async throws -> Data)? {
if case .closure(let closure, _) = ref.resource { return closure }
return nil
}
}
Expand Down Expand Up @@ -519,21 +475,21 @@ extension ImageRequest {
enum Resource: CustomStringConvertible {
case url(URL?)
case urlRequest(URLRequest)
case publisher(DataPublisher)
case closure(@Sendable () async throws -> Data, id: String)

var description: String {
switch self {
case .url(let url): return "\(url?.absoluteString ?? "nil")"
case .urlRequest(let urlRequest): return "\(urlRequest)"
case .publisher(let data): return "\(data)"
case .closure(_, let id): return id
}
}

var imageId: String? {
switch self {
case .url(let url): return url?.absoluteString
case .urlRequest(let urlRequest): return urlRequest.url?.absoluteString
case .publisher(let publisher): return publisher.id
case .closure(_, let id): return id
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/Nuke/ImageResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import AppKit
#endif

/// An image response that contains a fetched image and some metadata.
public struct ImageResponse: @unchecked Sendable {
public struct ImageResponse: Sendable {
/// An image container with an image and associated metadata.
public var container: ImageContainer

Expand Down
Loading
Loading