/*:#localized(key: "MigrationStrategy")
 # A pragmatic migration strategy

 You don't rewrite an app in a weekend, and you shouldn't. Migrate along a
 path that's safe at every step:

 **1. Wrap legacy callbacks at the boundary.**  
 The single highest-leverage
 move. Take a completion-handler API and give it an `async` face using a
 **continuation**. Now everything *above* that wrapper can be modern, while the
 old implementation underneath keeps working untouched:
 */
import Foundation

// Legacy API you don't want to rewrite yet.
func fetchStock(completion: @escaping @Sendable (Result<[String: Int], Error>) -> Void) {
    DispatchQueue.global().async {
        Thread.sleep(forTimeInterval: 0.4)
        completion(.success(["Latte": 3, "Cold brew": 0]))
    }
}

// Modern face over it, the bridge.
func fetchStock() async throws -> [String: Int] {
    try await withCheckedThrowingContinuation { continuation in
        fetchStock { result in
            continuation.resume(with: result)
        }
    }
}
/*:#localized(key: "MigrationStrategy-2")
 **2. Write all *new* code with `async`/`await`.**  
 Stop adding completion
 handlers. New features start modern and call into the wrapped legacy layer
 where needed.

 **3. Replace ad-hoc locking with actors.**  
 Wherever you find a serial queue,
 an `NSLock`, or a count-1 semaphore guarding some shared state, that's a prime
 candidate to become an **actor**. The isolation moves from "every caller must
 remember the rule" to "the compiler enforces it."

 **4. Adopt `@MainActor` for UI.**  
 Annotate your view models and UI-touching
 types with **`@MainActor`**. This deletes a whole category of "I forgot to
 hop back to main" bugs, because the compiler now tracks main-thread-ness for
 you.

 **5. Move toward Swift 6 data-race safety incrementally.**  
 Turn on stricter
 concurrency checking and fix warnings a module at a time. Each warning is the
 compiler pointing at a real (or potential) data race that used to be
 invisible. Treat it as a to-do list, not an emergency. The language mode lets
 you advance gradually rather than all at once.
 
 ---

 The through-line: **modernize at the seams.** Wrap the boundary, build new
 work on the modern side of it, and let the old side shrink over time instead
 of demanding a big-bang rewrite.

 [Previous](@previous)  |  page 6 of 8  |  [Next: Which Tool When](@next)
 */
