79774389

Date: 2025-09-25 05:31:08
Score: 1
Natty:
Report link

What about passing around CoreData objects (NSManagedObject)? In Xcode 26/Swift 6.2 I'm getting lots of warnings.

For example, user.update(from: fragment) below triggers a warning Capture of 'self' with non-Sendable type 'User' in a '@Sendable' closure in Xcode 26:

class User: NSManagedObject {
  func fetchInfo(with result: UserDetailsQuery.Data) async throws {
    let context: NSManagedObjectContext = MyDataWrapper.shared.backgroundContext

    try await withCheckedThrowingContinuation { continuation in
      context.perform {
        let user = User.find(id: self.id, context: context)

        // 👇 Capture of 'self' with non-Sendable type 'User' in a '@Sendable' closure
        user.update(from: fragment)

        try? context.save()
        continuation.resume()
      }
    }
  }
}

If I replace try await withCheckedThrowingContinuation { ... context.perform { ... } } with a custom NSManagedObject extension called enqueue(•), there is no warning.

class User: NSManagedObject {
  func fetchInfo(with result: UserDetailsQuery.Data) async throws {
    let dbContext: NSManagedObjectContext = MyDataWrapper.shared.backgroundContext

    await dbContext.enqueue { context in
        let user = User.find(id: self.id, context: context)

        user.update(from: fragment) // 👈 no warning

        try? context.save()
      }
    }
  }
}

The enqueue(•) extension:

extension NSManagedObjectContext {
  /// Runs the given block on this context's queue and suspends until it completes
  func enqueue(_ block: @escaping (NSManagedObjectContext) -> Void) async {
    await withCheckedContinuation { continuation in
      perform {
        block(self)
        continuation.resume()
      }
    }
  }
}

How are these two different?

Reasons:
  • Long answer (-1):
  • Has code block (-0.5):
  • Ends in question mark (2):
  • Starts with a question (0.5): What
Posted by: spnkr