-
Notifications
You must be signed in to change notification settings - Fork 1
制作流程
zhtut edited this page Dec 17, 2021
·
2 revisions
5.HTTPURLProtocol 400行 if request.isTimeoutIntervalSet 这个属性是内部方法,无法得知,使用timeoutInterval>0替换使用,判断一下是否为inf和nan
let requestTimeOut = request.timeoutInterval
if !requestTimeOut.isInfinite && !requestTimeOut.isNaN && request.timeoutInterval > 0 {
timeoutInterval = Int(request.timeoutInterval) * 1000
}
if #available(iOS 11.0, *) {
return try NSKeyedUnarchiver.unarchivedObject(ofClasses: [StoredCachedURLResponse.self], from: data) as? StoredCachedURLResponse
} else {
return NSKeyedUnarchiver.unarchiveObject(with: data) as? StoredCachedURLResponse
}
500行也是一样 var serialized: Data? if #available(iOS 11.0, *) { serialized = (onDisk && diskCapacity > 0) ? try? NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: true) : nil } else { // Fallback on earlier versions serialized = (onDisk && diskCapacity > 0) ? NSKeyedArchiver.archivedData(withRootObject: object) : nil }
return Foundation.URLProtocol.property(forKey: key, in: request)
Foundation.URLProtocol.setProperty(value, forKey: key, in: request)
Foundation.URLProtocol.removeProperty(forKey: key, in: request)
// add-
public struct _InputStreamSPIForFoundationNetworkingUseOnly {
var inputStream: InputStream
public init(_ inputStream: InputStream) {
self.inputStream = inputStream
}
public func seek(to position: UInt64) throws {
try inputStream.seek(to: position)
}
}
extension InputStream {
enum _Error: Error {
case cantSeekInputStream
}
func seek(to position: UInt64) throws {
guard position > 0 else {
return
}
guard position < Int.max else { throw _Error.cantSeekInputStream }
let bufferSize = 1024
var remainingBytes = Int(position)
let buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: bufferSize, alignment: MemoryLayout<UInt8>.alignment)
guard let pointer = buffer.baseAddress?.assumingMemoryBound(to: UInt8.self) else {
buffer.deallocate()
throw _Error.cantSeekInputStream
}
if self.streamStatus == .notOpen {
self.open()
}
while remainingBytes > 0 && self.hasBytesAvailable {
let read = self.read(pointer, maxLength: min(bufferSize, remainingBytes))
if read == -1 {
throw _Error.cantSeekInputStream
}
remainingBytes -= read
}
buffer.deallocate()
if remainingBytes != 0 {
throw _Error.cantSeekInputStream
}
}
}
if #available(iOS 13.0, *) {
guard let authenticateValue = response.value(forHTTPHeaderField: "WWW-Authenticate") else {
return []
}
return challenges(from: authenticateValue)
} else {
// Fallback on earlier versions
let allHeaders = response.allHeaderFields
guard let authenticateValue = allHeaders["WWW-Authenticate"] as? String else {
return []
}
return challenges(from: authenticateValue)
}
10.NetworkingSpecific有找不到的结构体_NSNonfileURLContentLoading,这个在swiftRuntime中,把结构体定义拷过来即可,注册这个loader也可以,这里没有调用
public protocol _NSNonfileURLContentLoading: AnyObject {
init()
func contentsOf(url: URL) throws -> (result: NSData, textEncodingNameIfAvailable: String?)
}
extension URLProtectionSpace {
//an internal helper to create a URLProtectionSpace from a HTTPURLResponse
static func create(with response: HTTPURLResponse) -> URLProtectionSpace? {
// Using first challenge, as we don't support multiple challenges yet
guard let challenge = _HTTPURLProtocol._HTTPMessage._Challenge.challenges(from: response).first else {
return nil
}
guard let url = response.url, let host = url.host, let proto = url.scheme, proto == "http" || proto == "https" else {
return nil
}
let port = url.port ?? (proto == "http" ? 80 : 443)
return URLProtectionSpace(host: host,
port: port,
protocol: proto,
realm: challenge.parameter(withName: "realm")?.value,
authenticationMethod: challenge.authenticationMethod)
}
}
extension _HTTPURLProtocol._HTTPMessage._Challenge {
var authenticationMethod: String? {
if authScheme.caseInsensitiveCompare(_HTTPURLProtocol._HTTPMessage._Challenge.AuthSchemeBasic) == .orderedSame {
return NSURLAuthenticationMethodHTTPBasic
} else if authScheme.caseInsensitiveCompare(_HTTPURLProtocol._HTTPMessage._Challenge.AuthSchemeDigest) == .orderedSame {
return NSURLAuthenticationMethodHTTPDigest
} else {
return nil
}
}
}
class URLSessionAuthenticationChallengeSender : NSObject, URLAuthenticationChallengeSender {
func cancel(_ challenge: URLAuthenticationChallenge) {
fatalError("swift-corelibs-foundation only supports URLSession; for challenges coming from URLSession, please implement the appropriate URLSessionTaskDelegate methods rather than using the sender argument.")
}
func continueWithoutCredential(for challenge: URLAuthenticationChallenge) {
fatalError("swift-corelibs-foundation only supports URLSession; for challenges coming from URLSession, please implement the appropriate URLSessionTaskDelegate methods rather than using the sender argument.")
}
func use(_ credential: URLCredential, for challenge: URLAuthenticationChallenge) {
fatalError("swift-corelibs-foundation only supports URLSession; for challenges coming from URLSession, please implement the appropriate URLSessionTaskDelegate methods rather than using the sender argument.")
}
func performDefaultHandling(for challenge: URLAuthenticationChallenge) {
fatalError("swift-corelibs-foundation only supports URLSession; for challenges coming from URLSession, please implement the appropriate URLSessionTaskDelegate methods rather than using the sender argument.")
}
func rejectProtectionSpaceAndContinue(with challenge: URLAuthenticationChallenge) {
fatalError("swift-corelibs-foundation only supports URLSession; for challenges coming from URLSession, please implement the appropriate URLSessionTaskDelegate methods rather than using the sender argument.")
}
}
extension URLCredentialStorage {
@objc
public func getCredentials(for protectionSpace: URLProtectionSpace, task: URLSessionTask, completionHandler: ([String : URLCredential]?) -> Void) {
completionHandler(credentials(for: protectionSpace))
}
@objc
public func set(_ credential: URLCredential, for protectionSpace: URLProtectionSpace, task: URLSessionTask) {
set(credential, for: protectionSpace)
}
@objc
public func remove(_ credential: URLCredential, for protectionSpace: URLProtectionSpace, options: [String : AnyObject]? = [:], task: URLSessionTask) {
remove(credential, for: protectionSpace, options: options)
}
@objc
public func getDefaultCredential(for space: URLProtectionSpace, task: URLSessionTask, completionHandler: (URLCredential?) -> Void) {
completionHandler(defaultCredential(for: space))
}
@objc
public func setDefaultCredential(_ credential: URLCredential, for protectionSpace: URLProtectionSpace, task: URLSessionTask) {
setDefaultCredential(credential, for: protectionSpace)
}
}
剩余的就是在适当的地方加上@objc,使库支持oc访问