Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ jobs:
build:
runs-on: macOS-15
env:
XCODE_VERSION: 16
dotnetVersion: 9.0.100
XCODE_VERSION: 16.2
dotnetVersion: 9.0.200

steps:
- name: Checkout
Expand Down
166 changes: 105 additions & 61 deletions NukeProxy/NukeProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import Nuke

@objc(ImagePipeline)
public class ImagePipeline : NSObject {

@objc
public static let shared = ImagePipeline()

Expand All @@ -22,6 +21,9 @@ public class ImagePipeline : NSObject {
Nuke.ImagePipeline.shared = Nuke.ImagePipeline(configuration: .withDataCache)
}

private var tasks: [ImageTask] = []
private let taskLock = NSLock()

@objc
public func isCached(for url: URL) -> Bool {
return Nuke.ImagePipeline.shared.cache.containsCachedImage(for: ImageRequest(url: url))
Expand All @@ -47,94 +49,137 @@ public class ImagePipeline : NSObject {
public func removeAllCaches() {
Nuke.ImagePipeline.shared.cache.removeAll()
}

@objc
public func loadImage(url: URL, onCompleted: @escaping (UIImage?, String) -> Void) {
_ = Nuke.ImagePipeline.shared.loadImage(
public func loadImage(url: URL, onCompleted: @escaping (UIImage?, String) -> Void) -> Int64 {
let task = Nuke.ImagePipeline.shared.loadImage(
with: url,
progress: nil,
completion: { result in
completion: { [weak self] result in
switch result {
case let .success(response):
onCompleted(response.image, "success")
case let .failure(error):
onCompleted(nil, error.localizedDescription)
}
self?.removeAllTasksForUrl(url.absoluteString)
}
)

return addTask(task)
}

@objc
public func loadImage(url: URL, placeholder: UIImage?, errorImage: UIImage?, into: UIImageView) {
loadImage(url: url, placeholder: placeholder, errorImage: errorImage, into: into, reloadIgnoringCachedData: false)
public func loadImage(url: URL, placeholder: UIImage?, errorImage: UIImage?, into: UIImageView) -> Int64 {
return loadImage(url: url, placeholder: placeholder, errorImage: errorImage, into: into, reloadIgnoringCachedData: false)
}

@objc
public func loadImage(url: URL, placeholder: UIImage?, errorImage: UIImage?, into: UIImageView, reloadIgnoringCachedData: Bool) {
let options = ImageLoadingOptions(placeholder:placeholder, failureImage: errorImage)
Nuke.loadImage(
with: ImageRequest(
urlRequest: URLRequest(
url: url,
cachePolicy: reloadIgnoringCachedData ?
URLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData :
URLRequest.CachePolicy.useProtocolCachePolicy
)
),
public func loadImage(url: URL, placeholder: UIImage?, errorImage: UIImage?, into: UIImageView, reloadIgnoringCachedData: Bool) -> Int64 {
let options = ImageLoadingOptions(placeholder: placeholder, failureImage: errorImage)
let cachePolicy = reloadIgnoringCachedData ? URLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData : URLRequest.CachePolicy.useProtocolCachePolicy
let urlRequest = URLRequest(url: url, cachePolicy: cachePolicy)
let request = ImageRequest(urlRequest: urlRequest)

let task = Nuke.loadImage(
with: request,
options: options,
into: into)
into: into
)

return addTask(task)
}

@objc
public func loadImage(url: URL, imageIdKey: String, placeholder: UIImage?, errorImage: UIImage?, into: UIImageView) {
loadImage(url: url, imageIdKey: imageIdKey, placeholder: placeholder, errorImage: errorImage, into: into, reloadIgnoringCachedData: false)
public func loadImage(url: URL, imageIdKey: String, placeholder: UIImage?, errorImage: UIImage?, into: UIImageView) -> Int64 {
return loadImage(url: url, imageIdKey: imageIdKey, placeholder: placeholder, errorImage: errorImage, into: into, reloadIgnoringCachedData: false)
}

@objc
public func loadImage(url: URL, imageIdKey: String, placeholder: UIImage?, errorImage: UIImage?, into: UIImageView, reloadIgnoringCachedData: Bool) {
public func loadImage(url: URL, imageIdKey: String, placeholder: UIImage?, errorImage: UIImage?, into: UIImageView, reloadIgnoringCachedData: Bool) -> Int64 {
let options = ImageLoadingOptions(placeholder: placeholder, failureImage: errorImage)

Nuke.loadImage(
with: ImageRequest(
urlRequest: URLRequest(
url: url,
cachePolicy: reloadIgnoringCachedData ?
URLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData :
URLRequest.CachePolicy.useProtocolCachePolicy
),
userInfo: [.imageIdKey: imageIdKey ]
),
let cachePolicy = reloadIgnoringCachedData ? URLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData : URLRequest.CachePolicy.useProtocolCachePolicy
let urlRequest = URLRequest(url: url, cachePolicy: cachePolicy)
let request = ImageRequest(urlRequest: urlRequest, userInfo: [.imageIdKey: imageIdKey])

let task = Nuke.loadImage(
with: request,
options: options,
into: into
)
}

return addTask(task)
}

@objc
public func loadData(url: URL, onCompleted: @escaping (Data?, URLResponse?) -> Void) {
loadData(url: url, imageIdKey: nil, reloadIgnoringCachedData: false, onCompleted: onCompleted)
public func loadData(url: URL, onCompleted: @escaping (Data?, URLResponse?) -> Void) -> Int64 {
return loadData(url: url, imageIdKey: nil, reloadIgnoringCachedData: false, onCompleted: onCompleted)
}

@objc
public func loadData(url: URL, imageIdKey: String?, reloadIgnoringCachedData: Bool, onCompleted: @escaping (Data?, URLResponse?) -> Void) {
_ = Nuke.ImagePipeline.shared.loadData(
with: ImageRequest(
urlRequest: URLRequest(
url: url,
cachePolicy: reloadIgnoringCachedData ?
URLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData :
URLRequest.CachePolicy.useProtocolCachePolicy
),
userInfo: imageIdKey == nil ? nil : [.imageIdKey: imageIdKey! ]
),
completion: { result in
public func loadData(url: URL, imageIdKey: String?, reloadIgnoringCachedData: Bool, onCompleted: @escaping (Data?, URLResponse?) -> Void) -> Int64 {
let cachePolicy = reloadIgnoringCachedData ? URLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData : URLRequest.CachePolicy.useProtocolCachePolicy
let urlRequest = URLRequest(url: url, cachePolicy: cachePolicy)
let request = ImageRequest(urlRequest: urlRequest, userInfo: imageIdKey == nil ? nil : [.imageIdKey: imageIdKey!])

let task = Nuke.ImagePipeline.shared.loadData(
with: request,
completion: { [weak self] result in
switch result {
case let .success(response):
onCompleted(response.data, response.response)
case .failure(_):
onCompleted(nil, nil)
}
self?.removeAllTasksForUrl(url.absoluteString)
}
)

return addTask(task)
}

@objc
public func cancelTasksForUrl(_ url: String) {
var cancelledTasks = [ImageTask]()

taskLock.lock()
tasks.forEach { task in
if (task.request.imageId == url) {
task.cancel()
cancelledTasks.append(task)
}
}

tasks.removeAll { task in
cancelledTasks.contains(task)
}
taskLock.unlock()
}

@objc
public func cancelTask(_ taskId: Int64) {
taskLock.lock()
tasks.first(where: { $0.taskId == taskId })?.cancel()
tasks.removeAll(where: { $0.taskId == taskId })
taskLock.unlock()
}

private func addTask(_ task: ImageTask?) -> Int64 {
guard let task else {
return -1
}

taskLock.lock()
tasks.append(task)
taskLock.unlock()

return task.taskId
}

private func removeAllTasksForUrl(_ url: String) {
taskLock.lock()
tasks.removeAll(where: { $0.request.imageId == url })
taskLock.unlock()
}
}

Expand Down Expand Up @@ -162,7 +207,7 @@ public final class DataLoader: NSObject {

@objc(Prefetcher)
public final class Prefetcher: NSObject {

private var prefetcher: ImagePrefetcher

@objc
Expand All @@ -173,17 +218,16 @@ public final class Prefetcher: NSObject {
@objc
public init(destination: Destination = .memoryCache) {
prefetcher = ImagePrefetcher(destination: destination == .memoryCache ?
ImagePrefetcher.Destination.memoryCache :
ImagePrefetcher.Destination.memoryCache :
ImagePrefetcher.Destination.diskCache)
}

@objc
public init(destination: Destination = .memoryCache,
maxConcurrentRequestCount: Int = 2) {
prefetcher = ImagePrefetcher(destination: destination == .memoryCache ?
ImagePrefetcher.Destination.memoryCache :
ImagePrefetcher.Destination.diskCache,
maxConcurrentRequestCount: maxConcurrentRequestCount)
public init(destination: Destination = .memoryCache, maxConcurrentRequestCount: Int = 2) {
prefetcher = ImagePrefetcher(
destination: destination == .memoryCache ? ImagePrefetcher.Destination.memoryCache : ImagePrefetcher.Destination.diskCache,
maxConcurrentRequestCount: maxConcurrentRequestCount
)
}

@objc
Expand Down
4 changes: 4 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/bin/bash

mkdir -p artifacts

echo "Update carthage deps"
sh carthage.sh update --use-xcframeworks --platform iOS --log-path artifacts/carthage.log

Expand All @@ -8,6 +10,8 @@ echo 'exit 0' > Carthage/Checkouts/Nuke/Scripts/validate.sh

sh carthage.sh build --use-xcframeworks --platform iOS --log-path artifacts/carthage.log

rm -r Output/NukeProxy.xcframework

echo "xcode build"
xcodebuild archive -sdk iphoneos -project NukeProxy.xcodeproj -scheme NukeProxy -configuration Release -archivePath Output/Output-iphoneos SKIP_INSTALL=NO
xcodebuild archive -sdk iphonesimulator -project NukeProxy.xcodeproj -scheme NukeProxy -configuration Release -archivePath Output/Output-iphonesimulator SKIP_INSTALL=NO
Expand Down
38 changes: 23 additions & 15 deletions src/ImageCaching.Nuke/ApiDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,33 +65,41 @@ interface ImagePipeline
[Export ("removeAllCaches")]
void RemoveAllCaches ();

// -(void)loadImageWithUrl:(NSURL * _Nonnull)url onCompleted:(void (^ _Nonnull)(UIImage * _Nullable, NSString * _Nonnull))onCompleted;
// -(Int64)loadImageWithUrl:(NSURL * _Nonnull)url onCompleted:(void (^ _Nonnull)(UIImage * _Nullable, NSString * _Nonnull))onCompleted;
[Export ("loadImageWithUrl:onCompleted:")]
void LoadImageWithUrl (NSUrl url, Action<UIImage, NSString> onCompleted);
long LoadImageWithUrl (NSUrl url, Action<UIImage, NSString> onCompleted);

// -(void)loadImageWithUrl:(NSURL * _Nonnull)url placeholder:(UIImage * _Nullable)placeholder errorImage:(UIImage * _Nullable)errorImage into:(UIImageView * _Nonnull)into;
// -(Int64)loadImageWithUrl:(NSURL * _Nonnull)url placeholder:(UIImage * _Nullable)placeholder errorImage:(UIImage * _Nullable)errorImage into:(UIImageView * _Nonnull)into;
[Export ("loadImageWithUrl:placeholder:errorImage:into:")]
void LoadImageWithUrl (NSUrl url, [NullAllowed] UIImage placeholder, [NullAllowed] UIImage errorImage, UIImageView into);
long LoadImageWithUrl (NSUrl url, [NullAllowed] UIImage placeholder, [NullAllowed] UIImage errorImage, UIImageView into);

// -(void)loadImageWithUrl:(NSURL * _Nonnull)url placeholder:(UIImage * _Nullable)placeholder errorImage:(UIImage * _Nullable)errorImage into:(UIImageView * _Nonnull)into reloadIgnoringCachedData:(BOOL)reloadIgnoringCachedData;
// -(Int64)loadImageWithUrl:(NSURL * _Nonnull)url placeholder:(UIImage * _Nullable)placeholder errorImage:(UIImage * _Nullable)errorImage into:(UIImageView * _Nonnull)into reloadIgnoringCachedData:(BOOL)reloadIgnoringCachedData;
[Export ("loadImageWithUrl:placeholder:errorImage:into:reloadIgnoringCachedData:")]
void LoadImageWithUrl (NSUrl url, [NullAllowed] UIImage placeholder, [NullAllowed] UIImage errorImage, UIImageView into, bool reloadIgnoringCachedData);
long LoadImageWithUrl (NSUrl url, [NullAllowed] UIImage placeholder, [NullAllowed] UIImage errorImage, UIImageView into, bool reloadIgnoringCachedData);

// -(void)loadImageWithUrl:(NSURL * _Nonnull)url imageIdKey:(NSString * _Nonnull)imageIdKey placeholder:(UIImage * _Nullable)placeholder errorImage:(UIImage * _Nullable)errorImage into:(UIImageView * _Nonnull)into;
// -(Int64)loadImageWithUrl:(NSURL * _Nonnull)url imageIdKey:(NSString * _Nonnull)imageIdKey placeholder:(UIImage * _Nullable)placeholder errorImage:(UIImage * _Nullable)errorImage into:(UIImageView * _Nonnull)into;
[Export ("loadImageWithUrl:imageIdKey:placeholder:errorImage:into:")]
void LoadImageWithUrl (NSUrl url, string imageIdKey, [NullAllowed] UIImage placeholder, [NullAllowed] UIImage errorImage, UIImageView into);
long LoadImageWithUrl (NSUrl url, string imageIdKey, [NullAllowed] UIImage placeholder, [NullAllowed] UIImage errorImage, UIImageView into);

// -(void)loadImageWithUrl:(NSURL * _Nonnull)url imageIdKey:(NSString * _Nonnull)imageIdKey placeholder:(UIImage * _Nullable)placeholder errorImage:(UIImage * _Nullable)errorImage into:(UIImageView * _Nonnull)into reloadIgnoringCachedData:(BOOL)reloadIgnoringCachedData;
// -(Int64)loadImageWithUrl:(NSURL * _Nonnull)url imageIdKey:(NSString * _Nonnull)imageIdKey placeholder:(UIImage * _Nullable)placeholder errorImage:(UIImage * _Nullable)errorImage into:(UIImageView * _Nonnull)into reloadIgnoringCachedData:(BOOL)reloadIgnoringCachedData;
[Export ("loadImageWithUrl:imageIdKey:placeholder:errorImage:into:reloadIgnoringCachedData:")]
void LoadImageWithUrl (NSUrl url, string imageIdKey, [NullAllowed] UIImage placeholder, [NullAllowed] UIImage errorImage, UIImageView into, bool reloadIgnoringCachedData);
long LoadImageWithUrl (NSUrl url, string imageIdKey, [NullAllowed] UIImage placeholder, [NullAllowed] UIImage errorImage, UIImageView into, bool reloadIgnoringCachedData);

// -(void)loadDataWithUrl:(NSURL * _Nonnull)url onCompleted:(void (^ _Nonnull)(NSData * _Nullable, NSUrlResponse * _Nullable))onCompleted;
// -(Int64)loadDataWithUrl:(NSURL * _Nonnull)url onCompleted:(void (^ _Nonnull)(NSData * _Nullable, NSUrlResponse * _Nullable))onCompleted;
[Export ("loadDataWithUrl:onCompleted:")]
void LoadDataWithUrl (NSUrl url, Action<NSData, NSUrlResponse> onCompleted);
long LoadDataWithUrl (NSUrl url, Action<NSData, NSUrlResponse> onCompleted);

// -(void)loadDataWithUrl:(NSURL * _Nonnull)url imageIdKey:(NSString * _Nullable)imageIdKey reloadIgnoringCachedData:(BOOL)reloadIgnoringCachedData onCompleted:(void (^ _Nonnull)(NSData * _Nullable, NSUrlResponse * _Nullable))onCompleted;
// -(Int64)loadDataWithUrl:(NSURL * _Nonnull)url imageIdKey:(NSString * _Nullable)imageIdKey reloadIgnoringCachedData:(BOOL)reloadIgnoringCachedData onCompleted:(void (^ _Nonnull)(NSData * _Nullable, NSUrlResponse * _Nullable))onCompleted;
[Export ("loadDataWithUrl:imageIdKey:reloadIgnoringCachedData:onCompleted:")]
void LoadDataWithUrl (NSUrl url, [NullAllowed] string imageIdKey, bool reloadIgnoringCachedData, Action<NSData, NSUrlResponse> onCompleted);
long LoadDataWithUrl (NSUrl url, [NullAllowed] string imageIdKey, bool reloadIgnoringCachedData, Action<NSData, NSUrlResponse> onCompleted);

// -(Int64)cancelTasksForUrl:(NSString * _Nonnull)url;
[Export ("cancelTasksForUrl:")]
void CancelTasksForUrl (string url);

// -(void)cancelTask:(Int64 * _Nonnull)taskId;
[Export ("cancelTask:")]
void CancelTask (long taskId);
}

// @interface Prefetcher : NSObject
Expand Down Expand Up @@ -128,4 +136,4 @@ interface Prefetcher
[Export ("unPause")]
void UnPause ();
}
}
}
Loading
Loading