如何在HKStatisticsCollectionQuery中获取productType?遇HKSource报错
问题:访问HKSource的productType时出现编译错误
我在使用HKStatisticsCollectionQuery获取特定数据点来源时,已经开启了separateBySource选项,但尝试访问HKSource的productType属性时,出现编译错误:Value of type 'HKSource' has no member 'productType'。
我的尝试代码如下:
func getDataPointWithTimestamp(statistics:HKStatistics) -> [String:Any?] { let startDate = statistics.startDate let endDate = statistics.endDate var sourceName:String? = "" var sourceBundleIdentifier:String? = "" var productType:String?="" var steps:Double = 0 if(statistics.sources != nil && statistics.sources!.count > 0){ sourceName = statistics.sources![0].name sourceBundleIdentifier = statistics.sources![0].bundleIdentifier productType = statistics.sources![0].productType } if let quantity = statistics.sumQuantity() { steps = quantity.doubleValue(for: HKUnit.count()) } var dataPoint: [String:Any?] = [:] dataPoint["steps"] = steps; dataPoint["start"] = dateToTimestamp(date: startDate) dataPoint["end"] = dateToTimestamp(date: endDate) dataPoint["iosSourceName"] = sourceName; dataPoint["iosSourceBundleIdentifier"] = sourceBundleIdentifier; return dataPoint }
我原本期望productType能像bundleIdentifier一样正常访问,请问我哪里出错了?
问题原因与解决方法
错误原因
HKSource类本身并不包含productType属性,你混淆了HKSource和HKDevice的职责:
HKSource用于标识数据的来源(比如某款健康类APP、苹果健康自身),提供name、bundleIdentifier等属性;- 设备的产品类型(如
iPhone15,1这类硬件标识符)属于HKDevice的属性,它记录了数据产生的硬件设备信息。
正确获取方式
如果需要获取数据对应的设备产品类型,需要从HKSource关联的HKDevice中读取,同时要注意HKDevice可能为nil,必须做可选绑定处理。
修改后的代码示例:
func getDataPointWithTimestamp(statistics:HKStatistics) -> [String:Any?] { let startDate = statistics.startDate let endDate = statistics.endDate var sourceName: String? = "" var sourceBundleIdentifier: String? = "" var productType: String? = "" var steps: Double = 0 if let sources = statistics.sources, !sources.isEmpty { let source = sources[0] sourceName = source.name sourceBundleIdentifier = source.bundleIdentifier // 从HKSource关联的HKDevice中获取productType if let device = source.device { productType = device.productType } } if let quantity = statistics.sumQuantity() { steps = quantity.doubleValue(for: HKUnit.count()) } var dataPoint: [String:Any?] = [:] dataPoint["steps"] = steps dataPoint["start"] = dateToTimestamp(date: startDate) dataPoint["end"] = dateToTimestamp(date: endDate) dataPoint["iosSourceName"] = sourceName dataPoint["iosSourceBundleIdentifier"] = sourceBundleIdentifier dataPoint["iosDeviceProductType"] = productType // 新增设备产品类型字段 return dataPoint }
另外,代码中建议尽量避免强制解包(!),改用可选绑定(if let)来提升代码安全性。
内容的提问来源于stack exchange,提问作者Alfred Siggurdson
相关产品推荐
相关产品推荐

