iOS 16+中如何实现CloudKit查询操作?已弃用API替代方案
iOS 16及以上版本替代CKQueryOperation弃用回调的方案
在iOS 16及之后版本中,CloudKit的CKQueryOperation弃用了recordFetchedBlock和queryCompletionBlock,官方推荐使用recordMatchedBlock和resultBlock替代,以下是适配原有业务逻辑的完整实现:
// 假设已提前定义好CKQuery实例query,以及features数组、completion回调等变量 let queryOperation = CKQueryOperation(query: query) queryOperation.resultsLimit = CKQueryOperation.maximumResults // 替代原recordFetchedBlock的新回调 queryOperation.recordMatchedBlock = { recordID, result in switch result { case .success(let record): guard let location = record["location1"] as? CLLocation else { return } var hideEvent = false if let takeaway = record["host"] as? String { // 简化屏蔽检查逻辑 hideEvent = self.blockedFeed.contains(takeaway) || self.blockedFeeder.contains(takeaway) if !hideEvent { let identified = record.recordID.recordName let category = record["type"] as? String ?? "defaultCategory" let feature = """ { "type": "Feature", "properties": { "category": "\(category)", "recordID": "\(identified)" }, "geometry": { "type": "Point", "coordinates": [\(location.coordinate.longitude), \(location.coordinate.latitude)] } } """ features.append(feature) } } case .failure(let error): print("匹配单条记录失败: \(error)") } } // 替代原queryCompletionBlock的新回调 queryOperation.resultBlock = { [weak self] result in guard let self = self else { return } switch result { case .success(let queryResult): switch queryResult { case .cursor(let cursor): // 处理分页,创建新的游标查询操作 let newOperation = CKQueryOperation(cursor: cursor) newOperation.resultsLimit = CKQueryOperation.maximumResults newOperation.recordMatchedBlock = queryOperation.recordMatchedBlock newOperation.resultBlock = queryOperation.resultBlock publicDB.add(newOperation) case .results(_): // 所有数据查询完成,生成GeoJSON并回调 let geoJSONString = """ { "type": "FeatureCollection", "features": [\(features.joined(separator: ","))] } """ completion(geoJSONString.data(using: .utf8)) } case .failure(let error): print("查询操作整体失败: \(error)") completion(nil) // 根据业务需求处理错误回调 } } publicDB.add(queryOperation)
关键变化说明
- 回调结构升级:新回调通过
Result枚举封装成功/失败状态,强制开发者处理错误场景,比原block更健壮 - 分页逻辑适配:原有的游标分页逻辑基本保留,但需使用新的
resultBlock判断是否存在后续数据 - 代码简化:将原有的循环检查屏蔽列表逻辑替换为
contains方法,提升代码简洁度
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

