Back to skills
SKILL.md
112 Caching 42b509e6
ASecurity| Type | Persistence | Use Case | |------|-------------|----------| | `.default` | Disk cache, cookies | Normal networking | | `.ephemeral` | Memory only | Privacy-sensitive | | `.background(withIdentifier:)` | System-managed | Large transfers |
- 9 stars
- 0 votes
- 0 copies
- 0 views
- Added October 11, 2026
Works with
Security analysis
100/100npx -y skills add tools-only/X-Skills --skill 112-caching_42b509e6 --agent claude-codeAre you the author of 112 Caching 42b509e6?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/tools-only-112-caching-42b509e6)# URLSession Caching and Configuration Reference
## Quick Reference
### URLSessionConfiguration Types
| Type | Persistence | Use Case |
|------|-------------|----------|
| `.default` | Disk cache, cookies | Normal networking |
| `.ephemeral` | Memory only | Privacy-sensitive |
| `.background(withIdentifier:)` | System-managed | Large transfers |
### Cache Policies
| Policy | Behavior | When to Use |
|--------|----------|-------------|
| `.useProtocolCachePolicy` | Follows HTTP headers | Default |
| `.reloadIgnoringLocalCacheData` | Always fetch fresh | Fresh data required |
| `.returnCacheDataElseLoad` | Cache first | Offline-first |
| `.returnCacheDataDontLoad` | Cache only | Strict offline |
### Timeout Defaults
| Property | Default | Typical Setting |
|----------|---------|-----------------|
| `timeoutIntervalForRequest` | 60s | 30-60s |
| `timeoutIntervalForResource` | **7 days** | 2-5 minutes |
### URLCache Sizing
| Type | Default | Recommended |
|------|---------|-------------|
| Memory | 512 KB | 20 MB |
| Disk | 10 MB | 100 MB |
## URLCache Configuration
```swift
// Default cache is too small - configure early in app lifecycle
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
URLCache.shared = URLCache(
memoryCapacity: 20 * 1024 * 1024, // 20 MB
diskCapacity: 100 * 1024 * 1024, // 100 MB
directory: nil
)
return true
}
```
**Cache rules**: Response must be <= 5% of disk cache size to be cached. ([Apple Developer Documentation](https://developer.apple.com/documentation/foundation/urlsessiondatadelegate/urlsession(_:datatask:willcacheresponse:completionhandler:)))
## Session Configuration
### Default Configuration
```swift
let config = URLSessionConfiguration.default
config.timeoutIntervalForRequest = 30.0
config.timeoutIntervalForResource = 300.0 // Not 7 days!
config.waitsForConnectivity = true
let session = URLSession(configuration: config)
```
### Ephemeral (Privacy Mode)
```swift
// No disk persistence - RAM only
let session = URLSession(configuration: .ephemeral)
```
### Background Configuration
```swift
let config = URLSessionConfiguration.background(
withIdentifier: "com.yourapp.backgroundSession"
)
config.isDiscretionary = false // Start immediately
config.sessionSendsLaunchEvents = true
let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
```
## Background Session Implementation
### AppDelegate Handler (Required)
```swift
var backgroundCompletionHandler: (() -> Void)?
func application(_ application: UIApplication,
handleEventsForBackgroundURLSession identifier: String,
completionHandler: @escaping () -> Void) {
backgroundCompletionHandler = completionHandler
}
```
### Delegate Methods
```swift
func urlSession(_ session: URLSession,
downloadTask: URLSessionDownloadTask,
didFinishDownloadingTo location: URL) {
// Move file immediately - location deleted after method returns
try? FileManager.default.moveItem(at: location, to: permanentURL)
}
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
DispatchQueue.main.async {
self.backgroundCompletionHandler?()
self.backgroundCompletionHandler = nil
}
}
```
## Connection Pooling
```swift
// CORRECT: Reuse sessions for HTTP/2 multiplexing
class NetworkService {
static let shared = NetworkService()
private let session = URLSession(configuration: .default)
}
// ANTI-PATTERN: New session per request - loses pooling
func badFetch(_ url: URL) async throws -> Data {
let session = URLSession(configuration: .default) // Bad!
return try await session.data(from: url).0
}
```
## Critical Anti-Patterns
### 1. Memory Leak from Strong Delegate
```swift
// BUG: URLSession retains delegate forever
class LeakyManager {
var session: URLSession!
init() {
session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
}
// deinit never called - memory leak
}
// CORRECT: Invalidate session
class CorrectManager {
var session: URLSession!
init() {
session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
}
deinit {
session.finishTasksAndInvalidate()
}
}
```
### 2. Background Session Identifier Conflicts
```swift
// BUG: Same identifier in app and extension
// Main app
let config = URLSessionConfiguration.background(withIdentifier: "downloads")
// Extension (CONFLICT!)
let config = URLSessionConfiguration.background(withIdentifier: "downloads")
// CORRECT: Unique per process
"com.yourapp.main.downloads"
"com.yourapp.extension.downloads"
```
### 3. Data-Based Background Uploads
```swift
// BUG: Data uploads don't persist in background
backgroundSession.uploadTask(with: request, from: data) // Fails!
// CORRECT: File-based uploads
let fileURL = saveDataToFile(data)
backgroundSession.uploadTask(with: request, fromFile: fileURL)
```
### 4. Completion Handlers in Background Sessions
```swift
// BUG: Completion handlers not called
backgroundSession.dataTask(with: url) { data, _, _ in
// Never executed!
}
// CORRECT: Use delegate methods only
```
### 5. Inadequate Cache Size
```swift
// BUG: Default 512KB memory, 10MB disk - too small
let session = URLSession.shared
// CORRECT: Configure adequate cache
URLCache.shared = URLCache(
memoryCapacity: 20 * 1024 * 1024,
diskCapacity: 100 * 1024 * 1024,
directory: nil
)
```
### 6. Battery Drain from Immediate Transfers
```swift
// ANTI-PATTERN: Non-urgent but immediate
config.isDiscretionary = false // Immediate regardless of conditions
// CORRECT: Let system optimize
config.isDiscretionary = true // Waits for WiFi, charging
```
### 7. Missing Background Event Handler
```swift
// BUG: No handleEventsForBackgroundURLSession
class IncompleteAppDelegate: UIResponder, UIApplicationDelegate {
// App never notified of completion
}
```
### 8. Unresumed Tasks
```swift
// BUG: Task created but never resumed
task = session.dataTask(with: url) { ... }
// MISSING: task.resume()
// Completion handler retained indefinitely
// CORRECT
task.resume() // Always call
```
## Review Questions
### Cache
- [ ] Is URLCache configured with adequate capacity?
- [ ] Is cache configured before network calls?
- [ ] Is ephemeral config used for sensitive data?
### Session Management
- [ ] Are sessions reused (not created per request)?
- [ ] Is session invalidated when done?
- [ ] Are timeouts configured (not 7-day default)?
### Background Sessions
- [ ] Is identifier unique (especially with extensions)?
- [ ] Is `handleEventsForBackgroundURLSession` implemented?
- [ ] Is `urlSessionDidFinishEvents` calling completion handler?
- [ ] Are uploads file-based (not data-based)?
- [ ] Are delegate methods used (not completion handlers)?
- [ ] Is `isDiscretionary` set for non-urgent transfers?
- [ ] Is background session at app level (not ViewController)?
### Memory
- [ ] Is session delegate invalidated to break retain cycle?
- [ ] Are tasks always resumed after creation?
Attribution
Comments
Loading comments…