2016-03-30 25 views
6

NSURLConnection ile özel bir NSURLProtocol uygulayan bu eğiticiyi uygulamaya çalışıyorum. beklendiği gibiNSURLSession ile Özel NSURLProtocol

https://www.raywenderlich.com/76735/using-nsurlprotocol-swift

O, ama şimdi NSURLConnection iOS9 önerilmiyor, ben NSURLSession dönüştürmek çalışıyorum çalışır.

Talihsizce işe yaramadı.

uiwebview'de bir web sitesi yüklüyorum, eğer NSURLConnection kullanırsam yükler yükler ve her şey beklendiği gibi çalışırsa, web görünümünün tüm http istekleri yakalanır, ancak NSURLSession kullanıldığında değil.

Herhangi bir yardım için teşekkür ederiz.

burada kendi koduyla yaşıyorsanız sorun size veri görevi içerecek şekilde NSURLSession.sharedSession kullanıyor olmasıdır kodum

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, dataTask: NSURLSessionDataTask, 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") 
    } 


    } 
+0

nasıl kod çalışmıyor biliyoruz? Sorunu kendin bulmak için ne yaptın? Kod örneğinizden geri dönüp yorumlanmış tüm bölümleri kaldırabilir misiniz? Her rutinde ne yapmaya çalıştığınız hakkında bazı yorumlar ekleyebilirsiniz. –

+0

Hey, web görüntüleme önbellekleme ile hızlı ve karşılaşılan sorun konusunda yeniyim. Aynı kaynak ile çalışıyorum, web sayfası düzgün yükleyin ve önbelleğe kaydedin. Ancak cihaz çevrimdışı olduğunda önbellek verisinden alamıyorum. Kodu urlsession ile güncellemeliyim. Lütfen bu kaynak ile bana yardımcı olabilir misiniz :(https://drive.google.com/file/d/0B-5GPXUpPZh-Q2FOWEJudXRaQkE/view?usp=sharing –

cevap

6

Bunu çözdüm.

Kimin buna ihtiyacı varsa, buradaki kod.

import Foundation 

class MyProtocol1: NSURLProtocol, NSURLSessionDataDelegate, 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, dataTask: NSURLSessionDataTask, 
       didReceiveResponse response: NSURLResponse, 
            completionHandler: (NSURLSessionResponseDisposition) -> Void) { 

    self.client?.URLProtocol(self, didReceiveResponse: response, cacheStoragePolicy: .NotAllowed) 

    self.urlResponse = response 
    self.receivedData = NSMutableData() 

    completionHandler(.Allow) 
} 

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) { 
    self.client?.URLProtocol(self, didLoadData: data) 

    self.receivedData?.appendData(data) 
} 

// MARK: NSURLSessionTaskDelegate 

func URLSession(session: NSURLSession, task: NSURLSessionTask, 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") 
} 


} 
+0

Teşekkürler adamım. çok yardımcı oldu. Aşağıda herkesin ihtiyacı olması halinde aynı sınıfın hızlı 3 sürümü. – deepax11

+0

Her istek için ayrı bir NSURLSession kullanmanız gerekmez. Bu çok verimsiz. Bunun yerine, tek bir paylaşılan örneği (bir dispatch_once bloğunda başlatılan genel bir değişken kullanarak) kullanmayı düşünmelisiniz. – dgatwood

5

olduğunu. Paylaşılan oturumu kullanarak oturum temsilcisini değiştiremezsiniz, böylece delege rutinlerinin hiçbiri çalıştırılamaz.

Oturumunuz için temsilci olarak kurulan protokolünüzle özel bir oturum oluşturmanız gerekir. Daha sonra, yüklemeye başlamanız istendiğinde, bu oturumda bir veri görevi oluşturabilirsiniz.

+0

merhaba, cevap için teşekkürler, yorumladı out kodu NSURLConnection içindir iOS9'da kullanımdan kaldırıldığından NSURLSession'a dönüştürmem gerekiyor, Ne yapıyorum uiwebview'deki tüm http isteklerini izlemek ve belirli url isteklerinden JSON yanıtını kaydetmek istiyorum. Kod NSURLConnection kullanarak iyi çalıştı, ama şimdi NSURLConnection ile istekleri görebiliyorum ve webview siteyi yüklüyor ve linke tıklanmış ancak NSURLSession ile yapılan değişiklikten sonra webview dos web sitesini yüklemiyor .. – kupilot

+0

Evet Anlıyorum. bağlantı için temsilci kurarken NSURLConnection kullanıyor ve verileri topladıysanız, yeni NSSession tabanlı kodunuzda NSSession.sharedSession kullanmak yerine özel bir oturum oluşturmanız gerekir. Bu oturumda oturum ve veri görev temsilci geri aramaları çağrılabilir. –

+0

Yardımlarınız için teşekkürler, çözdüm, Cevabımı görün. – kupilot

6

Swift 3 versiyon:

// CustomURLProtocol.swift 

class CustomURLProtocol: URLProtocol, URLSessionDataDelegate, URLSessionTaskDelegate { 
    private var dataTask: URLSessionDataTask? 
    private var urlResponse: URLResponse? 
    private var receivedData: NSMutableData? 

    class var CustomHeaderSet: String { 
     return "CustomHeaderSet" 
    } 

    // MARK: NSURLProtocol 

    override class func canInit(with request: URLRequest) -> Bool { 
     guard let host = request.url?.host, host == "your domain.com" else { 
      return false 
     } 
     if (URLProtocol.property(forKey: CustomURLProtocol.CustomHeaderSet, in: request as URLRequest) != nil) { 
      return false 
     } 

     return true 
    } 

    override class func canonicalRequest(for request: URLRequest) -> URLRequest { 
     return request 
    } 

    override func startLoading() { 

     let mutableRequest = NSMutableURLRequest.init(url: self.request.url!, cachePolicy: NSURLRequest.CachePolicy.useProtocolCachePolicy, timeoutInterval: 240.0)//self.request as! NSMutableURLRequest 

     //Add User Agent 

     var userAgentValueString = "myApp" 
    mutableRequest.setValue(userAgentValueString, forHTTPHeaderField: "User-Agent") 

     print(mutableRequest.allHTTPHeaderFields ?? "") 
     URLProtocol.setProperty("true", forKey: CustomURLProtocol.CustomHeaderSet, in: mutableRequest) 
     let defaultConfigObj = URLSessionConfiguration.default 
     let defaultSession = URLSession(configuration: defaultConfigObj, delegate: self, delegateQueue: nil) 
     self.dataTask = defaultSession.dataTask(with: mutableRequest as URLRequest) 
     self.dataTask!.resume() 

    } 

    override func stopLoading() { 
     self.dataTask?.cancel() 
     self.dataTask  = nil 
     self.receivedData = nil 
     self.urlResponse = nil 
    } 

    // MARK: NSURLSessionDataDelegate 

    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, 
        didReceive response: URLResponse, 
        completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) { 

     self.client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed) 

     self.urlResponse = response 
     self.receivedData = NSMutableData() 

     completionHandler(.allow) 
    } 

    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { 
     self.client?.urlProtocol(self, didLoad: data as Data) 

     self.receivedData?.append(data as Data) 
    } 

    // MARK: NSURLSessionTaskDelegate 

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { 
     if error != nil { //&& error.code != NSURLErrorCancelled { 
      self.client?.urlProtocol(self, didFailWithError: error!) 
     } else { 
      //saveCachedResponse() 
      self.client?.urlProtocolDidFinishLoading(self) 
     } 
    } 
} 
+0

Çalışıyor ancak tam web sitesini gösteriyor. Mobil site görünümünü gösterme. – vp2698