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
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
.
Step 4: In the Data Model Inspector for the parent Entity, change Class Codegen to Manual/None
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)