Import Unique Object Question #209

Closed
opened 2025-12-29 18:24:23 +01:00 by adam · 5 comments
Owner

Originally created by @ASPetrov on GitHub (Apr 27, 2018).

Hello,

I'd like to kindly ask you could you suggest me any best practice(s) to avoid complex lines like in the following examples?

e.g.

let managedBeacon: CDBeacon! = try! transaction.importUniqueObject(Into(CDBeacon.self), source: beacon)

or

let managedBeacon = (try? transaction.importUniqueObject(Into(CDBeacon.self), source: beacon)) as? CDBeacon

I'm currently using helper function like the following:

@inline(__always) func importHelper<T: ImportableUniqueObject>(_ transaction: AsynchronousDataTransaction, _ source: T.ImportSource) -> T? {
    let object = try? transaction.importUniqueObject(Into(T.self), source: source)
    return object as? T
}

Here is more clear example how I using it:

private func save(_ beacons: [Beacon]) {
    // Helper function only for the needs of the import
    @inline(__always) func importHelper<T: ImportableUniqueObject>(_ transaction: AsynchronousDataTransaction, _ source: T.ImportSource) -> T? {
        let object = try? transaction.importUniqueObject(Into(T.self), source: source)
        return object as? T
    }

    CoreStore.perform(asynchronous: { (transaction) -> Bool in
    // Clear
    for (_, type) in CoreStore.entityTypesByName(for: NSManagedObject.self) {
        transaction.deleteAll(From(type))
    }

    print("Start imorting")

    // Add new data
    for remoteBeacon in beacons {
        // insert beacon
        guard let managedBeacon: CDBeacon = importHelper(transaction, remoteBeacon) else {
            continue
        }
...

Thank you for your time!

Originally created by @ASPetrov on GitHub (Apr 27, 2018). Hello, I'd like to kindly ask you could you suggest me any best practice(s) to avoid complex lines like in the following examples? **e.g.** `let managedBeacon: CDBeacon! = try! transaction.importUniqueObject(Into(CDBeacon.self), source: beacon)` **or** `let managedBeacon = (try? transaction.importUniqueObject(Into(CDBeacon.self), source: beacon)) as? CDBeacon` I'm currently using helper function like the following: ``` @inline(__always) func importHelper<T: ImportableUniqueObject>(_ transaction: AsynchronousDataTransaction, _ source: T.ImportSource) -> T? { let object = try? transaction.importUniqueObject(Into(T.self), source: source) return object as? T } ``` Here is more clear example how I using it: ``` private func save(_ beacons: [Beacon]) { // Helper function only for the needs of the import @inline(__always) func importHelper<T: ImportableUniqueObject>(_ transaction: AsynchronousDataTransaction, _ source: T.ImportSource) -> T? { let object = try? transaction.importUniqueObject(Into(T.self), source: source) return object as? T } CoreStore.perform(asynchronous: { (transaction) -> Bool in // Clear for (_, type) in CoreStore.entityTypesByName(for: NSManagedObject.self) { transaction.deleteAll(From(type)) } print("Start imorting") // Add new data for remoteBeacon in beacons { // insert beacon guard let managedBeacon: CDBeacon = importHelper(transaction, remoteBeacon) else { continue } ... ``` Thank you for your time!
adam added the question label 2025-12-29 18:24:23 +01:00
adam closed this issue 2025-12-29 18:24:24 +01:00
Author
Owner

@JohnEstropia commented on GitHub (May 5, 2018):

I'd like to kindly ask you could you suggest me any best practice(s) to avoid complex lines

The current API is designed in such a way that it's simple without losing any important information, so "complex" here is subjective and it is up to you to decide on the tradeoff you are willing to compromise. To comment on your examples,

e.g.
let managedBeacon: CDBeacon! = try! transaction.importUniqueObject(Into(CDBeacon.self), source: beacon)

or

let managedBeacon = (try? transaction.importUniqueObject(Into(CDBeacon.self), source: beacon)) as? CDBeacon

You are initializing Into with its dynamic initializer, which was made for types with complex inheritance. Instead, you can get rid of the casts by using the generic Into<T>:

let managedBeacon = try? transaction.importUniqueObject(Into<CDBeacon>(), source: beacon))
@JohnEstropia commented on GitHub (May 5, 2018): > I'd like to kindly ask you could you suggest me any best practice(s) to avoid complex lines The current API is designed in such a way that it's simple without losing any important information, so "complex" here is subjective and it is up to you to decide on the tradeoff you are willing to compromise. To comment on your examples, > e.g. > let managedBeacon: CDBeacon! = try! transaction.importUniqueObject(Into(CDBeacon.self), source: beacon) > > or > > let managedBeacon = (try? transaction.importUniqueObject(Into(CDBeacon.self), source: beacon)) as? CDBeacon You are initializing `Into` with its dynamic initializer, which was made for types with complex inheritance. Instead, you can get rid of the casts by using the generic `Into<T>`: ```swift let managedBeacon = try? transaction.importUniqueObject(Into<CDBeacon>(), source: beacon)) ```
Author
Owner

@ASPetrov commented on GitHub (May 7, 2018):

Thank you for your response!

By "complex" I meant that the line length easily exceeds 100 characters and when I'm using tools like SwiftLint I'm getting warnings. But you're right this is subjective.

The only reason I'm using the helper function above instead of:

let managedBeacon = try? transaction.importUniqueObject(Into<CDBeacon>(), source: beacon)

and then

managedBeacon.content = managedBeaconContent

Is to avoid compile errors like this

Value of optional type 'CDBeacon??' not unwrapped; did you mean to use '!' or '?'?

I really hate those ??. :)

@ASPetrov commented on GitHub (May 7, 2018): Thank you for your response! By "complex" I meant that the line length easily exceeds 100 characters and when I'm using tools like SwiftLint I'm getting warnings. But you're right this is subjective. The only reason I'm using the helper function above instead of: > `let managedBeacon = try? transaction.importUniqueObject(Into<CDBeacon>(), source: beacon)` and then `managedBeacon.content = managedBeaconContent` Is to avoid compile errors like this > Value of optional type 'CDBeacon??' not unwrapped; did you mean to use '!' or '?'? I really hate those `??`. :)
Author
Owner

@JohnEstropia commented on GitHub (May 7, 2018):

Why not just call it normally with a plain try? (no exclamation/question mark)

for remoteBeacon in beacons {
    guard let managedBeacon = try transaction.importUniqueObject(Into<CDBeacon>(), source: beacon) else {
        continue
    }
    // ...
}

Also, since you are working with arrays I recommend you use the array version instead of importing one-by-one:

let beacons = try transaction.importUniqueObjects(Into<CDBeacon>(), source: beacons)
@JohnEstropia commented on GitHub (May 7, 2018): Why not just call it normally with a plain `try`? (no exclamation/question mark) ```swift for remoteBeacon in beacons { guard let managedBeacon = try transaction.importUniqueObject(Into<CDBeacon>(), source: beacon) else { continue } // ... } ``` Also, since you are working with arrays I recommend you use the array version instead of importing one-by-one: ```swift let beacons = try transaction.importUniqueObjects(Into<CDBeacon>(), source: beacons) ```
Author
Owner

@ASPetrov commented on GitHub (May 7, 2018):

Thank you! Both of those suggestions make perfect sense.

@ASPetrov commented on GitHub (May 7, 2018): Thank you! Both of those suggestions make perfect sense.
Author
Owner

@JohnEstropia commented on GitHub (May 7, 2018):

I'll close this issue but feel free to reopen if you have further questions :)

@JohnEstropia commented on GitHub (May 7, 2018): I'll close this issue but feel free to reopen if you have further questions :)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore-JohnEstropia#209