Skip to content

Commit

Permalink
Swift 6 updates
Browse files Browse the repository at this point in the history
  • Loading branch information
johnfairh committed Jun 27, 2024
1 parent db6b1a9 commit 722771c
Show file tree
Hide file tree
Showing 19 changed files with 164 additions and 158 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
steps:
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: 15.3
xcode-version: '16.0-beta'
- uses: actions/checkout@v4
- name: Tests
run: xcodebuild build test -project TMLPersistentContainer.xcodeproj -scheme TMLPersistentContainer-macOS -enableCodeCoverage YES
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import PackageDescription

let package = Package(
name: "TMLPersistentContainer",
platforms: [.macOS("10.12")],
platforms: [.macOS("11.0")],
products: [
.library(
name: "TMLPersistentContainer",
Expand Down
4 changes: 2 additions & 2 deletions Sources/MigrationError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//

import Foundation
@preconcurrency import CoreData
import CoreData

/// Errors that can occur preventing persistent store loading, passed into the callback given to
/// `PersistentContainer.loadPersistentStores(...)` or
Expand All @@ -17,7 +17,7 @@ import Foundation
/// one of these errors is to read that text and try to make sense of it.
///
@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
public enum MigrationError: Error {
public enum MigrationError: Error, @unchecked Sendable {

/// The persistent store has not been loaded because another store associated with the persistent
/// container required migration but there was an error attempting to migrate it. To avoid leaving
Expand Down
8 changes: 4 additions & 4 deletions Sources/PersistentCloudKitContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import CoreData
/// See `PersistentContainer` for a version that does not support CloudKit-backed stores.
///
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
open class PersistentCloudKitContainer: NSPersistentCloudKitContainer, PersistentContainerMigratable, PersistentContainerProtocol, LogMessageEmitter {
open class PersistentCloudKitContainer: NSPersistentCloudKitContainer, PersistentContainerMigratable, PersistentContainerProtocol, LogMessageEmitter, @unchecked Sendable {

/// Background queue for running store operations.
let dispatchQueue = DispatchQueue(label: "CloudKitPersistentContainer", qos: .utility)
Expand Down Expand Up @@ -140,10 +140,10 @@ open class PersistentCloudKitContainer: NSPersistentCloudKitContainer, Persisten
/// in this package.
///
open override func loadPersistentStores(completionHandler block: @escaping (NSPersistentStoreDescription, Error?) -> ()) {
let invokeCoreDataClosure = { block in
super.loadPersistentStores(completionHandler: block)
let invokeCoreDataClosure = { (box: CompletionBox) in
super.loadPersistentStores(completionHandler: box.value)
}

loadPersistentStoresHelper(invokeCoreDataClosure: invokeCoreDataClosure, completionHandler: block)
loadPersistentStoresHelper(invokeCoreDataClosure: invokeCoreDataClosure, completionHandler: CompletionBox(block))
}
}
29 changes: 20 additions & 9 deletions Sources/PersistentContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ extension PersistentContainerProtocol {
}
}

func loadPersistentStoresHelper(invokeCoreDataClosure: @escaping ((_ block: @escaping (NSPersistentStoreDescription, Error?) -> ()) -> Void), completionHandler block: @escaping (NSPersistentStoreDescription, Error?) -> ()) {
func loadPersistentStoresHelper(invokeCoreDataClosure: @escaping @Sendable ((_ block: CompletionBox) -> Void), completionHandler block: CompletionBox) {
// Filter out the stores that need loading to replicate the superclass API
// There are probably only a handful at most of these so no need to be terribly efficient
let storeURLs = persistentStoreCoordinator.persistentStores.compactMap(\.url)
Expand Down Expand Up @@ -80,6 +80,8 @@ extension PersistentContainerProtocol {
async || description.shouldAddStoreAsynchronously
}

let uncheckedInvokeCoreDataClosure = UncheckedSendable(invokeCoreDataClosure)

// Helper to deal with the sync/async version....
@Sendable func doStoreMigration() {
var failures = false
Expand All @@ -89,10 +91,10 @@ extension PersistentContainerProtocol {
self.log(.error, "Migration of store \(desc.fileURL) failed, sending user callback - \(error)")
if asyncMode {
DispatchQueue.main.sync {
block(desc, error)
block.value(desc, error)
}
} else {
block(desc, error)
block.value(desc, error)
}
}

Expand All @@ -101,10 +103,10 @@ extension PersistentContainerProtocol {
self.log(.info, "All store migration successful, invoking Core Data.")
if asyncMode {
DispatchQueue.main.async {
invokeCoreDataClosure(block)
uncheckedInvokeCoreDataClosure.value(block)
}
} else {
invokeCoreDataClosure(block)
uncheckedInvokeCoreDataClosure.value(block)
}
}
}
Expand Down Expand Up @@ -141,7 +143,7 @@ extension PersistentContainerProtocol {
/// CloudKit-backed and non-cloud stores..
///
@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
open class PersistentContainer: NSPersistentContainer, PersistentContainerMigratable, PersistentContainerProtocol, LogMessageEmitter {
open class PersistentContainer: NSPersistentContainer, PersistentContainerMigratable, PersistentContainerProtocol, LogMessageEmitter, @unchecked Sendable {

/// Background queue for running store operations.
let dispatchQueue = DispatchQueue(label: "PersistentContainer", qos: .utility)
Expand Down Expand Up @@ -261,10 +263,19 @@ open class PersistentContainer: NSPersistentContainer, PersistentContainerMigrat
/// in this package.
///
open override func loadPersistentStores(completionHandler block: @escaping (NSPersistentStoreDescription, Error?) -> ()) {
let invokeCoreDataClosure = { block in
super.loadPersistentStores(completionHandler: block)
let invokeCoreDataClosure = { (box: CompletionBox) in
super.loadPersistentStores(completionHandler: box.value)
}

loadPersistentStoresHelper(invokeCoreDataClosure: invokeCoreDataClosure, completionHandler: block)
loadPersistentStoresHelper(invokeCoreDataClosure: invokeCoreDataClosure, completionHandler: CompletionBox(block))
}
}

typealias CompletionBox = UncheckedSendable<(NSPersistentStoreDescription, Error?) -> ()>

class UncheckedSendable<T>: @unchecked Sendable {
let value: T
init(_ value: T) {
self.value = value
}
}
Loading

0 comments on commit 722771c

Please sign in to comment.