Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swift 6 updates #24

Merged
merged 1 commit into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading