iOS - Swift:如何编写通用函数?

时间:2022-11-25 16:53:38

I'm using CoreData in my app. There're 4 tables in the database: User, Medicine, Schedule and Patient. For each table I need to write an Add function to add data into the database like this:

我在我的app中使用CoreData,数据库中有4个表:用户、药物、时间表和病人。对于每个表,我都需要编写一个Add函数将数据添加到数据库中,如下所示:

func addUser(email: String, password: NSData, handler: @escaping (_ status: SaveStatus, _ error: NSError?) -> Void){
    let managedContext = (UIApplication.shared.delegate as? AppDelegate)?.managedObjectContext
    let entity = NSEntityDescription.entity(forEntityName: DB.TABLE.USER, in: managedContext!)!
    let nurse = NSManagedObject(entity: entity, insertInto: managedContext) as! User
    nurse.email = email
    nurse.password = password

    save { (status, error) in
        handler(status, error)
    }
}

func addMedicine(name: String, handler: @escaping(_ status: SaveStatus, _ error: NSError?) -> Void){
    let managedContext = (UIApplication.shared.delegate as? AppDelegate)?.managedObjectContext
    let entity = NSEntityDescription.entity(forEntityName: DB.TABLE.MEDICINE, in: managedContext!)!
    let medicine = NSManagedObject(entity: entity, insertInto: managedContext) as! Medicine
    medicine.name = name

    save { (status, error) in
        handler(status, error)
    }
}

and so on ...

等等……

I want to write an generic function like this:

我想写一个这样的泛型函数:

func addDataToDB<DATA>(object: DATA, handler: @escaping SaveStatusHandler){
    switch DATA {
    case DATA is LoginData:
        break
    default:
        break
    }
}

I don't know what type should the LoginData be, so I can compare the DATA with it. Or is there any better way to do this?

我不知道LoginData应该是什么类型,所以我可以用它来比较数据。或者有更好的方法吗?

1 个解决方案

#1


1  

The fastest solution for this case, since each Entity has a different save implementation, is to declare a Saveable protocol

对于这种情况,由于每个实体都有不同的保存实现,所以最快的解决方案是声明一个可保存的协议

protocol Saveable {
    associatedtype Parameters
    static var entityName: String { get }
    static var context: NSManagedContext { get }
    func setup(with parameters: Parameters)
    func save(_ handler: () -> ())
}

And then use this protocol as generic parameter in the addDataToDB function

然后在addDataToDB函数中使用该协议作为泛型参数。

func addDataToDB<T>(params: T.Parameters, _ handler: () -> ()) where T: Saveable {
    let entity = NSEntityDescription.entity(forEntityName: T.entityName, in: T.contenxt)!
    let object = NSManagedObject(entity: entity, insertInto: T.context) as! T
    object.setup(with: params)

    object.save(handler)
}

Parameters in this case should be a struct for example, or a dictionary, it's completely up to you

这个例子中的参数应该是一个struct,或者一个字典,它完全取决于你。

#1


1  

The fastest solution for this case, since each Entity has a different save implementation, is to declare a Saveable protocol

对于这种情况,由于每个实体都有不同的保存实现,所以最快的解决方案是声明一个可保存的协议

protocol Saveable {
    associatedtype Parameters
    static var entityName: String { get }
    static var context: NSManagedContext { get }
    func setup(with parameters: Parameters)
    func save(_ handler: () -> ())
}

And then use this protocol as generic parameter in the addDataToDB function

然后在addDataToDB函数中使用该协议作为泛型参数。

func addDataToDB<T>(params: T.Parameters, _ handler: () -> ()) where T: Saveable {
    let entity = NSEntityDescription.entity(forEntityName: T.entityName, in: T.contenxt)!
    let object = NSManagedObject(entity: entity, insertInto: T.context) as! T
    object.setup(with: params)

    object.save(handler)
}

Parameters in this case should be a struct for example, or a dictionary, it's completely up to you

这个例子中的参数应该是一个struct,或者一个字典,它完全取决于你。