Last active
August 2, 2023 09:18
-
-
Save rinov/30e3851a6521e20c99f88c73d5dfeede to your computer and use it in GitHub Desktop.
Guide on Swizzling Asynchronous URLSession Method
This file contains hidden or 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 SwiftUI | |
import Foundation | |
class CustomHTTPProtocol: URLProtocol { | |
private var dataTask: URLSessionDataTask? | |
override class func canonicalRequest(for request: URLRequest) -> URLRequest { | |
print(#function) | |
return request | |
} | |
override class func requestIsCacheEquivalent(_ a: URLRequest, to b: URLRequest) -> Bool { | |
print(#function) | |
return super.requestIsCacheEquivalent(a, to: b) | |
} | |
override class func canInit(with request: URLRequest) -> Bool { | |
print(#function) | |
print("Request: \(request.url?.absoluteString ?? "Unknown")") | |
return true | |
} | |
override func startLoading() { | |
print(#function) | |
dataTask = URLSession.shared.dataTask(with: request) { data, response, error in | |
if let error = error { | |
self.client?.urlProtocol(self, didFailWithError: error) | |
} else { | |
if let data = data, let response = response { | |
print("Response: \(String(data: data, encoding: .utf8) ?? "")") | |
self.client?.urlProtocol(self, didLoad: data) | |
self.client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed) | |
} | |
self.client?.urlProtocolDidFinishLoading(self) | |
} | |
} | |
dataTask?.resume() | |
} | |
override func stopLoading() { | |
print(#function) | |
dataTask?.cancel() | |
} | |
} | |
extension URLSessionConfiguration { | |
static func swizzleDefaultSessionConfiguration() { | |
let defaultSessionConfiguration = class_getClassMethod(URLSessionConfiguration.self, #selector(getter: URLSessionConfiguration.default)) | |
let swizzledDefaultSessionConfiguration = class_getClassMethod(URLSessionConfiguration.self, #selector(URLSessionConfiguration.swizzledDefaultSessionConfiguration)) | |
method_exchangeImplementations(defaultSessionConfiguration!, swizzledDefaultSessionConfiguration!) | |
} | |
@objc class func swizzledDefaultSessionConfiguration() -> URLSessionConfiguration { | |
let configuration = swizzledDefaultSessionConfiguration() | |
configuration.protocolClasses?.insert(CustomHTTPProtocol.self, at: 0) | |
return configuration | |
} | |
} | |
struct ContentView: View { | |
@State var responseData: String = "" | |
var body: some View { | |
VStack { | |
Text("Response Data:") | |
Text(responseData) | |
} | |
.task { | |
await fetchData() | |
} | |
} | |
func fetchData() async { | |
guard let url = URL(string: "https://github.com/rinov/") else { | |
return | |
} | |
let config = URLSessionConfiguration.default | |
let session = URLSession(configuration: config) | |
do { | |
let (data, _) = try await session.data(from: url) | |
if let string = String(data: data, encoding: .utf8) { | |
responseData = string | |
} | |
} catch { | |
print("Error: \(error)") | |
} | |
} | |
} | |
struct ContentView_Previews: PreviewProvider { | |
static var previews: some View { | |
ContentView() | |
} | |
} |
This file contains hidden or 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 SwiftUI | |
@main | |
struct TestAsyncURLSessionSwizzleApp: App { | |
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate | |
var body: some Scene { | |
WindowGroup { | |
ContentView() | |
} | |
} | |
class AppDelegate: UIResponder, UIApplicationDelegate { | |
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { | |
URLSessionConfiguration.swizzleDefaultSessionConfiguration() | |
return true | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment