horst
horst

Reputation: 575

Update CoreData attribute of type Int32

I'd like to get the value of an core data attribute and after getting this object/value I'd like to update it. This is my code:

var numberOfChanges:Int32?
numberOfChanges = theme.valueForKey("numberThemeChanged") as Int32
var newValueThemeChanges:Int32?
newValueThemeChanges = numberOfChanges+1
theme.setValue(newValueThemeChanges, forKey: "numberThemeChanged")

I'm getting the following errors:

  1. Type 'Int32' does not conform to protocol 'AnyObject' in this line of code: numberOfChanges = theme.valueForKey("numberThemeChanged") as Int32.
  2. 'Int32' is not identical to 'AnyObject' in this line of code: theme.setValue(newValueThemeChanges, forKey: "numberThemeChanged")

Do you know how I can do it/what's wrong with my code? Thanks for your answer!

Upvotes: 2

Views: 2289

Answers (1)

Martin R
Martin R

Reputation: 539955

The Key-Value Coding methods

func valueForKey(key: String) -> AnyObject?
func setValue(value: AnyObject?, forKey key: String)

work with values of the type AnyObject, for an integer attribute these are instances of NSNumber.

There is an automatic bridging between Int and NSNumber, but not between Int32 and NSNumber (and this has nothing to do with the fact that you define the property as "Integer 32" in the Core Data model inspector).

You have several options:

  • Simply use a variable of type Int:

    var numChanges = theme.valueForKey("numberThemeChanged") as Int
    numChanges++
    theme.setValue(numChanges, forKey: "numberThemeChanged")
    
  • Use Int32 and convert from and to NSNumber explicitly:

    var numberOfChanges = (theme.valueForKey("numberThemeChanged") as NSNumber).intValue // Int32
    numberOfChanges++
    theme.setValue(NSNumber(int: numberOfChanges), forKey: "numberThemeChanged")
    
  • Use Xcode -> Editor -> Create NSManagedObject subclass ... and check the "Use scalar properties for primitive data types" options. This will give you a managed object subclass with the property

    @NSManaged var numberThemeChanged: Int32
    

    and you can access the property without Key-Value Coding:

    var numberOfChanges = theme.numberThemeChanged
    numberOfChanges++
    theme.numberThemeChanged = numberOfChanges
    

Here is a complete "create-or-update" example:

var theme : Entity!

let request = NSFetchRequest(entityName: "Entity")
var error : NSError?
if let result = context.executeFetchRequest(request, error: &error) as [Entity]? {
    if result.count > 0 {
        // (At least) one object found, set `theme` to the first one:
        theme = result.first!
    } else {
        // No object found, create a new one:
        theme = NSEntityDescription.insertNewObjectForEntityForName("Entity", inManagedObjectContext: context) as Entity
        // Set an initial value:
        theme.setValue(0, forKey: "numberThemeChanged")
    }
} else {
    println("Fetch failed: \(error?.localizedDescription)")
}

// Get value and update value:
var numChanges = theme.valueForKey("numberThemeChanged") as Int
numChanges++
theme.setValue(numChanges, forKey: "numberThemeChanged")

// Save context:
if !context.save(&error) {
    println("Save failed: \(error?.localizedDescription)")
}

println(numChanges)

Upvotes: 4

Related Questions