Cannot upsert a value #211

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

Originally created by @tosbaha on GitHub (May 10, 2018).

I am trying to do basic operation and it is just doesn't work. I am directly copy pasting code from Readme.

@objc(CourierCD)
class CourierCD: NSManagedObject {
    @NSManaged var slug: String
    @NSManaged var counter: NSNumber
}

        Storage.stack.perform(
            asynchronous: { (transaction) -> Void in
                let person = transaction.fetchOne(
                    From<CourierCD>()
                        .where(\.slug == "something")
                )
                person.counter = person.counter + 1
        },
            completion: { _ in }
        )

I get following error,

Value of optional type 'CourierCD?' not unwrapped.

Ok lets unwrap it

            person!.counter = person!.counter + 1

Binary operator '+' cannot be applied to operands of type 'NSNumber' and 'Int'

Ok lets try with NSNumber

            person!.counter = person!.counter + NSNumber(value: 1)

Cannot convert value of type 'NSNumber' to expected argument type 'Self'

What is the correct way to upsert a value?

In CoreData model editor, slug is set as string, counter is sat as Decimal.

Originally created by @tosbaha on GitHub (May 10, 2018). I am trying to do basic operation and it is just doesn't work. I am directly copy pasting code from Readme. ```swift @objc(CourierCD) class CourierCD: NSManagedObject { @NSManaged var slug: String @NSManaged var counter: NSNumber } Storage.stack.perform( asynchronous: { (transaction) -> Void in let person = transaction.fetchOne( From<CourierCD>() .where(\.slug == "something") ) person.counter = person.counter + 1 }, completion: { _ in } ) ``` I get following error, > Value of optional type 'CourierCD?' not unwrapped. Ok lets unwrap it person!.counter = person!.counter + 1 > Binary operator '+' cannot be applied to operands of type 'NSNumber' and 'Int' Ok lets try with NSNumber person!.counter = person!.counter + NSNumber(value: 1) > Cannot convert value of type 'NSNumber' to expected argument type 'Self' What is the correct way to upsert a value? In CoreData model editor, slug is set as string, counter is sat as Decimal.
adam added the question label 2025-12-29 18:24:25 +01:00
adam closed this issue 2025-12-29 18:24:25 +01:00
Author
Owner

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

Your counter property is an NSNumber, so you need to unbox if first:

if let person = person {
    person.counter = NSNumber(value: person.counter.intValue + 1)
}

Personally, I would recommend to just set counter to Int:

@NSManaged var counter: Int
@JohnEstropia commented on GitHub (May 11, 2018): Your `counter` property is an `NSNumber`, so you need to unbox if first: ```swift if let person = person { person.counter = NSNumber(value: person.counter.intValue + 1) } ``` Personally, I would recommend to just set `counter` to `Int`: ```swift @NSManaged var counter: Int ```
Author
Owner

@tosbaha commented on GitHub (May 11, 2018):

Thanks again. I guess my mistake was setting counter to Decimal. I set it up as Int32 in Model editor, and Int the class, and it worked. You can close the issue.

PS: Maybe it is also good idea to change documentation for updating because query returns an optional. Here is my upsert code for simple counter increase

Storage.stack.perform(
    asynchronous: { (transaction) -> Void in
        if let person = transaction.fetchOne(
            From<CourierCD>()
                .where(\.slug == slug)
            ) {
            person.counter = person.counter + 1
        } else {
            let person = transaction.create(Into<CourierCD>())
            person.slug = slug
            person.counter = 1
        }
},
    completion: { _ in }
)

@tosbaha commented on GitHub (May 11, 2018): Thanks again. I guess my mistake was setting counter to Decimal. I set it up as Int32 in Model editor, and Int the class, and it worked. You can close the issue. PS: Maybe it is also good idea to change documentation for updating because query returns an optional. Here is my upsert code for simple counter increase ```swift Storage.stack.perform( asynchronous: { (transaction) -> Void in if let person = transaction.fetchOne( From<CourierCD>() .where(\.slug == slug) ) { person.counter = person.counter + 1 } else { let person = transaction.create(Into<CourierCD>()) person.slug = slug person.counter = 1 } }, completion: { _ in } ) ```
Author
Owner

@JohnEstropia commented on GitHub (Jun 10, 2018):

I'm closing this issue for now. I'm planning to change fetches and queries to be throws functions instead of returning an optional in the future.

@JohnEstropia commented on GitHub (Jun 10, 2018): I'm closing this issue for now. I'm planning to change fetches and queries to be `throws` functions instead of returning an optional in the future.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore-JohnEstropia#211