Say you have
extension APISingleton {
func items (
_ blah: Blah?,
completionOnMain: ( (_ status: Int, _ found: Blahs) -> ())? = nil
) {
let t = URLSession.shared.dataTask(with: r) { [weak self] (d, r, r) in
guard let self else { ..; return }
blah
self.blah
DispatchQueue.main.async { completionOnMain?(666, []) }
blah
DispatchQueue.main.async { completionOnMain?(200, parsed) }
}
p = task.progress.etc {NB, p is held somewhere}
t.resume()
}
func refunds ( ... other similar api calls
}
and you call it from anywhere, perhaps a VC, as
api.items(thisUser) { .. etc
// note, obviously you use weak self here in the VC
// this, obviously, is not what the question is about TY
foldin(stuff: found)
}
I have always checked that self
still exists in
URLSession.shared.dataTask(with: r) { [weak self] (d, r, r) in
However, that could be completely pointless. What is the situation?
I can't see how a retain cycle could be created since everything in the closure is only within .items
within the API singleton.
I know that this is not a literal answer to the question, but I'd like to suggest an example how to use progress report with the async/await
API
Run the code in a Playground and replace https://example.com/pathToLargeFile.zip
with a real URL pointing to a large file
class ProgressTest : NSObject, URLSessionTaskDelegate {
private var progressObservation: NSKeyValueObservation?
func load() async {
do {
let url = URL(string: "https://example.com/pathToLargeFile.zip")!
let (data, _ ) = try await URLSession.shared.data(from: url, delegate: self)
print("complete")
} catch {
print(error)
}
}
func urlSession(_ session: URLSession, didCreateTask task: URLSessionTask) {
progressObservation = task.progress.observe(\.fractionCompleted) { progress, value in
print("progress: ", progress.fractionCompleted)
}
}
}
Task {
let test = ProgressTest()
await test.load()
}