Skip to content

Commit

Permalink
Add v8 migration guide
Browse files Browse the repository at this point in the history
  • Loading branch information
onevcat committed Mar 23, 2024
1 parent fcec3f1 commit 6e956a8
Showing 1 changed file with 171 additions and 0 deletions.
171 changes: 171 additions & 0 deletions Sources/Documentation.docc/MigrationGuide/Migration-To-8.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# Migrating from v7 to v8

This guide assists you in updating Kingfisher from version 7 to version 8.

## Overview

Kingfisher 8.0 introduces breaking changes from its predecessor. This document highlights the major updates and significant API modifications.

## Deployment Target

Starting with Kingfisher 8.0, the minimum supported versions are:

- iOS 13.0
- macOS 10.15
- tvOS 13.0
- watchOS 6.0
- visionOS 1.0

## Migration Steps and Insights

First, ensure there are no existing warnings from Kingfisher. Several deprecated methods and properties have been removed in version 8.

For the breaking changes, review the sections below for any utilized features and symbols.

### Disk Cache Changes

Version 8 updates the disk cache hash calculation method, invalidating existing caches. Kingfisher's disk cache is resilient, automatically re-downloading and caching data if missing. Typically, no action is required unless your application's logic heavily relies on disk cache, which is generally not recommended.

### Swift Concurrency APIs

Kingfisher now embraces Swift's `async` keyword, enhancing most asynchronous APIs previously implemented with completion handlers. While the traditional APIs remain in struct and class types, some protocol methods have transitioned to `async` without the traditional ones.

Ensure your implementations conform to these changes.

#### `ImageDownloadRedirectHandler` Protocol

The `handleHTTPRedirection(for:response:newRequest:completionHandler:)` method has been replaced with an asynchronous counterpart. Update your implementation accordingly:

```swift
// Old
extension YourType: ImageDownloadRedirectHandler {
func handleHTTPRedirection(
for task: Kingfisher.SessionDataTask,
response: HTTPURLResponse,
newRequest: URLRequest,
completionHandler: @escaping (URLRequest?) -> Void
) {
// Do something with the result, potentially in async way
requestUpdater.update(newRequest) { result in
completionHandler(result)
}
}
}
```

```swift
// New
extension YourType: ImageDownloadRedirectHandler {
func handleHTTPRedirection(
for task: Kingfisher.SessionDataTask,
response: HTTPURLResponse,
newRequest: URLRequest
) async -> URLRequest? {
let result = await requestUpdater.update(newRequest)
return result
}
}
```

#### `AsyncImageDownloadRequestModifier` Protocol

The `modified(for:reportModified:)` method is now asynchronous. Reimplement it if used:

```swift
// Old
extension YourType: AsyncImageDownloadRequestModifier {
func modified(for request: URLRequest, reportModified: @escaping (URLRequest?) -> Void) {
reportModified(request)
}
}
```

```swift
// New
extension YourType: AsyncImageDownloadRequestModifier {
func modified(for request: URLRequest) async -> URLRequest? {
return request
}
}
```

#### `AuthenticationChallengeResponsible` Protocol

The following methods have been updated to async versions:

- `downloader(_:didReceive:completionHandler:)`
- `downloader(_:task:didReceive:completionHandler:)`

Ensure your implementation is current:

```swift
// Old
extension YourType: AuthenticationChallengeResponsible {
func downloader(
_ downloader: ImageDownloader,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
)
{
generateCredential { credential in
completionHandler(.useCredential, credential)
}
}

func downloader(
_ downloader: ImageDownloader,
task: URLSessionTask,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
)
{
generateCredential { credential in
completionHandler(.useCredential, credential)
}
}
}
```

```swift
// New
extension YourType: AuthenticationChallengeResponsible {
func downloader(
_ downloader: ImageDownloader,
didReceive challenge: URLAuthenticationChallenge
) async -> (URLSession.AuthChallengeDisposition, URLCredential?)
{
let credential = await generateCredential()
return (.useCredential, credential)
}

func downloader(
_ downloader: ImageDownloader,
task: URLSessionTask,
didReceive challenge: URLAuthenticationChallenge
) async -> (URLSession.AuthChallengeDisposition, URLCredential?)
{
let credential = await generateCredential()
return (.useCredential, credential)
}
}
```

### Type Adjustments

#### `ColorElement`

`Filter.ColorElement` has evolved from a typealias for a tuple to a `struct`. Instantiate `ColorElement` using its initializer:

```swift
let brightness, contrast, saturation, inputEV: CGFloat

// Old
let colorElement: Filter.ColorElement = (brightness, contrast, saturation, inputEV)

// New
let colorElement = Filter.ColorElement(brightness, contrast, saturation, inputEV)
```

#### `DownloadTask`

`DownloadTask` has been redefined as a `class` instead of a `struct`, without further API modifications.

0 comments on commit 6e956a8

Please sign in to comment.