为什么我的iOS中的DateComponents对象无法正确保存到CloudKit或从CloudKit中正确检索?

时间:2019-07-11 23:22:32

标签: ios swift nsdata cloudkit nsdatecomponents

我将CloudKit与iOS的Swift结合使用。

我将类型为DateComponents的对象保存在字节类型的CloudKit字段中。检索对象时,它的值与我最初保存的对象的值不同。

这是将对象保存到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)

这是调试窗口中的打印结果:

  

时间=日历:gregorian(autoupdatingCurrent)timeZone:美国/芝加哥(autoupdatingCurrent)小时:12分钟:0 isLeapMonth:false

这是我从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
}

这是调试窗口中的打印结果:

  

unsafeMutableBufferPointer.first =可选(ERA:0年:0个月:0天:0小时:0分钟:0秒:0纳秒:0工作日:0工作日常规:0季度:0 weekOfMonth:0 weekOfYear:0 yearForWeekOfYear: 0 isLeapMonth:false)

1 个答案:

答案 0 :(得分:1)

尝试持久保存DateComponents实例是错误的方法;您没有对象的内部结构的可见性,并且此结构可能会随着Swift或iOS更新而改变。

您的假设是,只需恢复代表其他实例的字节,即可绕过DateComponents的初始化;这是一个错误的假设。

DateComponents实际上是免费电话桥接到NSDateComponents的基础实例。

调用UnsafeBufferPointer<DateComponents>(start: unsafePointer, count: 1)时,您正在访问用于访问基础NSDateComponents实例的Swift结构。

当您随后尝试重新创建此结构时,该基础对象不存在,并且得到0。

您应该保存重新创建日期成分所需的特定字段(例如,时区,小时等),或保存Date对象。