Swift: Storing states in CoreData with enums

Solution 1:

You can declare your enum as @objc. Then it all automagically works. Here's a snippet from a project I'm working on.

// Defined with @objc to allow it to be used with @NSManaged.
@objc enum AgeType: Int32
{
    case Age                = 0
    case LifeExpectancy     = 1
}

/// The age type, either Age or LifeExpectancy.
@NSManaged var ageType: AgeType

In the Core Data model, ageType is set to type Integer 32.

Solution 2:

You can extract raw Int16 value with .rawValue property of ObjStatus.

// compare
obj.state == ObjStatus.State1.rawValue

// store
obj.state = ObjStatus.State1.rawValue

But you might want to implement stateEnum accessor for it:

class StateFullManagedObject: NSManagedObject {
    @NSManaged var state: Int16
    var stateEnum:ObjStatus {                    //  ↓ If self.state is invalid.
        get { return ObjStatus(rawValue: self.state) ?? .State1 }
        set { self.state = newValue.rawValue }
    }
}

// compare
obj.stateEnum == .State1

// store
obj.stateEnum = .State1

// switch
switch obj.stateEnum {
case .State1:
    //...
case .State2:
    //...
case .State3:
    //...
}

Solution 3:

Xcode 12.5 Swift 5

I am storing the values of multiple Enums in CoreData with CloudKit Database.

There are quite a few precise steps required to get this working correctly. I have set out here what I have learned works well.

Step 1: Define your Enum:

Mark it @objc, public and Int16

@objc
public enum SomeState: Int16 {
    case stateA
    case stateB
    case stateC
}

Step 2: In your xcdatamodeld create an attribute where the Enum value will be stored

The type should be Integer 16

enter image description here

Step 3: In the Data Model Inspector uncheck Optional, and set a default value of 0

This equates to the first index of the Enum.

enter image description here

Step 4: In the Data Model Inspector for the parent Entity, change Class Codegen to Manual/None

enter image description here

Step 5: Create NSManaged Subclass

Click on the Entity name, then from the menu bar select Editor > Create NSManagedObject Subclass. Make sure that the Target is set to your main project. This will create two new files in the project navigator.

MyObject+CoreDataClass.swift

MyObject+CoreDataProperties.swift

Step 6: In the MyObject+CoreDataProperties.swift file change the attribute type from Int16 to your Enum type

extension MyObject {

    @NSManaged public var state: SomeState

}

USAGE:

Setting/updating the value:

myObject.state = .stateA

NSPredicate to search for enum value:

NSPredicate(format: "state = %i", SomeState.stateA.rawValue)