Carekit 数据是否已损坏?
Is the Carekit data corrupted?
我正在将 carekit 收集的数据发送到 firebase。
firebase(ex.updateDate) 中的日期是浮动的。
云 Firestore:
{"updatedAt":"2021-07-11 06:28:22.420435 UTC","revisions":[{"knowledgeVector":
{"processes":[{"clock":"34","id":"3353F0B6-8B59-4B86-B4AD-A74EE76DCD93","__key__":
{"namespace":"","app":"","path":""}}],"__key__":
{"namespace":"","app":"","path":""}},"entities":[{"type":"task","object":
{"instructions":"Tap the button below anytime you experience nausea.","schemaVersion":
{"majorVersion":"2","patchNumber":"4","minorVersion":"0","__key__":
{"namespace":"","app":"","path":""}},"timezone":{"identifier":"Asia/Tokyo","__key__":
{"namespace":"","app":"","path":""}},"updatedDate":646268927.410913,"title":"Track your
nausea!!","uuid":"1942E91C-F0C3-410D-9D06-F5F6B3859D0E","schedule":{"elements":
[{"start":"645980400","duration":{"isAllDay":true,"__key__":
{"namespace":"","app":"","path":""}},"interval":
{"weekOfYear":"0","year":"0","second":"0","minute":"0","hour":"0","month":"0","day":"1","
__key__":{"namespace":"","app":"","path":""}},"text":"Anytime throughout the
day","__key__":{"namespace":"","app":"","path":""}}],"__key__":
{"namespace":"","app":"","path":""}},"createdDate":646268927.410907,"id":"nausea","impact
sAdherence":false,"effectiveDate":
{"integer":"645980400","provided":"integer"},"phoneNumbers":[],"messagingNumbers":
[],"emailAddresses":[],"values":[],"__key__":
{"namespace":"","app":"","path":""}},"__key__":{"namespace":"","app":"","path":""}},
{"type":"task","object":{"instructions":"Peform Pelvic Gymnastics 5times for 10 Seconds
Each Time.","schemaVersion":
{"majorVersion":"2","patchNumber":"4","minorVersion":"0","__key__":
{"namespace":"","app":"","path":""}},"timezone":{"identifier":"Asia/Tokyo","__key__":
{"namespace":"","app":"","path":""}},"updatedDate":646268927.42012,"title":
在carekit数据输出到日志的代码如下,日期是时间戳。
日志(称为 revisions 的变量的内容,在向 Firebase 发送和接收患者事件时交换。):
[CareKitStore.OCKRevisionRecord(entities:
[CareKitStore.OCKEntity.task(CareKitStore.OCKTask(carePlanUUID: nil, id: "nausea", title:
Optional("Track your incontinence!!"), instructions: Optional("Tap the button below
anytime you experience nausea."), impactsAdherence: false, schedule:
CareKitStore.OCKSchedule(elements: [CareKitStore.OCKScheduleElement(text: Optional("Anytime throughout the day"), duration: CareKitStore.OCKScheduleElement.Duration.allDay, start: 2021-08-12 15:00:00 +0000, end: nil, interval: year: 0 month: 0 day: 1 hour: 0 minute: 0 second: 0 weekOfYear: 0 isLeapMonth: false , targetValues: [])]), groupIdentifier: nil, tags: nil, effectiveDate: 2021-08-12 15:00:00 +0000, deletedDate: nil, uuid: Optional(E6D112BD-0E9F-430F-BF9C-4CE5D69BAC54), nextVersionUUID: nil, previousVersionUUID: nil, createdDate: Optional(2021-08-15 23:28:52 +0000), updatedDate: Optional(2021-08-15 23:28:52 +0000), schemaVersion: Optional(2.0.4), remoteID: nil, source: nil, userInfo: nil, asset: nil, notes: Optional([]), timezone: Asia/Tokyo (current))),
我用下面的代码得到了修改的内容
extension CKCareKitRemoteSyncWithFirestore {
fileprivate func putRevisionInFirestore(deviceRevision: OCKRevisionRecord, _ overwriteRemote: Bool, _ completion: @escaping (Error?) -> Void) {
do {
let data = try JSONEncoder().encode(deviceRevision)
let json = try CKSendHelper.jsonDataAsDict(data) ?? [String:Any]()
CKSendHelper.appendCareKitArrayInFirestore(json: json, collection: collection, withIdentifier: identifier, overwriteRemote: overwriteRemote) { (success, error) in
print("[putRevisionInFirestore] success \(success), error \(error?.localizedDescription ?? "")")
completion(error)
}
} catch {
print("[putRevisionInFirestore] " + error.localizedDescription)
completion(error)
}
}
fileprivate func getRevisionsFromFirestore(completion: @escaping (_ revisions: [OCKRevisionRecord]) -> Void) {
CKSendHelper.getFromFirestore(collection: collection, identifier: identifier, onCompletion: { (document, error) in
guard let document = document,
let payload = document.data()?["revisions"] else {
completion([OCKRevisionRecord]())
return
}
do {
let jsonData = try JSONSerialization.data(withJSONObject: payload, options: [])
let revisions = try JSONDecoder().decode([OCKRevisionRecord].self, from: jsonData)
completion(revisions)
print(revisions)
} catch {
print("[getRevisionsFromFirestore] ERROR " + error.localizedDescription)
completion([OCKRevisionRecord]())
}
})
}
fileprivate func createPullMergeRevisionRecord(_ revisions: [OCKRevisionRecord], _ knowledgeVector: OCKRevisionRecord.KnowledgeVector) -> OCKRevisionRecord {
let newEntities = revisions.filter({ [=12=].knowledgeVector >= knowledgeVector }).flatMap({ [=12=].entities })
var allKnowledge = OCKRevisionRecord.KnowledgeVector()
for rev in revisions.map({ [=12=].knowledgeVector }) {
allKnowledge.merge(with: rev)
}
let newRecord = OCKRevisionRecord(entities: newEntities, knowledgeVector: allKnowledge)
return newRecord
}
fileprivate func createPushMergeRevisionRecord(_ revisions: [OCKRevisionRecord], _ knowledgeVector: OCKRevisionRecord.KnowledgeVector) -> OCKRevisionRecord {
let newEntities = revisions.filter({ knowledgeVector >= [=12=].knowledgeVector }).flatMap({ [=12=].entities })
var allKnowledge = knowledgeVector
for rev in revisions.map({ [=12=].knowledgeVector }) {
allKnowledge.merge(with: rev)
}
let newRecord = OCKRevisionRecord(entities: newEntities, knowledgeVector: allKnowledge)
return newRecord
}
}
我尝试使用以下查询 (BigQuery) 将此浮点日期数据转换为时间戳,但它不正确。
还有其他好的解决办法吗?
提前致谢。
SELECT FORMAT_TIMESTAMP("%Y-%m-%d %H:%M:%S", TIMESTAMP_SECONDS(CAST(updatedDate as INT64)), "Asia/Tokyo") as formatted FROM `@@@`
Gourav B,感谢您的回复。我解决了。
按照你的建议,在上面代码的“putRevisionInFirestore”函数中,我把原始数据“deviceRevision”和“json”把“deviceRevision”转换成json日志。
因此,前者的日期数据是正确的timestamp,后者是float。
因此,我猜测是json的编码部分有问题,在putRevisionInFirestore中指定了如下所示的编码策略,firebase上的日期数据由float变成了正确的时间戳。
感谢您的帮助!
fileprivate func putRevisionInFirestore(deviceRevision: OCKRevisionRecord, _ overwriteRemote: Bool, _ completion: @escaping (Error?) -> Void) {
do {let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
let data = try encoder.encode(deviceRevision)
let json = try CKSendHelper.jsonDataAsDict(data) ?? [String:Any]()
CKSendHelper.appendCareKitArrayInFirestore(json: json, collection: collection, withIdentifier: identifier, overwriteRemote: overwriteRemote) { (success, error) in
print("[putRevisionInFirestore] success \(success), error \(error?.localizedDescription ?? "")")
print("[putRevisionInFirestore_deviceRevision]",deviceRevision)
print("[putRevisionInFirestore_json]",json)
completion(error)
}
} catch {
print("[putRevisionInFirestore] " + error.localizedDescription)
completion(error)
}
}
我正在将 carekit 收集的数据发送到 firebase。 firebase(ex.updateDate) 中的日期是浮动的。
云 Firestore:
{"updatedAt":"2021-07-11 06:28:22.420435 UTC","revisions":[{"knowledgeVector":
{"processes":[{"clock":"34","id":"3353F0B6-8B59-4B86-B4AD-A74EE76DCD93","__key__":
{"namespace":"","app":"","path":""}}],"__key__":
{"namespace":"","app":"","path":""}},"entities":[{"type":"task","object":
{"instructions":"Tap the button below anytime you experience nausea.","schemaVersion":
{"majorVersion":"2","patchNumber":"4","minorVersion":"0","__key__":
{"namespace":"","app":"","path":""}},"timezone":{"identifier":"Asia/Tokyo","__key__":
{"namespace":"","app":"","path":""}},"updatedDate":646268927.410913,"title":"Track your
nausea!!","uuid":"1942E91C-F0C3-410D-9D06-F5F6B3859D0E","schedule":{"elements":
[{"start":"645980400","duration":{"isAllDay":true,"__key__":
{"namespace":"","app":"","path":""}},"interval":
{"weekOfYear":"0","year":"0","second":"0","minute":"0","hour":"0","month":"0","day":"1","
__key__":{"namespace":"","app":"","path":""}},"text":"Anytime throughout the
day","__key__":{"namespace":"","app":"","path":""}}],"__key__":
{"namespace":"","app":"","path":""}},"createdDate":646268927.410907,"id":"nausea","impact
sAdherence":false,"effectiveDate":
{"integer":"645980400","provided":"integer"},"phoneNumbers":[],"messagingNumbers":
[],"emailAddresses":[],"values":[],"__key__":
{"namespace":"","app":"","path":""}},"__key__":{"namespace":"","app":"","path":""}},
{"type":"task","object":{"instructions":"Peform Pelvic Gymnastics 5times for 10 Seconds
Each Time.","schemaVersion":
{"majorVersion":"2","patchNumber":"4","minorVersion":"0","__key__":
{"namespace":"","app":"","path":""}},"timezone":{"identifier":"Asia/Tokyo","__key__":
{"namespace":"","app":"","path":""}},"updatedDate":646268927.42012,"title":
在carekit数据输出到日志的代码如下,日期是时间戳。
日志(称为 revisions 的变量的内容,在向 Firebase 发送和接收患者事件时交换。):
[CareKitStore.OCKRevisionRecord(entities:
[CareKitStore.OCKEntity.task(CareKitStore.OCKTask(carePlanUUID: nil, id: "nausea", title:
Optional("Track your incontinence!!"), instructions: Optional("Tap the button below
anytime you experience nausea."), impactsAdherence: false, schedule:
CareKitStore.OCKSchedule(elements: [CareKitStore.OCKScheduleElement(text: Optional("Anytime throughout the day"), duration: CareKitStore.OCKScheduleElement.Duration.allDay, start: 2021-08-12 15:00:00 +0000, end: nil, interval: year: 0 month: 0 day: 1 hour: 0 minute: 0 second: 0 weekOfYear: 0 isLeapMonth: false , targetValues: [])]), groupIdentifier: nil, tags: nil, effectiveDate: 2021-08-12 15:00:00 +0000, deletedDate: nil, uuid: Optional(E6D112BD-0E9F-430F-BF9C-4CE5D69BAC54), nextVersionUUID: nil, previousVersionUUID: nil, createdDate: Optional(2021-08-15 23:28:52 +0000), updatedDate: Optional(2021-08-15 23:28:52 +0000), schemaVersion: Optional(2.0.4), remoteID: nil, source: nil, userInfo: nil, asset: nil, notes: Optional([]), timezone: Asia/Tokyo (current))),
我用下面的代码得到了修改的内容
extension CKCareKitRemoteSyncWithFirestore {
fileprivate func putRevisionInFirestore(deviceRevision: OCKRevisionRecord, _ overwriteRemote: Bool, _ completion: @escaping (Error?) -> Void) {
do {
let data = try JSONEncoder().encode(deviceRevision)
let json = try CKSendHelper.jsonDataAsDict(data) ?? [String:Any]()
CKSendHelper.appendCareKitArrayInFirestore(json: json, collection: collection, withIdentifier: identifier, overwriteRemote: overwriteRemote) { (success, error) in
print("[putRevisionInFirestore] success \(success), error \(error?.localizedDescription ?? "")")
completion(error)
}
} catch {
print("[putRevisionInFirestore] " + error.localizedDescription)
completion(error)
}
}
fileprivate func getRevisionsFromFirestore(completion: @escaping (_ revisions: [OCKRevisionRecord]) -> Void) {
CKSendHelper.getFromFirestore(collection: collection, identifier: identifier, onCompletion: { (document, error) in
guard let document = document,
let payload = document.data()?["revisions"] else {
completion([OCKRevisionRecord]())
return
}
do {
let jsonData = try JSONSerialization.data(withJSONObject: payload, options: [])
let revisions = try JSONDecoder().decode([OCKRevisionRecord].self, from: jsonData)
completion(revisions)
print(revisions)
} catch {
print("[getRevisionsFromFirestore] ERROR " + error.localizedDescription)
completion([OCKRevisionRecord]())
}
})
}
fileprivate func createPullMergeRevisionRecord(_ revisions: [OCKRevisionRecord], _ knowledgeVector: OCKRevisionRecord.KnowledgeVector) -> OCKRevisionRecord {
let newEntities = revisions.filter({ [=12=].knowledgeVector >= knowledgeVector }).flatMap({ [=12=].entities })
var allKnowledge = OCKRevisionRecord.KnowledgeVector()
for rev in revisions.map({ [=12=].knowledgeVector }) {
allKnowledge.merge(with: rev)
}
let newRecord = OCKRevisionRecord(entities: newEntities, knowledgeVector: allKnowledge)
return newRecord
}
fileprivate func createPushMergeRevisionRecord(_ revisions: [OCKRevisionRecord], _ knowledgeVector: OCKRevisionRecord.KnowledgeVector) -> OCKRevisionRecord {
let newEntities = revisions.filter({ knowledgeVector >= [=12=].knowledgeVector }).flatMap({ [=12=].entities })
var allKnowledge = knowledgeVector
for rev in revisions.map({ [=12=].knowledgeVector }) {
allKnowledge.merge(with: rev)
}
let newRecord = OCKRevisionRecord(entities: newEntities, knowledgeVector: allKnowledge)
return newRecord
}
}
我尝试使用以下查询 (BigQuery) 将此浮点日期数据转换为时间戳,但它不正确。 还有其他好的解决办法吗? 提前致谢。
SELECT FORMAT_TIMESTAMP("%Y-%m-%d %H:%M:%S", TIMESTAMP_SECONDS(CAST(updatedDate as INT64)), "Asia/Tokyo") as formatted FROM `@@@`
Gourav B,感谢您的回复。我解决了。
按照你的建议,在上面代码的“putRevisionInFirestore”函数中,我把原始数据“deviceRevision”和“json”把“deviceRevision”转换成json日志。
因此,前者的日期数据是正确的timestamp,后者是float。
因此,我猜测是json的编码部分有问题,在putRevisionInFirestore中指定了如下所示的编码策略,firebase上的日期数据由float变成了正确的时间戳。
感谢您的帮助!
fileprivate func putRevisionInFirestore(deviceRevision: OCKRevisionRecord, _ overwriteRemote: Bool, _ completion: @escaping (Error?) -> Void) {
do {let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
let data = try encoder.encode(deviceRevision)
let json = try CKSendHelper.jsonDataAsDict(data) ?? [String:Any]()
CKSendHelper.appendCareKitArrayInFirestore(json: json, collection: collection, withIdentifier: identifier, overwriteRemote: overwriteRemote) { (success, error) in
print("[putRevisionInFirestore] success \(success), error \(error?.localizedDescription ?? "")")
print("[putRevisionInFirestore_deviceRevision]",deviceRevision)
print("[putRevisionInFirestore_json]",json)
completion(error)
}
} catch {
print("[putRevisionInFirestore] " + error.localizedDescription)
completion(error)
}
}