如何通过枚举属性使用新#Predicate宏进行数据查询?
在Xcode 15 Beta 4中使用#Predicate宏查询Core Data枚举属性的问题
问题背景
使用Xcode 15 Beta 4,尝试通过新的#Predicate宏查询带有枚举属性的Core Data模型时出现编译错误,两种查询写法均失败:
查询写法1
let predicate = #Predicate<ModelA> { $0.type == ModelA.ModelAType.a }
查询写法2
let predicate = #Predicate<ModelA> { $0.type.rawValue == ModelA.ModelAType.a.rawValue }
模型定义
@Model final class ModelA: Codable { @Attribute(.unique) var id: Int64 = 0 enum ModelAType: Int, CaseIterable, Codable { case a = 1, b } var type: ModelAType = ModelAType.a }
报错信息
Type 'ModelA.Type' cannot conform to 'StandardPredicateExpression' Type 'ModelA.Type' cannot conform to 'PredicateExpression' Cannot infer key path type from context; consider explicitly specifying a root type
问题原因
这是Xcode 15 Beta阶段的兼容性缺陷:#Predicate宏对Core Data中未显式标记@Attribute的枚举属性解析存在逻辑问题,无法正确推断枚举类型的表达式路径,导致编译错误;即使通过rawValue比较,宏的表达式解析逻辑也会因类型推断失败抛出错误。
解决方案
1. 给枚举属性添加@Attribute标记
修改模型定义,为枚举属性显式添加@Attribute注解,明确告知Core Data该属性需要持久化:
@Model final class ModelA: Codable { @Attribute(.unique) var id: Int64 = 0 enum ModelAType: Int, CaseIterable, Codable { case a = 1, b } // 添加@Attribute标记,Core Data会自动映射枚举的rawValue @Attribute var type: ModelAType = .a }
2. 调整#Predicate写法
修改后的模型支持两种正确的查询写法:
- 直接比较枚举值:
let predicate = #Predicate<ModelA> { $0.type == .a } // 或显式指定枚举类型 let predicate = #Predicate<ModelA> { $0.type == ModelA.ModelAType.a }
- 通过rawValue比较(需提前提取目标值,避免宏解析时的类型混淆):
let targetRaw = ModelA.ModelAType.a.rawValue let predicate = #Predicate<ModelA> { $0.type.rawValue == targetRaw }
3. 临时过渡方案(使用NSPredicate)
如果上述方案仍无法解决,可以暂时使用旧的NSPredicate作为过渡:
let predicate = NSPredicate(format: "type == %d", ModelA.ModelAType.a.rawValue)
说明
该问题属于Xcode 15 Beta版本的bug,苹果后续的Beta版本或正式版应该会修复#Predicate宏对Core Data枚举属性的解析支持。
内容的提问来源于stack exchange,提问作者PerroVerde
相关产品推荐
相关产品推荐

