2015-02-04 1 views
2

나는 이상한 곳에서 튀어 나오는 이상한 버그가 있습니다. 나는 거의 내 애플 리케이션과 함께 다 끝났어 그리고 그것을 테스트하고 데이터가 업데이 트되지 않는 것으로 나타났습니다. 데이터베이스가 업데이트되고 URL을 직접 치고 데이터가 서버에서 올바르게 반환되는지 확인할 수 있지만 Swift에서 데이터를 인쇄하면 변경되지 않습니다. 나는 응용 프로그램을 다시 실행하면HTTP Get 요청이 Swift에서 캐시되지 않도록하려면 어떻게합니까?

은 내가 Alamofire을 사용하고

(대부분의 시간)을 변경하지만 나는 또한 다른 두 가지 방법을 시도했다 :

let url = NSURL(string: "http://www.stackoverflow.com") 
    let request = NSURLRequest(URL: url!) 

    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in 
     println(NSString(data: data, encoding: NSUTF8StringEncoding)) 
    } 

let url = NSURL(string: "http://www.stackoverflow.com") 
    let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in 
     println(NSString(data: data, encoding: NSUTF8StringEncoding)) 
    } 

    task.resume() 

모두 3 동일한 데이터를 인쇄합니다.

스위프트의 캐싱 문제라고 생각하지만 스위프트에 데이터를 캐시하도록 설정하지 않았으며 지난 몇 주 동안 정상적으로 작동했습니다.

오늘 제가 한 것은 프로젝트에 대한 Git repo입니다.

누군가이 문제를 일으킬 수있는 아이디어가 있습니까?


* 편집 : 추가

NSURLConnectionDelegate

대리인에 부합하는

: 다음

func connection(connection: NSURLConnection, willCacheResponse cachedResponse: NSCachedURLResponse) -> NSCachedURLResponse? 
{ 
    return nil // never cache anything. ever. 
} 

과를 만들기 위해이 시도 I Abhi 베커의 답변을 사용

전화 :

let url:NSURL! = NSURL(string: "http://coffee.datausadev.com/api/getCoffeeBrands") 
let request = NSURLRequest(URL: url, cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval: 60) 

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in 
    println(NSString(data: data, encoding: NSUTF8StringEncoding)) 
} 

이 방법은 여전히 ​​작동하지 않았습니다.

답변

1

당신은 NSURLConnection의 대리인으로 컨트롤러 객체를 설정해야 방법 :

func connection(connection: NSURLConnection, willCacheResponse cachedResponse: NSCachedURLResponse) -> NSCachedURLResponse? 
{ 
    return nil // never cache anything. ever. 
} 

.ReloadIgnoringLocalCacheData 옵션 URL 요청에 따라 캐시 읽기가 비활성화되고 willCacheResponse 대리자 메서드는 캐시 쓰기를 비활성화합니다. 둘 다 사용해야합니다.

불행히도 sendAsynchronousRequest 편리한 방법을 사용할 수없고 콜백을 차단할 수 없다는 의미입니다. 대신 NSURLConnectionDataDelegate의 대리자 메서드를 사용하여 응답을 처리해야합니다. 기본적으로 NSMutableData 객체를 생성하고 연결이 요청을 완료하거나 실패 할 때까지 데이터가 연결에서 들어올 때 추가합니다. 그런 다음 데이터로 무엇인가 할 수 있습니다.

내가 알고있는 한, sendAsynchronousRequest을 사용하는 동안 캐싱을 완전히 비활성화하는 것은 불가능합니다. 코드를 더 깔끔하게 만들려면 NSURLConnection 주위에 래퍼 클래스를 만들어야 할 수 있습니다.

+0

저는 임시 구성을 사용하고 다운로드를 마친 후 세션을 무효화하여 NSUrlSession (iOS7에서 도입 됨)을 사용할 때 위의 사항을 수행 할 수 있다고 확신합니다 (Apple docs에 따라 캐시를 지울 예정 임) – joakim

+0

" 클래스에는 currentConnection이라는 멤버가 없습니다. "내가 시도한 것을 보여주기 위해 내 게시물을 편집했습니다. 그래도 여전히 작동하지 않았다. – Kolby

+0

@Kolby currentConnection 클래스에 인스턴스 변수가 있어야합니다. NSURLConnection 사용법에 대한 Apple의 문서를 읽으십시오. 모든 코드가 있습니다. 캐싱과 관련된 부분 만 게시했습니다. –

1

신속한 오류가 아닙니다.

뒷 배경 NSUrlSession은 구성 객체를지지하는 특정 정책을 따릅니다.

기본 구성은 (당신이 sharedSession 싱글을 통해 사용하고있는 사람은) NSUrlSession Reference

귀하의 옵션을 통해은 "현재 설정되어있는 글로벌 NSURLCache, NSHTTPCookieStorage 및 NSURLCredentialStorage 객체와 기본 구성을 기반으로"사용

-1) 거의 캐시 아무것도 (개인 정보 보호 브라우징 모드를 생각하지 않는 "임시"구성),

-2) 설정 구성 자신을 사용하여 필요에 맞는 무엇에 캐싱 및 다른 정책을 설정합니다.

서버의 정책도 고려해야합니다. 설명서를 참조하거나 없으면 요청에 대한 응답으로 돌아 오는 http 헤더를 기반으로 최선의 결정을 내려보십시오.

편집 : 저는 Alamofire를 처음 사용하신 것으로 나타났습니다. 이 모든 기능 (Objective-c의 AF 기능)은 iOS7 이전의 NSUrlSession 및 NSUrlConnection과 같은 일을 편리하고 높은 수준으로 제공합니다. 둘 다 캐싱을 사용자 정의하고 문서를 검토해야합니다. 관련 대표와

class MyController: NSURLConnectionDataDelegate { 

비활성화 캐싱 :이 또한 자체 데이터 소스에 적합하고 필요

let request = NSURLRequest(URL: requestURL, cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval: 60) 
self.currentConnection = NSURLConnection(request: request, delegate: self) 

:

+0

나는 Alamofire를 사용하는 방법을 찾고 싶습니다. 필자는 문서를 몇 번 읽었으며 캐싱에 대해 언급 한 것은 "캐싱은 NSURLCache에 의해 시스템 프레임 워크 수준에서 처리됩니다." – Kolby

+0

캐시에서 놀아 본다는 것에 대해서는 언급하지 않았습니까? 나는 AFNetworking, Alamofire의 Objective-C 사촌이 당신이 그것을 할 수있게 해주는 것을 알고 있으며, 그것은 같은 사람들에 의해 쓰여졌습니다. 그것은 오픈 소스 프로젝트입니다. 여러분은 언제든지 그것을 파고 들여서 추가 할 수 있습니다. :) – joakim

+0

그것이 제가 금요일에하기 전에 시작한 것입니다. 이 앱은 내 첫 스위프트 앱이므로 아직 갈 때 학습하고 있습니다. 임시 구성을위한 코드를 제공 하시겠습니까? – Kolby

0

나는 모든 것을 지쳤으며, 도움이되지 못했습니다. (스위프트 3 )에 나를 위해 일한이 솔루션

나는 모든 HttpResponse에 후 destroyCache() 함수를 호출.

public static func destroyCache() { 
     let fileManager = FileManager.default 
     let documentsUrl = fileManager.urls(for: FileManager.SearchPathDirectory.cachesDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).first! as NSURL 
     let documentsPath = documentsUrl.path 
     let bundleIdentifier = Bundle.main.bundleIdentifier! as String 
     do { 
      if let documentPath = documentsPath 
      { 
       let fileNames = try fileManager.contentsOfDirectory(atPath: "\(documentPath)/\(bundleIdentifier)") 
       for fileName in fileNames { 
        let filePathName = "\(documentPath)/\(bundleIdentifier)/\(fileName)" 
        try fileManager.removeItem(atPath: filePathName) 
       } 
      } 

     } catch { 
      print("Could not clear: \(error)") 
     } 
    } 
관련 문제