Swift 通用获取请求
我有一个静态函数,它扩展了Swift 通用获取请求,swift,generics,nsmanagedobject,Swift,Generics,Nsmanagedobject,我有一个静态函数,它扩展了NSManagedObject,以获得这样一个对象 NSManagedObject.get(类型:MYUser.self,带:(“id”,“SomeUserId”),在:context中) 扩展NSManagedObject{ 静态func-get(类型:M.type,带kvp:(字符串,CVarArg),在上下文:NSManagedObjectContext)->M{ guard let name=entity().name else{return nil} guar
NSManagedObject
,以获得这样一个对象
NSManagedObject.get(类型:MYUser.self,带:(“id”,“SomeUserId”),在:context中)
扩展NSManagedObject{
静态func-get(类型:M.type,带kvp:(字符串,CVarArg),在上下文:NSManagedObjectContext)->M{
guard let name=entity().name else{return nil}
guard M.entity().propertiesByName[kvp.0]!=nil else{Assert(\(name)没有\(kvp.0)”);返回nil}
let fetchRequest=NSFetchRequest(entityName:name)
fetchRequest.predicate=NSPredicate(格式:“\(kvp.0)=%@”,kvp.1)
做{
let object=try context.fetch(fetchRequest)
如果让foundObject=object.first{返回foundObject}
归零
}抓住{
归零
}
}
}
我想要的语法是
MYUser.get(使用:(“id”,“SomeUserId”),在:context中)
要从调用的类推断类型。。。但我不确定该用什么来代替通用的
NSFetchRequest(entityName:name)
NSFetchRequest(entityName:name)
提前感谢如果您不介意写两次
MYUser
,您可以删除类型
参数并指定类型,以便Swift可以推断M
:
extension NSManagedObject {
static func get<M: NSManagedObject>(with kvp: (String, CVarArg), in context: NSManagedObjectContext) -> M? {
guard let name = entity().name else { return nil }
guard M.entity().propertiesByName[kvp.0] != nil else {
print("\(name) does not have \(kvp.0)")
return nil
}
let fetchRequest = NSFetchRequest<M>(entityName: name)
fetchRequest.predicate = NSPredicate(format: "\(kvp.0) == %@", kvp.1)
do {
let object = try context.fetch(fetchRequest)
if let foundObject = object.first { return foundObject }
return nil
} catch {
return nil
}
}
}
// usage:
let user: MYUser? = MYUser.get(with: ("id", "SomeUserId"), in: context)
扩展NSManagedObject{
静态func get(使用kvp:(字符串,CVarArg),在context:NSManagedObjectContext中)->M{
guard let name=entity().name else{return nil}
guard M.entity().propertiesByName[kvp.0]!=nil else{
打印(“\(名称)没有\(kvp.0)”)
归零
}
let fetchRequest=NSFetchRequest(entityName:name)
fetchRequest.predicate=NSPredicate(格式:“\(kvp.0)=%@”,kvp.1)
做{
let object=try context.fetch(fetchRequest)
如果让foundObject=object.first{返回foundObject}
归零
}抓住{
归零
}
}
}
//用法:
让用户:MYUser?=get(带有:(“id”,“SomeUserId”),位于:context中)
如果您不想写两次MYUser
,那么我想不出任何解决方案。如果NSManagedObject
是一个协议,您可以在其中使用Self
。根据
协议管理,其中Self:NSManagedObject{}
扩展管理,其中Self:NSManagedObject{
静态func get(使用kvp:(字符串,CVarArg),在context:NSManagedObjectContext中)->Self{
guard let name=entity().name else{return nil}
guard entity().propertiesByName[kvp.0]!=nil-else{Assert(\(名称)没有\(kvp.0)”);返回nil}
let fetchRequest=NSFetchRequest(entityName:name)
fetchRequest.predicate=NSPredicate(格式:“\(kvp.0)=%@”,kvp.1)
做{
let object=try context.fetch(fetchRequest)
如果让foundObject=object.first{返回foundObject}
归零
}抓住{
归零
}
}
将M
作为泛型类型对您不起作用吗?我想删除泛型类型它将是零对吗?哦,对不起,我误解了您的问题。现在考虑一个答案…我假设您不想做类似让用户:MYUser?=MYUser.get(…)
?只是为了清楚让用户=MYUser.get(使用:(“id”),“SomeUserId”),在:上下文中)
不起作用?@Magoo用户的类型要么无法推断,要么只是NSManagedObject
。你自己试试。@Magoo实际上Martin R的链接中显示的解决方案也很好。尝试调整一下。如果你解释了问题和解决方案,而不是只转储代码,那么答案会更有用。–你可能会遇到问题我想给你的答案加一个参考,因为你显然受到了这个解决方案的启发。当然……我认为从评论中可以清楚地看出,但你是对的,我应该引用你和你指给我的答案。。
extension NSManagedObject {
static func get<M: NSManagedObject>(with kvp: (String, CVarArg), in context: NSManagedObjectContext) -> M? {
guard let name = entity().name else { return nil }
guard M.entity().propertiesByName[kvp.0] != nil else {
print("\(name) does not have \(kvp.0)")
return nil
}
let fetchRequest = NSFetchRequest<M>(entityName: name)
fetchRequest.predicate = NSPredicate(format: "\(kvp.0) == %@", kvp.1)
do {
let object = try context.fetch(fetchRequest)
if let foundObject = object.first { return foundObject }
return nil
} catch {
return nil
}
}
}
// usage:
let user: MYUser? = MYUser.get(with: ("id", "SomeUserId"), in: context)
protocol Managed where Self: NSManagedObject { }
extension Managed where Self: NSManagedObject {
static func get(with kvp: (String, CVarArg), in context: NSManagedObjectContext) -> Self? {
guard let name = entity().name else { return nil }
guard entity().propertiesByName[kvp.0] != nil else { Assert("\(name) does not have \(kvp.0)"); return nil }
let fetchRequest = NSFetchRequest<Self>(entityName: name)
fetchRequest.predicate = NSPredicate(format: "\(kvp.0) == %@", kvp.1)
do {
let object = try context.fetch(fetchRequest)
if let foundObject = object.first { return foundObject }
return nil
} catch {
return nil
}
}