2015-01-19 2 views
2

내가 거래는 여기 모르겠어요 호출되지 않습니다,하지만 기능 :NSURLProtocol. requestIsCacheEquivalent는

class func requestIsCacheEquivalent(a: NSURLRequest, toRequest b: NSURLRequest) -> Bool 

은 내 NSURLProtocol 서브 클래스 내에서 호출되지 않습니다. 나는 심지어 캐시가 사용되는 것을 보았습니다. (네트워크 프록시를 사용하고 호출이 이루어지지 않음을 확인함으로써)이 방법은 결코 호출되지 않습니다. 나는 이것이 왜 그리울 까?

내가 해결하려고하는 문제는 데이터를 캐시하고 싶다는 요청이 있지만 이러한 요청에는 각각 (넌센스와 같은 종류의) 서명 매개 변수가 있습니다. 이렇게하면 데이터가 동등 함에도 불구하고 캐시 키가 동일하지 않게됩니다. 나는 (이 같은 : www.example.com?param1=1&param2=2&signature=1abcdefabc312093) 사용자 지정 서명 요청을 발사

  1. :

    명시 적 세부 사항으로 이동하려면
  2. 요청 Etag입니다이 있어야하는데 되돌려 Etag입니다
  3. 와 함께 제공 NSURLCache에 의해 관리되지만 다른 요청 (www.example.com?param1=1&param2=2&signature=1abdabcda3359809823)이 만들어지고 있다고 생각하기 때문에 걱정하지 않아도됩니다.

나는 애플의 워드 프로세서 말부터 NSURLProtocol를 사용하여 내 모든 문제를 해결할 것이라고 생각 :

class func requestIsCacheEquivalent(_ aRequest: NSURLRequest, 
         toRequest bRequest: NSURLRequest) -> Bool 

YES aRequest 및 bRequest 캐시의 목적을 위해 동등한 경우는 true, 그렇지 않은 경우는 NO . 과 같은 프로토콜로 처리되고 프로토콜이 구현 특정 검사를 수행 한 후에 동등하다고 선언하는 경우에만 요청이 캐시 목적으로 동일하게 간주됩니다.

슬프게도 함수는 호출되지 않습니다. 다음과 같이

NSURLProtocol.registerClass(WWURLProtocol.self) 

나는 프로토콜 트리거 : 나는 다음과 같이 내 애플 대리자에서 프로토콜을 등록

class WWURLProtocol : NSURLProtocol, NSURLSessionDataDelegate { 
var dataTask: NSURLSessionDataTask? 
var session: NSURLSession! 
var trueRequest: NSURLRequest! 

private lazy var netOpsQueue: NSOperationQueue! = NSOperationQueue() 
private lazy var delegateOpsQueue: NSOperationQueue! = NSOperationQueue() 

override class func canInitWithRequest(request: NSURLRequest) -> Bool { 
    println("can init with request called") 
    return true 
} 

override class func canonicalRequestForRequest(request: NSURLRequest) -> NSURLRequest { 
    println("canonical request for request called") 
    return request 
} 

override class func requestIsCacheEquivalent(a: NSURLRequest, toRequest b: NSURLRequest) -> Bool  { 
    // never ever called?!? 
    let cacheKeyA = a.allHTTPHeaderFields?["CacheKey"] as? String 
    let cacheKeyB = b.allHTTPHeaderFields?["CacheKey"] as? String 

    println("request is cache equivalent? \(cacheKeyA) == \(cacheKeyB)") 

    return cacheKeyA == cacheKeyB 
} 

override func startLoading() { 
    println("start loading") 

    let sharedSession = NSURLSession.sharedSession() 
    let config = sharedSession.configuration 
    config.URLCache = NSURLCache.sharedURLCache() 
    self.session = NSURLSession(configuration: config, delegate: self, delegateQueue: self.delegateOpsQueue) 

    dataTask = session.dataTaskWithRequest(request, nil) 
    dataTask?.resume() 
} 

override func stopLoading() { 
    println("stop loading") 
    dataTask?.cancel() 
} 


//SessionDelegate 

func URLSession(session: NSURLSession, didBecomeInvalidWithError error: NSError?) { 
    println("did become invalid with error") 
    client?.URLProtocol(self, didFailWithError: error!) 
} 


func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) { 
    println("did complete with error") 
    if error == nil { 
     client?.URLProtocolDidFinishLoading(self) 
    } else { 
     client?.URLProtocol(self, didFailWithError: error!) 
    } 
} 

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) { 
    println("did receive response") 
    client?.URLProtocol(self, didReceiveResponse: response, cacheStoragePolicy: .Allowed) 
    completionHandler(.Allow) 
} 

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) { 
    println("did receive data called") 
    client?.URLProtocol(self, didLoadData: data) 
} 

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, willCacheResponse proposedResponse: NSCachedURLResponse, completionHandler: (NSCachedURLResponse!) -> Void) { 
    println("will cache response called") 
    client?.URLProtocol(self, cachedResponseIsValid: proposedResponse) 

    completionHandler(proposedResponse) 
} 

... 문제가 될 수있는 것을 모르는

@IBAction func requestData(endpointString: String) { 
    let url = NSURL(string: endpointString) 
    let request = NSMutableURLRequest(URL: url!) 
    var cacheKey = endpointString 
    request.setValue("\(endpointString)", forHTTPHeaderField: "CacheKey") 
    request.cachePolicy = .UseProtocolCachePolicy 

    NSURLConnection.sendAsynchronousRequest(request, queue: netOpsQueue) { (response, data, error) -> Void in 
     if data != nil { 
      println("succeeded with data:\(NSString(data: data, encoding: NSUTF8StringEncoding)))") 
     } 
    } 

} 

답변

0

실제로 로딩 시스템은 캐싱 목적으로 정규화 된 URL을 사용하고 스트레이트 문자열 비교를 수행한다고 생각합니다. 그래도 나는 확실하지 않다. nonce를 정규화 할 때 쉽게 제거/감지 할 수있는 형태로 추가하십시오 (이미있을 경우).

0

코드는 약 URLProtocol 우선은 NSURLConnection에 대한 URLSession이 새로운 아이폰 OS version.Good 행운에서 더 이상 사용되지 않습니다 사용하려고 할 수있는 모든 right.You 그냥 애플의 문서를 다음과 같습니다.

관련 문제