You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 06:11:24