Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save MainasuK/49b7379ebc2513b981d1ac2d9c57658a to your computer and use it in GitHub Desktop.
Save MainasuK/49b7379ebc2513b981d1ac2d9c57658a to your computer and use it in GitHub Desktop.
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