我正在尝试实现本教程,该教程使用NSURLConnection实现自定义NSURLProtocol.
https://www.raywenderlich.com/76735/using-nsurlprotocol-swift
它按预期工作,但现在在iOS9中不推荐使用NSURLConnection,我试图将其转换为NSURLSession.
不幸的是,它没有用.
我正在uiwebview中加载一个网站,如果我使用NSURLConnection加载并且一切都按预期工作,则会捕获来自webview的所有http请求,但在使用NSURLSession时则不会.
任何帮助表示赞赏.
这是我的代码
import UIKit class MyProtocol: NSURLProtocol,NSURLSessionDataDelegate,NSURLSessionTaskDelegate,NSURLSessionDelegate { //var connection: NSURLConnection! var mutableData: NSMutableData! var response: NSURLResponse! var dataSession: NSURLSessionDataTask! override class func canInitWithRequest(request: NSURLRequest) -> Bool { if NSURLProtocol.propertyForKey("MyURLProtocolHandledKey",inRequest: request) != nil { return false } return true } override class func canonicalRequestForRequest(request: NSURLRequest) -> NSURLRequest { return request } override class func requestIsCacheEquivalent(aRequest: NSURLRequest,toRequest bRequest: NSURLRequest) -> Bool { return super.requestIsCacheEquivalent(aRequest,toRequest:bRequest) } override func startLoading() { let newRequest = self.request.mutableCopy() as! NSMutableURLRequest NSURLProtocol.setProperty(true,forKey: "MyURLProtocolHandledKey",inRequest: newRequest) self.dataSession = NSURLSession.sharedSession().dataTaskWithRequest(newRequest) dataSession.resume() self.mutableData = NSMutableData() } override func stopLoading() { print("Data task stop") self.dataSession.cancel() self.mutableData = nil } func URLSession(session: NSURLSession,dataTask: NSURLSessionDataTask,didReceiveResponse response: NSURLResponse,completionHandler: (NSURLSessionResponseDisposition) -> Void) { self.response = response self.mutableData = NSMutableData() print(mutableData) } func URLSession(session: NSURLSession,didReceiveData data: NSData) { self.client?.URLProtocol(self,didLoadData: data) self.mutableData.appendData(data) } func URLSession(session: NSURLSession,task: NSURLSessionTask,didCompleteWithError error: NSError?) { if (error == nil) { self.client!.URLProtocolDidFinishLoading(self) self.saveCachedResponse() } else { self.client?.URLProtocol(self,didFailWithError: error!) } } func saveCachedResponse () { let timeStamp = NSDate() let urlString = self.request.URL?.absoluteString let dataString = NSString(data: self.mutableData,encoding: NSUTF8StringEncoding) as NSString? print("TiemStamp:\(timeStamp)\nURL: \(urlString)\n\nDATA:\(dataString)\n\n") } }
解决方法
我已经解决了.
如果有人需要,这是代码.
import Foundation class MyProtocol1: NSURLProtocol,NSURLSessionTaskDelegate { private var dataTask:NSURLSessionDataTask? private var urlResponse:NSURLResponse? private var receivedData:NSMutableData? class var CustomKey:String { return "myCustomKey" } // MARK: NSURLProtocol override class func canInitWithRequest(request: NSURLRequest) -> Bool { if (NSURLProtocol.propertyForKey(MyProtocol1.CustomKey,inRequest: request) != nil) { return false } return true } override class func canonicalRequestForRequest(request: NSURLRequest) -> NSURLRequest { return request } override func startLoading() { let newRequest = self.request.mutableCopy() as! NSMutableURLRequest NSURLProtocol.setProperty("true",forKey: MyProtocol1.CustomKey,inRequest: newRequest) let defaultConfigObj = NSURLSessionConfiguration.defaultSessionConfiguration() let defaultSession = NSURLSession(configuration: defaultConfigObj,delegate: self,delegateQueue: nil) self.dataTask = defaultSession.dataTaskWithRequest(newRequest) self.dataTask!.resume() } override func stopLoading() { self.dataTask?.cancel() self.dataTask = nil self.receivedData = nil self.urlResponse = nil } // MARK: NSURLSessionDataDelegate func URLSession(session: NSURLSession,completionHandler: (NSURLSessionResponseDisposition) -> Void) { self.client?.URLProtocol(self,didReceiveResponse: response,cacheStoragePolicy: .NotAllowed) self.urlResponse = response self.receivedData = NSMutableData() completionHandler(.Allow) } func URLSession(session: NSURLSession,didReceiveData data: NSData) { self.client?.URLProtocol(self,didLoadData: data) self.receivedData?.appendData(data) } // MARK: NSURLSessionTaskDelegate func URLSession(session: NSURLSession,didCompleteWithError error: NSError?) { if error != nil && error!.code != NSURLErrorCancelled { self.client?.URLProtocol(self,didFailWithError: error!) } else { saveCachedResponse() self.client?.URLProtocolDidFinishLoading(self) } } // MARK: Private methods /** Do whatever with the data here */ func saveCachedResponse () { let timeStamp = NSDate() let urlString = self.request.URL?.absoluteString let dataString = NSString(data: self.receivedData!,encoding: NSUTF8StringEncoding) as NSString? print("TimeStamp:\(timeStamp)\nURL: \(urlString)\n\nDATA:\(dataString)\n\n") } }