将请求函数转换为通用类型

将请求函数转换为通用类型

问题描述:

我正在尝试将以下获取请求代码从核心数据转换为通用类型.

I am trying to convert my below fetch request code from core data to generic type.

let request = NSPredicate(format: "name == %@ AND password == %@ AND type == %@", "admin", "admin", "admin")
let fetchReq : NSFetchRequest = UserRegistration.fetchRequest()
fetchReq.predicate = request
let adminDetail :[UserRegistration] = DatabaseEngine.fetch(fetchRequest: fetchReq)!

到目前为止已转换:

extension UIViewController{
    class func getData<T: NSManagedObject>(req: NSPredicate) -> T{
        let fetchReq : NSFetchRequest = T.fetchRequest()
        fetchReq.predicate = req
        return DatabaseEngine.fetch(fetchRequest: fetchReq as! NSFetchRequest<NSManagedObject>)! as! T

    }
}


DatabaseEngine.fetch函数.


DatabaseEngine.fetch function.

static func fetch (fetchRequest: NSFetchRequest<T> = NSFetchRequest(), context:NSManagedObjectContext = kApplicationDelegate.managedObjectContext) -> [T]? {

    let entity =  NSEntityDescription.entity(forEntityName: typeName(some:T.self)
        , in:context)
    // Configure Fetch Request
    fetchRequest.entity = entity
    do {
        return try  context.fetch(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) as? [T]
    } catch {

        //let fetchError = error as NSError
        // return nil

    }
    return nil
}

但是没有结果了.任何人都可以通过很少的解释行帮助我转换此代码. Ans将不胜感激.

But no results any more. Anybody help me to convert this code with few explaining lines. Ans will be appreciated sure.

根据我的评论,我建议使用带有扩展名的协议

According to my comment I recommend to use a protocol with extension for example

protocol Fetchable
{
    associatedtype FetchableType: NSManagedObject = Self

    static var entityName : String { get }
    static var managedObjectContext : NSManagedObjectContext { get }
    static func objects(for predicate: NSPredicate?) throws -> [FetchableType]
}

extension Fetchable where Self : NSManagedObject, FetchableType == Self
{
    static var entityName : String {
        return NSStringFromClass(self).components(separatedBy: ".").last!
    }

    static var managedObjectContext : NSManagedObjectContext {
        return (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    }

    static func objects(for predicate: NSPredicate?) throws -> [FetchableType]
    {
        let request = NSFetchRequest<FetchableType>(entityName: entityName)
        request.predicate = predicate
        return try managedObjectContext.fetch(request)
    }
}

(UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext更改为对托管对象上下文的引用.

Change (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext to the reference to your managed object context.

使所有NSManagedObject子类都采用Fetchable.子类中不需要额外的代码.

Make all NSManagedObject subclasses adopt Fetchable. There is no extra code needed in the subclasses.

现在您可以使用

do {
   let predicate = NSPredicate(format: ...
   let objects = try MyEntity.objects(for: predicate)
} catch {
    print(error)
}

仅此而已,objects[MyEntity],没有任何类型转换,并且在成功时总是非可选的.

That's all, objects are [MyEntity] without any type casting and always non-optional on success.

该协议可以通过默认的排序描述符,排序方向等轻松扩展.

The protocol is easily extendable by default sorting descriptors, sorting directions etc.