Joshua Hart
Joshua Hart

Reputation: 850

How do you store an UInt64 in CoreData?

My understanding is that a UInt64 can be any value from: 0 to 18446744073709551615

I need to save a UInt64 identifier to CoreData, however the values I see are:

enter image description here

I initially tried Integer 64 but now I am understanding that has a range of: -9223372036854775808 to 9223372036854775807

Do developers usually store an UInt64 as a String and do conversions between the two types? Is this the best practice?

Upvotes: 2

Views: 780

Answers (2)

JeremySom
JeremySom

Reputation: 256

The accepted answer by Martin R will work.

However it appears that this is part of the default implementation of @NSManaged properties by Apple.

I tested it like so:

  1. I created a new Xcode project with Core Data and made a single Entity called Hello.
  2. It has a single attribute called short which is saved as an Integer 16.
  3. Marked Codegen as Manual/None
  4. Created the manual class file for Hello as follows:
class Hello: NSManagedObject {
    @NSManaged var short : UInt16
}

You'll notice that I've typed it as an unsigned UInt16.

In my AppDelegate:

func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Get Context
        let context = self.persistentContainer.viewContext

        // Create Test Objects
        let hello1 = Hello(entity: Hello.entity(), insertInto: context)
        hello1.short = 255
        let hello2 = Hello(entity: Hello.entity(), insertInto: context)
        hello2.short = 32767 // Should overflow Int16
        let hello3 = Hello(entity: Hello.entity(), insertInto: context)
        hello3.short = 65535 // Should overflow Int16 by a lot

        // Save them to the database
        do {
            try context.save()
        } catch {
            print(error)
        }
        
        // Fetch the save objects
        let fetch = NSFetchRequest<Hello>(entityName: "Hello")
        if let results = try? context.fetch(fetch) {
            for result in results {
                print(result.short)
            }
        }
    }

This prints out the following:

255
32767
65535

Which I imagine is what someone would want from saving unsigned ints in Core Data.

Upvotes: 2

Martin R
Martin R

Reputation: 540135

You can (losslessly) convert between UInt64 and Int64:

// Set:
obj.int64Property = Int64(bitPattern: uint64Value)

// Get:
let uint64Value = UInt64(bitPattern: obj.int64Property)

You can define uint64Value as a computed property of the managed object class to automate the conversion:

@objc(MyEntity)
public class MyEntity: NSManagedObject {
    
    public var uint64Property: UInt64 {
        get {
            return UInt64(bitPattern: int64Property)
        }
        set {
            int64Property = Int64(bitPattern: newValue)
        }
    }
}

Upvotes: 5

Related Questions