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

时间:2017-09-04 13:12:18

标签: ios generics swift3

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

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函数。

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肯定会受到赞赏。

1 个答案:

答案 0 :(得分:1)

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

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更改为对托管对象上下文的引用。

让所有NSManagedObject子类采用Fetchable。子类中不需要额外的代码。

现在您可以使用

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

这就是全部,objects[MyEntity]没有任何类型转换,并且在成功时始终是非可选的。

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