想法是使用 Coredata 获取“类型化”数据。
已更新
class func retrieve<T: AnyObject>(entityName:T.Type, sortBy:String? = nil, isAscending:Bool? = true, predicate:NSPredicate? = nil) -> AnyObject[] {
println("\(entityName)")
let request = NSFetchRequest(entityName: "Users")
request.returnsObjectsAsFaults = false
if predicate != nil {
request.predicate = predicate
}
if (sortBy != nil){
var sorter: NSSortDescriptor = NSSortDescriptor(key: sortBy , ascending: isAscending!)
request.sortDescriptors = [sorter]
}
var error: NSError? = nil
var fetchedResult = myDataModel.managedObjectContext.executeFetchRequest(request, error: &error)
if !error {
println("errore: \(error)")
}
println("retrieved \(fetchedResult.count) elements for \(entityName)")
return fetchedResult
}
现在,我上面写的在语法上是正确的,但我相信还有另一种方法可以做到这一点,也许更“容易”。我认为建议很明确:) 我试图从 entityName 输入参数中获取类名
以下面的方式或类似的方式调用此函数:
var xx = myDataModel.retrieve(Users.self)
在哪里
Users: NSManagedeObject
你有什么建议吗?
如果正如@David 指出的那样,您将
@objc(ModelClassName)
添加到您的模型类中,这是一个简化版本:
func retrieve<T: NSManagedObject>(entityClass:T.Type, sortBy:String? = nil, isAscending:Bool = true, predicate:NSPredicate? = nil) -> T[] {
let entityName = NSStringFromClass(entityClass)
let request = NSFetchRequest(entityName: entityName)
request.returnsObjectsAsFaults = false
request.predicate = predicate
if (sortBy != nil) {
var sorter = NSSortDescriptor(key:sortBy , ascending:isAscending)
request.sortDescriptors = [sorter]
}
var error: NSError? = nil
var fetchedResult = myDataModel.managedObjectContext.executeFetchRequest(request, error: &error)
if !error {
println("errore: \(error)")
}
println("retrieved \(fetchedResult.count) elements for \(entityName)")
return fetchedResult
}
人们会这样使用它:
@objc(Client)
class Client : NSManagedObject {
...
}
retrieve(Client) // This would get all clients in the database.
您可以使用
NSStringFromClass
只要您通过使用@objc(ModelClassName)
确保您的模型类具有未损坏的名称
let request = NSFetchRequest(entityName:NSStringFromClass(entityClass))
另一种选择,对您来说更有效,可能是这样的:
protocol EntityWithName {
class func entityName() -> String
}
extension MyModelObject : EntityWithName {
class func entityName() -> String {
return "MyModelObject"
}
}
extension NSManagedObjectContext {
// Create an instance of T and insert it into the Context (this is normal)
func insert<T:NSManagedObject where T:EntityWithName>(entityClass:T.Type) -> T? {
let entityDescription = NSEntityDescription.entityForName(entityClass.entityName(), inManagedObjectContext: self)
if !entityDescription {
return nil
}
return NSManagedObject(entity: entityDescription, insertIntoManagedObjectContext: self) as? T
}
}
let myModelObject = myContext.insert(MyModelObject.Self)
但是,由于您的模型对象需要具有
NSManagedObject
作为超类,因此试图避免“绑定到 objective-c”确实有点毫无意义。
另一个观察,如果你使用 mogenerator 和它的新的快速生成选项,那么 EntityWithName 方法变得容易得多,你可以添加:
extension MyModelObject : EntityWithName {}
对于每个用户可修改的类文件(不是 _ 文件),它应该没问题,因为 mogenerator 生成一个 entityName 类方法。
我似乎无法让
@objc
注释为我工作,所以我使用了:
let fetchRequest = NSFetchRequest(entityName: NSStringFromClass(entityClass).componentsSeparatedByString(".").last!)
深入到实体名称。
lazy var persistentContainer: NSPersistentContainer = {
let persistent = NSPersistentContainer(name: "SuperModelName")
persistent.loadPersistentStores { _, error in
print(error?.localizedDescription ?? "")
}
return persistent
}()
var moc: NSManagedObjectContext {
persistentContainer.viewContext
}
func fetch<T: NSManagedObject>(_ type: T.Type) -> [T] {
do {
let fetchRequest = NSFetchRequest<T>(entityName: type.description())
let fetchItem = try moc.fetch(fetchRequest)
return fetchItem
} catch {
print(error.localizedDescription)
return []
}
}
var beverageData: [Beverage] {
fetch(Beverage.self)
}