NSURLRequest가 데이터를 캐시하지 못하도록하거나 요청 후 캐시 된 데이터를 제거 할 수 있습니까?


90

iPhone에서는 데이터 청크에 대해 NSURLRequest를 사용하여 HTTP 요청을 수행합니다. 개체 할당이 급증하고 그에 따라 데이터를 할당합니다. 데이터 작업을 마치면 그에 따라 해제합니다. 그러나 기기에는 해제 된 데이터가 표시되지 않습니다!

내 이론은 기본적으로 HTTP 요청이 캐시되지만 iPhone 앱이이 데이터를 캐시하는 것을 원하지 않습니다.

요청 후이 캐시를 지우거나 데이터가 처음에 캐시되지 않도록하는 방법이 있습니까?

다음과 같이 약간 문서화 된 모든 캐시 정책을 사용해 보았습니다.

NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
theRequest.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;

그러나 아무것도 기억을 비우는 것 같지 않습니다!


캐시와 관련이 없을 가능성이 있습니까? 다시로드해야하는 데이터가 실제로 이전 데이터인지 확인하기 위해 데이터를 검사 해 보셨습니까? 아마 당신의 부추는 다른 곳에서 왔을 것입니다. NSURLRequests를 어떻게 초기화하고 해제합니까? 문제를 진단하는 데 도움이 될 수 있습니다.
lpfavreau

참고로 – 무차별 대입으로 파일을 제거하려는 경우이를 수행하는 예제 코드가 있습니다. salesforce.stackexchange.com/a/69736
zekel

답변:


158

일반적으로 다음과 같은 요청을 만드는 것이 더 쉽습니다.

NSURLRequest *request = [NSURLRequest requestWithURL:url
      cachePolicy:NSURLRequestReloadIgnoringCacheData
      timeoutInterval:60.0];

그런 다음 연결을 만듭니다.

NSURLConnection *conn = [NSURLConnection connectionWithRequest:request
       delegate:self];

대리자에서 connection : willCacheResponse : 메서드를 구현합니다. nil을 반환하면됩니다.

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
  return nil;
}

도움을 주셔서 감사합니다! 새긴 ​​금.
Nick Cartwright

1
그 아이디어에 감사드립니다-나는 이와 같은 SOAP 웹 서비스를 반복적으로 호출하고 있었고 누출이 아무 것도 잘못되었음을 보여주지 않았음에도 불구하고 제어 할 수없이 힙을 증가 시켰습니다. 며칠 동안 최적화하고 마침내 내부 프레임 워크의 많은 CFURL * 개체가 매달려 있었기 때문에 캐싱을 방지하려고했습니다. willCacheResponse에서 nil을 반환하는 것이 유일하게 작동했습니다!
Bron Davies

15
둘 다 수행 NSURLRequestReloadIgnoringCacheData 하고 구현 해야하는 이유는 무엇 connection:willCacheResponse:입니까?
fabb

1
안녕하세요, 이것을 로컬 콘텐츠를로드하는 데 사용할 수 있습니까? 위는 NSUrlConnection에 대한 것이지만 NSUrlRequest를 사용하여 로컬 HTML 데이터를 UIWebView에로드하고 있습니다. SQLite에서 웹 뷰로 들어가는 이미지가 있고 페이지가로드 될 때마다 메모리가 증가하므로 캐싱을 거부해야합니다. 감사.
jim

7
@fabb, 재정의 connection:willCacheResponse:하면 응답을 캐시에 저장할 수 없습니다. NSURLRequestReloadIgnoringCacheData연결이 캐시를 확인하지 않고 요청을로드하도록 지정합니다. 전자는 아마도 메모리 할당을 관리하는 데 도움이 될 것입니다.
Christopher Pickslay 2011

12

트위터에서 정보를 요청할 때 내 앱에서 동일한 문제가 발생합니다. 제 경우에는 해당 자격 증명을 보존 할 필요가 없었으므로 다음 코드를 사용하여 간단히 지 웁니다.

- (void) eraseCredentials{
NSURLCredentialStorage *credentialsStorage = [NSURLCredentialStorage sharedCredentialStorage];
NSDictionary *allCredentials = [credentialsStorage allCredentials];

//iterate through all credentials to find the twitter host
for (NSURLProtectionSpace *protectionSpace in allCredentials)
    if ([[protectionSpace host] isEqualToString:@"twitter.com"]){
        //to get the twitter's credentials
        NSDictionary *credentials = [credentialsStorage credentialsForProtectionSpace:protectionSpace];
        //iterate through twitter's credentials, and erase them all
        for (NSString *credentialKey in credentials)
            [credentialsStorage removeCredential:[credentials objectForKey:credentialKey] forProtectionSpace:protectionSpace];
    }
}

누군가에게 효과가 있기를 바랍니다. :)


이 자격 증명이 저장되어 자동으로있는 NSURLConnection에 의해 제출되고 있었다 때문에 내 문제에 대한 완벽한 솔루션, 난 :)이 나에게 굉장한 도움이, 감사에게, 많은 문제를 다시 로그인 있었다
RVN

감사합니다. 제안 해 주셔서 감사합니다. 실제로 내 문제는 NSURLRequest가 사용자 이름과 비밀번호를 저장한다는 것입니다. 이 도움말은 ... 캐시에서 사용자 자격 증명을 제거하는 그래서
Nilesh Kikani

10

NSURLConnection을 사용하는 경우 대리자를 살펴보십시오.

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse

반환 값

캐시에 저장할 실제 캐시 된 응답입니다. 델리게이트는 수정되지 않은 cachedResponse를 반환하거나, 수정 된 캐시 된 응답을 반환하거나, 연결에 대해 캐시 된 응답을 저장해야하는 경우 nil을 반환 할 수 있습니다.


여기에 정말 감사합니다. 내 앱의 메모리 사용량이 갑자기 절반으로 줄어 들었습니다! 새긴 ​​금.
Nick Cartwright

9

당신이 사용하는 경우 NSURLSession요청을 방지하기 위해, 또 다른 솔루션과에 매개 변수가 기록되는 Cache.db아이폰 OS는 응용 프로그램의 내 생성 Caches디렉토리의 설정하는 것입니다 NSURLCacheA와 세션의 구성을 0 크기의 메모리와 공 크기의 디스크 캐시

let configuration = URLSessionConfiguration.default    
configuration.urlCache = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)
let session = URLSession(configuration: configuration)

또는 위에서 언급했듯이 전역 캐시 수준에서 설정

URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)

아마도 iOS가 디스크에 쓰는 것을 중지하는 디스크 크기의 경우 0이지만 정책이 있다면 reloadIgnoringLocalCacheData아마도 메모리 캐싱에도 관심이 없을 것입니다.

참고 이렇게하면 Caches/Cache.db(요청 및 응답) 또는 Caches/fsCachedData/폴더 (응답 데이터)가 전혀 생성되지 않습니다. 우리는 요청이 디스크 캐시에 저장되는 것을 원하지 않으므로 보안 목적으로 앱에서이 접근 방식을 사용하기로 결정했습니다.

요청 캐싱 만 중지하고 iOS URL로드 메커니즘에서 응답 데이터 캐싱을 유지하는 방법이 있다는 것을 아는 사람이 있다면 알고 싶습니다. (내가 말할 수있는 API 나 공식 문서가 없습니다)


7

하나의 요청에 국한되지 않는 경우 (U는 전체 앱에 대해 캐시를 비활성화하려는 경우) 하나 아래에있는 것이 가장 좋습니다.이 코드를 앱 대리자에 추가하거나 필요에 따라 어디에나 추가하십시오.

        int cacheSizeMemory = 0*4*1024*1024; // 0MB
        int cacheSizeDisk = 0*32*1024*1024; // 0MB
        NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"];
        [NSURLCache setSharedURLCache:sharedCache];

7
나를 위해 잘 작동하지만 어쨌든 0으로 끝나는 곱셈을 수행하는 대신 0을 사용할 수 있습니다.
Gary Riches 2011

1
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] url];
[request setValue:@"no-store" forHTTPHeaderField:@"Cache-Control"];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];

서버가 올바르게 구현되었다고 가정하고 Cache-Control:no-store요청에 헤더를 넣으면 동일한 헤더를 가진 서버 응답이 생성 NSURLCache되어 응답 데이터가 디스크에 저장되지 않습니다.

따라서 NSURLCache디스크 캐싱 을 비활성화하는 샷건 방식이 필요하지 않습니다 .

추신 : 헤더 추가는 다음과 같은 모든 HTTP 프레임 워크에서 작동합니다. AFNetworking

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.