Forked from carlynorama/URLSessionDelegateExample.swift
Created
November 14, 2024 02:42
-
-
Save MainasuK/49b7379ebc2513b981d1ac2d9c57658a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import PlaygroundSupport | |
import Foundation | |
PlaygroundPage.current.needsIndefiniteExecution = true | |
//URLSessionTaskDelegate | |
//You use this protocol in one of two ways, depending on how you use a URLSession: | |
//If you create tasks with Swift’s async-await syntax, using methods like bytes(for:delegate:) and data(for:delegate:), you pass a delegate argument of this type. The delegate receives callbacks for things like task progress, while the call point awaits the completion of the task. A delegate that receives life cycle and authentication challenge callbacks as the transfer progresses. | |
//If you add tasks to the session with methods like dataTask(with:) and downloadTask(with:), then you implement this protocol’s methods in a delegate you set on the session. This session delegate may also implement other protocols as appropriate, like URLSessionDownloadDelegate and URLSessionDataDelegate. You can also assign a delegate of this type directly to the task to intercept callbacks before the task delivers them to the session’s delegate. | |
//TODO?: https://developer.apple.com/documentation/foundation/urlsessiondownloaddelegate | |
//would appear to work exclusively with downloadTask not .download | |
//https://github.com/apple/swift-corelibs-foundation/blob/main/Sources/FoundationNetworking/URLSession/URLSessionTask.swift | |
@available(iOS 15.0, *) | |
public class TestDelegate: NSObject, URLSessionDataDelegate, URLSessionTaskDelegate { | |
private var session: URLSession! = nil | |
private var dataTask: URLSessionDataTask? | |
private var sessionTask: URLSessionTask? | |
public init(urlSession:URLSession? = nil) { | |
super.init() | |
if urlSession != nil { | |
self.session = urlSession! | |
} else { | |
let config = URLSessionConfiguration.default | |
config.requestCachePolicy = .reloadIgnoringLocalCacheData | |
self.session = URLSession(configuration: config, delegate: self, delegateQueue: .main) | |
} | |
} | |
let urlString_redirect = "http:www.apple.com" | |
let urlString_json = "https://jsonplaceholder.typicode.com/posts/1" | |
let urlString_auth = "https://httpbin.org/basic-auth/hello/dolly" | |
public func simpleGet() async throws { | |
let url = URL(string:urlString_json)! | |
let (data, response) = try await self.session.data(from:url, delegate: self) | |
print(sessionTask?.state.rawValue) | |
print(sessionTask?.progress) | |
print(sessionTask?.progress.fileOperationKind) | |
let httpResponse = response as? HTTPURLResponse | |
print("Task \(sessionTask?.description ?? "") heard \(httpResponse?.statusCode ?? 0)") | |
print(await session.tasks) | |
print("I got data. \(data.count)") | |
} | |
public func simpleDataTask() { | |
let url = URL(string:urlString_json)! | |
self.dataTask = self.session.dataTask(with: URLRequest(url: url)) | |
dataTask?.resume() | |
} | |
//MARK: WORKS .data & .dataTask | |
public func urlSession(_ session: URLSession, didCreateTask task: URLSessionTask) { | |
print("I made a task:\(task)") | |
self.sessionTask = task | |
} | |
//fires on finish | |
public func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) { | |
print("metrics for \(task) recieved.") | |
//print(metrics) | |
} | |
public func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest) async -> URLRequest? { | |
print("redirecting... \(String(describing: request.url))") | |
return request | |
} | |
//MARK: Worked JUST for .data | |
//presumably the one with a completion handler is for .dataTask | |
//but was challenge even maybe when wasn't supposed to have been? | |
public func urlSession( | |
_ session: URLSession, | |
task: URLSessionTask, | |
didReceive challenge: URLAuthenticationChallenge | |
) async -> (URLSession.AuthChallengeDisposition, URLCredential?) { | |
print("challenged \(task) with \(challenge)") | |
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic { | |
do { | |
let (username, password) = ("hello", "dolly") | |
return (.useCredential, URLCredential(user: username, password: password, persistence: .forSession)) | |
} catch { | |
return (.cancelAuthenticationChallenge, nil) | |
} | |
} else { | |
return (.performDefaultHandling, nil) | |
} | |
} | |
//MARK: Works with dataTask only | |
public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse) async -> URLSession.ResponseDisposition { | |
let httpResponse = response as? HTTPURLResponse | |
print("Task \(dataTask) heard \(httpResponse?.statusCode ?? 0)") | |
return URLSession.ResponseDisposition.allow | |
} | |
public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { | |
print("I heard that...\(data.count)") | |
//NSLog("task data: %@", data as NSData) | |
//print("task data: %@", data as NSData) | |
} | |
public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { | |
if let error = error as NSError? { | |
//NSLog("task error: %@ / %d", error.domain, error.code) | |
print("task error: %@ / %d", error.domain, error.code) | |
} else { | |
print("task complete") | |
//NSLog("task complete") | |
} | |
} | |
public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didBecome downloadTask: URLSessionDownloadTask) { | |
print("downLoadTask\(downloadTask) from dataTask \(dataTask)") | |
} | |
public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didBecome streamTask: URLSessionStreamTask) { | |
print("streamTask\(streamTask) from dataTask \(dataTask)") | |
} | |
//auth catch for data task. | |
// public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { | |
// print("challenged with \(challenge)") | |
// //No idea what else to do. | |
// } | |
// public func urlSession(_ session: URLSession, task: URLSessionTask, willBeginDelayedRequest request: URLRequest) async -> (URLSession.DelayedRequestDisposition, URLRequest?) { | |
// <#code#> | |
// } | |
} | |
let testDelegate = TestDelegate() | |
Task { | |
do { | |
try await testDelegate.simpleGet() | |
testDelegate.simpleDataTask() | |
} catch { | |
print(error.self) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment