问题
I am using CloudKit with Swift for iOS.
I am saving an object of type DateComponents in a CloudKit field of type Bytes. When I retrieve the object, it does not have the same value as the object I originally saved.
Here is the code where I save the object to CloudKit:
let unsafePointer: UnsafePointer<DateComponents> = UnsafePointer<DateComponents>(&time)
let unsafeBufferPointer: UnsafeBufferPointer<DateComponents> = UnsafeBufferPointer<DateComponents>(start: unsafePointer, count: 1)
let data: Data = Data(buffer: unsafeBufferPointer)
privateRecord.setObject(data as CKRecordValue?, forKey: DatabaseNameStrings.fieldTime)
Here is the print result in the debug window:
time = calendar: gregorian (autoupdatingCurrent) timeZone: America/Chicago (autoupdatingCurrent) hour: 12 minute: 0 isLeapMonth: false
Here is the code where I retrieve the object from CloudKit:
if let dataTime = privateRecord.object(forKey: DatabaseNameStrings.fieldTime) as? Data {
let unsafeMutableBufferPointer: UnsafeMutableBufferPointer<DateComponents> = UnsafeMutableBufferPointer<DateComponents>.allocate(capacity: 1)
_ = dataTime.copyBytes(to: unsafeMutableBufferPointer)
print("unsafeMutableBufferPointer.first =", unsafeMutableBufferPointer.first as Any)
privateTime = unsafeMutableBufferPointer.first
}
Here is the print result in the debug window:
unsafeMutableBufferPointer.first = Optional(era: 0 year: 0 month: 0 day: 0 hour: 0 minute: 0 second: 0 nanosecond: 0 weekday: 0 weekdayOrdinal: 0 quarter: 0 weekOfMonth: 0 weekOfYear: 0 yearForWeekOfYear: 0 isLeapMonth: false )
回答1:
Trying to persist a DateComponents
instance is the wrong approach; You have no visibility of the internal structure of the object and this structure could change with Swift or iOS updates.
Your assumption is that you can bypass the initialisation of DateComponents
simply by restoring the bytes that represented some other instance; This is an incorrect assumption.
DateComponents
is actually toll-free bridged to an underlying instance of NSDateComponents
.
When you call UnsafeBufferPointer<DateComponents>(start: unsafePointer, count: 1)
you are accessing the Swift struct that is used to access the underlying NSDateComponents
instance.
When you subsequently try to re-create this struct, that underlying object does not exist and you get 0s.
You should either save the specific fields required to re-create the date components (e.g. timezone, hour etc) or save a Date
object.
来源:https://stackoverflow.com/questions/56998458/why-does-my-datecomponents-object-in-ios-not-save-to-or-retrieve-from-cloudkit-c