Skip to content
Back to skills

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
documentationswiftapidocumentation

Works with

  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 112-caching_42b509e6 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 112 Caching 42b509e6?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 112 Caching 42b509e6
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-112-caching-42b509e6/badge)](https://www.skillsdirectory.com/skills/tools-only-112-caching-42b509e6)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# 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

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…