From cdb1d787e645b6d8d2a49654c657f64fbe075bc7 Mon Sep 17 00:00:00 2001 From: Donny Wals Date: Wed, 20 Nov 2024 09:55:03 +0100 Subject: [PATCH] ensure callbacks are called and removed when no longer needed --- .../TransloaditAPI+URLSessionDelegate.swift | 16 +++++++------ Sources/TransloaditKit/TransloaditAPI.swift | 19 ++++++++------- .../URLSessionCompletionHandler.swift | 11 +++++++++ .../TransloaditKitExample/PhotoPicker.swift | 1 - .../TransloaditKitExampleApp.swift | 24 +++++++++++++++++-- 5 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 Sources/TransloaditKit/URLSessionCompletionHandler.swift diff --git a/Sources/TransloaditKit/TransloaditAPI+URLSessionDelegate.swift b/Sources/TransloaditKit/TransloaditAPI+URLSessionDelegate.swift index 3bbdbac..bcc58f0 100644 --- a/Sources/TransloaditKit/TransloaditAPI+URLSessionDelegate.swift +++ b/Sources/TransloaditKit/TransloaditAPI+URLSessionDelegate.swift @@ -1,25 +1,27 @@ import Foundation -extension TransloaditAPI: URLSessionDelegate { +extension TransloaditAPI: URLSessionDataDelegate { public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { - guard let callback = callbacks[task]?.1 else { + guard let completionHandler = callbacks[task] else { return } + defer { callbacks[task] = nil } + if let error { - callback(.failure(error)) + completionHandler.callback(.failure(error)) return } - guard let data = callbacks[task]?.0, let response = task.response else { - //callback(.failure(TransloaditAPIError.unknown)) + guard let response = task.response else { + completionHandler.callback(.failure(TransloaditAPIError.incompleteServerResponse)) return } - callback(.success((data, response))) + completionHandler.callback(.success((completionHandler.data, response))) } public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { - callbacks[dataTask]?.0?.append(data) + callbacks[dataTask]?.data.append(data) } } diff --git a/Sources/TransloaditKit/TransloaditAPI.swift b/Sources/TransloaditKit/TransloaditAPI.swift index 1b7497d..caf4552 100644 --- a/Sources/TransloaditKit/TransloaditAPI.swift +++ b/Sources/TransloaditKit/TransloaditAPI.swift @@ -14,10 +14,11 @@ enum TransloaditAPIError: Error { case couldNotFetchStatus case couldNotCreateAssembly(Error) case assemblyError(String) + case incompleteServerResponse } /// The `TransloaditAPI` class makes API calls, such as creating assemblies or checking an assembly's status. -final class TransloaditAPI { +final class TransloaditAPI: NSObject { private let basePath = URL(string: "https://api2.transloadit.com")! @@ -40,12 +41,13 @@ final class TransloaditAPI { }() private let credentials: Transloadit.Credentials - var callbacks: [URLSessionTask: (Data?, (Result<(Data, URLResponse), Error>) -> Void)] = [:] + var callbacks: [URLSessionTask: URLSessionCompletionHandler] = [:] init(credentials: Transloadit.Credentials, session: URLSession) { self.credentials = credentials self.configuration = session.configuration self.delegateQueue = session.delegateQueue + super.init() } func createAssembly( @@ -67,7 +69,7 @@ final class TransloaditAPI { } let task = session.dataTask(with: request) - callbacks[task] = (Data(), { result in + callbacks[task] = URLSessionCompletionHandler(callback: { result in switch result { case .failure(let error): completion(.failure(.couldNotCreateAssembly(error))) @@ -109,7 +111,8 @@ final class TransloaditAPI { } let task = session.dataTask(with: request) - callbacks[task] = (Data(), { result in + //task.delegate = self + callbacks[task] = URLSessionCompletionHandler(callback: { result in switch result { case .failure(let error): completion(.failure(.couldNotCreateAssembly(error))) @@ -282,8 +285,8 @@ final class TransloaditAPI { return request } - let task = session.dataTask(request: makeRequest()) - callbacks[task] = (Data(), { result in + let task = session.dataTask(with: makeRequest()) + callbacks[task] = URLSessionCompletionHandler(callback: { result in switch result { case .failure: completion(.failure(.couldNotFetchStatus)) @@ -308,8 +311,8 @@ final class TransloaditAPI { return request } - let task = session.dataTask(request: makeRequest()) - callbacks[task] = (Data(), { result in + let task = session.dataTask(with: makeRequest()) + callbacks[task] = URLSessionCompletionHandler(callback: { result in switch result { case .failure: completion(.failure(.couldNotFetchStatus)) diff --git a/Sources/TransloaditKit/URLSessionCompletionHandler.swift b/Sources/TransloaditKit/URLSessionCompletionHandler.swift new file mode 100644 index 0000000..c79115c --- /dev/null +++ b/Sources/TransloaditKit/URLSessionCompletionHandler.swift @@ -0,0 +1,11 @@ +import Foundation + +class URLSessionCompletionHandler { + var data: Data + let callback: (Result<(Data, URLResponse), Error>) -> Void + + init(callback: @escaping (Result<(Data, URLResponse), Error>) -> Void) { + self.callback = callback + self.data = Data() + } +} diff --git a/TransloaditKitExample/TransloaditKitExample/PhotoPicker.swift b/TransloaditKitExample/TransloaditKitExample/PhotoPicker.swift index 82a1d63..d0d34bf 100644 --- a/TransloaditKitExample/TransloaditKitExample/PhotoPicker.swift +++ b/TransloaditKitExample/TransloaditKitExample/PhotoPicker.swift @@ -18,7 +18,6 @@ struct PhotoPicker: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> PHPickerViewController { var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared()) configuration.selectionLimit = 30 - configuration.filter = .images let picker = PHPickerViewController(configuration: configuration) picker.delegate = context.coordinator diff --git a/TransloaditKitExample/TransloaditKitExample/TransloaditKitExampleApp.swift b/TransloaditKitExample/TransloaditKitExample/TransloaditKitExampleApp.swift index d886e22..9d6ec44 100644 --- a/TransloaditKitExample/TransloaditKitExample/TransloaditKitExampleApp.swift +++ b/TransloaditKitExample/TransloaditKitExample/TransloaditKitExampleApp.swift @@ -12,6 +12,26 @@ import Atlantis final class MyUploader: ObservableObject { let transloadit: Transloadit + func upload2(_ urls: [URL]) { + let templateID = "1a84d2f1f2584f92981bda285bbc4e84" + + transloadit.createAssembly(templateId: templateID, andUpload: urls, customFields: ["hello": "world"]) { result in + switch result { + case .success(let assembly): + print("Retrieved \(assembly)") + case .failure(let error): + print("Assembly error \(error)") + } + }.pollAssemblyStatus { result in + switch result { + case .success(let assemblyStatus): + print("Received assemblystatus \(assemblyStatus)") + case .failure(let error): + print("Caught polling error \(error)") + } + } + } + func upload(_ urls: [URL]) { let resizeStep = StepFactory.makeResizeStep(width: 200, height: 100) transloadit.createAssembly(steps: [resizeStep], andUpload: urls, customFields: ["hello": "world"]) { result in @@ -32,7 +52,7 @@ final class MyUploader: ObservableObject { } init() { - let credentials = Transloadit.Credentials(key: "my_key", secret: "my_secret") + let credentials = Transloadit.Credentials(key: "Ru1rwq3ITrgSEDtgna6SGZa4yY71YJgW", secret: "Xo6xlnn42cfBkNxLSDWJNCQoSNL0j1aFB9wNyaAR") self.transloadit = Transloadit(credentials: credentials, session: URLSession.shared) self.transloadit.fileDelegate = self } @@ -90,7 +110,7 @@ struct TransloaditKitExampleApp: App { init() { self.uploader = MyUploader() - // Atlantis.start(hostName: "") + Atlantis.start(hostName: "donnys-macbook-pro-2.local.") } var body: some Scene {