Disk Cache(디스크 캐시)는 기기의 디스크에 데이터를 일시적으로 저장하는 메멤즈로, iOS 애플리케이션이 이전에 로드된 리소스에 다시 액세스하는 속도를 가속합니다. Apple Developer Documentation, 2024에 따르면, Disk Cache는 네트워크 사용량을 줄이고, 배터리 부하를 감소시키며, 오프라인 모드에서 애플리케이션 작업을 가능하게 합니다. iOS는 몇 가지 내장 캐싰 메멤즘을 제공합니다: 네트워크 요청용 URLCache, RAM용 NSCache, 그리고 Caches 디렉토리를 통한 캠스텀 구현입니다.
주요 포인트
Disk Cache는 기기의 영구 저장장치(플래시 메모리)에 데이터를 일시적으로 저장하여 동일한 데이터에 대한 추후 요청을 가속하는 기술입니다. RAM 캐시와 달리, Disk Cache는 애플리케이션 및 기기 재시작 후도 데이터를 유지합니다.
iOS는 두 가지 주요 캐싰 레벨을 제공합니다: 브기성(NSCache, 메모리) 및 디스크 기반(URLCache, 파일 시스템)입니다. 디스크 캐시는 브기성 캐시보다 10–100배 느리지만, 네트워크 요청보다는 효율적으로 빠릅니다. 그 차이는 2에서 3 정도까지일 수 있습니다. 최적의 전략은 두 레벨 캐시를 사용합니다: 탁트 데이터에는 메모리, 콘드 데이터에는 디스크입니다.
Apple Performance Optimization Guide, 2023에 따르면, 적절히 구성된 Disk Cache는 반복 보기에서 컨텐츠 로딩 시간을 60–80% 단축하고 트래픽 소비를 40–70% 감소시킵니다. 미디어 풀부한 애플리케이션(이미지, 동영상, 오디오)에서 캐싰은 중요한 UX 요소입니다.
URLCache는 URLSession 요청을 위한 복합 캐시를 구현하는 내장 Foundation 클래스입니다. Cache-Control, Expires 및 ETag와 같은 HTTP 헤더에 기반하여 캐시 크기와 무효화 정책을 관리하면서 서버 응답을 자동으로 디스크와 메모리에 저장합니다.
import Foundation
let cache = URLCache(
memoryCapacity: 50 * 1024 * 1024,
diskCapacity: 200 * 1024 * 1024,
diskPath: "network-cache"
)
URLCache.shared = cache
let config = URLSessionConfiguration.default
config.urlCache = cache
config.requestCachePolicy = .returnCacheDataElseLoad
let session = URLSession(configuration: config)
URLCache 캐싰 정책은 캐싰된 데이터를 사용할 시점과 새 요청을 수행할 시점을 결정합니다. 주요 정책은 다음과 같습니다: useProtocolCachePolicy(서버 헤더 기반), reloadIgnoringLocalCacheData(항상 서버에서), returnCacheDataElseLoad(캐시 우선), returnCacheDataDontLoad(캐시 전용 — 오프라인 모드).
Cache-Control은 서버가 응답과 함께 보내는 HTTP 헤더로, max-age(최대 수명(초)), must-revalidate(신선성 확인), no-cache(확인 없이 사용 금지) 및 no-store(캐싰 금지)를 지정합니다. iOS는 useProtocolCachePolicy 정책과 함께 URLCache를 사용할 때 이러한 헤더를 자동으로 엄격하게 준수합니다.
캠스텀 캐싰은 내장 URLCache가 부족할 때 필요합니다 — 처리된 이미지, 직렬화된 데이터 모델 또는 계산 결과를 저장하기 위해서입니다. 이런 경우 개발자는 애플리케이션의 Sandbox에 Caches 디렉토리를 기반으로 자체 캐싰 시스템을 구축합니다.
class DiskCache<T: Codable> {
private let cacheDir: URL
private let encoder = JSONEncoder()
private let decoder = JSONDecoder()
init() {
let paths = FileManager.default
.urls(for: .cachesDirectory,
in: .userDomainMask)
cacheDir = paths[0].appendingPathComponent(
"data-cache", isDirectory: true
)
try? FileManager.default
.createDirectory(at: cacheDir,
withIntermediateDirectories: true)
}
func set(value: T, for key: String) {
let url = cacheDir.appendingPathComponent(
SHA256.hash(key)
)
if let data = try? encoder.encode(value) {
try? data.write(to: url)
}
}
func get(for key: String) -> T? {
let url = cacheDir.appendingPathComponent(
SHA256.hash(key)
)
guard let data = try? Data(contentsOf: url) else { return nil }
return try? decoder.decode(T.self, from: data)
}
func clearAll() {
try? FileManager.default
.removeItem(at: cacheDir)
}
}
캐시 무효화 전략은 저장된 데이터가 언제 구된것으로 간주되는지 결정합니다: TTL(Time-To-Live) — 데이터가 작성 후 일정 기간 유효; 이벤트 구동 — 이벤트(예: 서버에서 데이터 업데이트)에 기반한 무효화; 버전 기반 — API 버전 또는 데이터 형식 변경 시 무효화; LRU(Least Recently Used) — 크기 제한을 초과하면 가장 적게 사용된 항목을 자동 제거.
실전 규칙: TTL은 예측 가능한 기간이 지나면 구된하는 뉴스 및 컨텐츠에 적합합니다. 이벤트 구동은 퓨시 알림을 통한 서버 관리 데이터에 적합합니다. 버전 기반은 구성 및 데이터 모델 캐시에 적합합니다. LRU는 제한된 디스크 공간이 있는 미디어 파일에 보편적인 선택입니다.
Disk Cache 성능은 타 비율(hit ratio)로 책정됩니다 — 네트워크 호출 없이 캐시에서 충족된 요청의 백분율입니다. 잘 구성된 이미지 캐시의 일반적인 타 비율은 70–90%, API 응답은 40–60%, 스트리밍 동영상은 30–50%입니다.
| 데이터 유형 | 일반적인 타 비율 | 권장 캐시 크기 |
|---|---|---|
| 이미지 | 70–90% | 100–500 MB |
| API JSON 응답 | 40–60% | 10–50 MB |
| 동영상/오디오 | 30–50% | 500 MB — 1 GB |
| 폰트 및 리소스 | 90–99% | 5–20 MB |
| 웹 컨텐츠 | 50–70% | 50–200 MB |
iOS에서 Disk Cache 제한: 시스템은 디스크 공간이 부족할 때 언제든지 Caches 디렉토리의 내용을 삭제할 수 있습니다. 이 동작은 구성할 수 없습니다 — iOS가 언제 그리고 어떤 캐싰 파일을 삭제할지 결정합니다. 따라서, 캐시에는 네트워크 또는 다른 출처에서 복구할 수 없는 데이터가 있어서는 안 됩니다.
플래시 메모리에 미치는 영향: Disk Cache에 잧은 쓰기는 플래시 저장장치의 마계를 가속화합니다. iOS는 TRIM 및 웨어 레벨링을 사용하여 마계를 최소화하지만, 개발자는 과도한 쓰기를 피하도록 권장됩니다: 동일한 파일에 대해 5분에 한 번 이상 캐시를 업데이트하지 마세요; 작은 쓰기를 한깨번에 모으세요; 디스크에 저장할 필요가 없는 일시 데이터에는 NSCache를 사용하세요.
두 레벨 캐시는 iOS 애플리케이션의 표준 아키텍처입니다: 자주 액세스하는 데이터에는 메모리(NSCache), 세션 간에 유지해야 하는 데이터에는 디스크(URLCache 또는 캠스텀)입니다. 메모리에서의 수명은 분 단위, 디스크에서는 시간 또는 몇 일입니다.
이미지 캐싰: 자동 무효화, 메모리 관리 및 비동기 디스크 쓰기를 갖춘 두 레벨 캐시를 구현하는 전문 라이브러리(Kingfisher, SDWebImage, Nuke)를 사용하세요. 캠스텀 이미지 캐시를 구현하려면 디코딩, 색상 공간 및 스케일링을 고려해야 합니다.
캐시 및 보안: 비밀번호, 토큰, 개인 정보와 같은 민감한 데이터를 암호화 없이 디스크에 캐시하지 마세요. URLCache는 기본적으로 데이터를 암호화하지 않습니다 — 민감한 컨텐츠에는 NSFileProtection 또는 애플리케이션 레벨 암호화를 사용하세요. 인증이 필요한 네트워크 요청에는 .reloadIgnoringLocalCacheData 정책을 사용하세요.
캐시 머니터링: 타 비율, 현재 캐시 크기 및 분당 쓰기 회수를 추적하세요. 타 비율이 30%를 지나 떨어지면 캐시가 비효율적이므로 전략 검토 또는 크기 증가가 필요합니다. Point-Free (2024)에 따르면, 캐시 머니터링은 iOS 애플리케이션 성능 최적화 실천 중 가장 평가가 더받지 모하는 한 가지입니다.
자주 묻는 질문
Disk Cache는 반복 액세스를 가속하기 위해 기기의 디스크에 데이터를 저장하는 기술입니다. iOS의 내장 URLCache는 HTTP 응답을 캐싰하고, 개발자는 Caches 디렉토리를 통해 캠스텀 캐시를 만들 수 있습니다.
RAM Cache(NSCache)는 데이터를 RAM에 저장합니다 — 빠르지만 애플리케이션 재시작 시 손실됩니다. Disk Cache는 느리지만 세션 간에 유지됩니다. 최적의 전략은 두 레벨 모두를 사용합니다: 탁트 데이터에는 메모리, 콘드 데이터에는 디스크.
네, 시스템은 디스크 공간이 부족할 때 언제든지 Caches 디렉토리의 내용을 삭제할 수 있습니다. 따라서 복구할 수 없는 데이터를 캐시에 저장하지 마세요. 사용자 문서에는 Documents 디렉토리를 사용하세요.
캐시 크기는 데이터 유형에 따라 다릅니다: 이미지의 경우 100–500 MB, API 응답의 경우 10–50 MB, 동영상의 경우 최대 1 GB입니다. 타 비율을 모니터링하세요 — 50%이하로 떨어지면 캐시 크기를 늘리거나 무효화 전략을 변경하세요.
URLCache.removeAllCachedResponses()는 내장 캐시를 제거합니다. 캠스텀 캐시의 경우 FileManager를 통해 Caches 디렉토리에서 파일을 삭제하세요. 애플리케이션 설정을 통해 캐시를 지울 수 있는 옵션을 항상 제공하세요.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.