2016-09-16 1 views
3

J'utilise une méthode de requête CoreData générale dans mon projet.Swift3: Passage de paramètres dans la méthode NSFetchRequest

func query(table: String, searchPredicate: NSPredicate) -> [AnyObject] 
{ 
    let context = app.managedObjectContext 

    let fetchRequest = NSFetchRequest(entityName: table) 

    fetchRequest.predicate = searchPredicate 

    let results = try! context.fetch(fetchRequest) 
    return results 
} 

Dans Swift 3 cela ne fonctionne pas. J'ai trouvé sur le site web d'Apple:

func findAnimals() 
{ 
    let request: NSFetchRequest<Animal> = Animal.fetchRequest 
    do 
    { 
     let searchResults = try context.fetch(request) 
     ... use(searchResults) ... 
    } 
    catch 
    { 
     print("Error with request: \(error)") 
    } 
} 

En utilisant l'exemple d'Apple, comment pourrais-je passer des animaux dans la méthode en tant que paramètre pour faire findAnimals plus générique?

Répondre

3

Je ne l'ai pas essayé mais je pense que quelque chose comme ça marcherait ...

func findCoreDataObjects<T: NSManagedObject>() -> [T] { 
    let request = T.fetchRequest 
    do 
    { 
     let searchResults = try context.fetch(request) 
     ... use(searchResults) ... 
    } 
    catch 
    { 
     print("Error with request: \(error)") 
    } 
} 

Vous devez faire l'ensemble de la fonction générique et donc vous devez lui dire quel type T est lors de l'appel .

someObject.findCoreDataObjects<Animal>() 

Je pense qui devrait faire le travail. Pas tout à fait certain cependant que je suis nouveau aux génériques moi-même: D

+0

En fait, si je l'avais eu la chance de passer plus de temps avec cela après que j'ai posté la générosité j'aurais réalisé que c'était en fait la bonne réponse tout le long. – iphaaw

1

Que diriez-vous de ceci.

func query<T: NSManagedObject>(table: String, searchPredicate: NSPredicate) -> [T] { 
    let context = app.managedObjectContext 
    let fetchRequest: NSFetchRequest<T> = NSFetchRequest(entityName: table) 
    fetchRequest.predicate = searchPredicate 
    let results = try! context.fetch(fetchRequest) 
    return results 
} 
+0

Nous avons essayé de l'utiliser avec func allRecords (table: String, tri: NSSortDescriptor? = Nil) -> [T] { retourner la requête (table: table, recherche: nil, trier: trier } – iphaaw

+0

Attendez quoi? Vous obtenez la prime pour copier à peu près ma réponse? Comment cela peut-il avoir un sens? Lol – Fogmeister

+0

@Fogmeister - J'ai dû réfléchir longuement à qui a obtenu la prime car les réponses étaient similaires. Je pourrais copier et coller la réponse de closetCoder dans mon code, c'est ce qui l'a fait basculer. Merci quand même pour vôtre aide. – iphaaw

0

Voici le résultat final qui peut aider quelqu'un:

import Foundation 
import Cocoa 

func addRecord<T: NSManagedObject>(_ type : T.Type) -> T 
{ 
    let entityName = T.description() 
    let context = app.managedObjectContext 
    let entity = NSEntityDescription.entity(forEntityName: entityName, in: context) 
    let record = T(entity: entity!, insertInto: context) 
    return record 
} 

func recordsInTable<T: NSManagedObject>(_ type : T.Type) -> Int 
{ 
    let recs = allRecords(T.self) 
    return recs.count 
} 


func allRecords<T: NSManagedObject>(_ type : T.Type, sort: NSSortDescriptor? = nil) -> [T] 
{ 
    let context = app.managedObjectContext 
    let request = T.fetchRequest() 
    do 
    { 
     let results = try context.fetch(request) 
     return results as! [T] 
    } 
    catch 
    { 
     print("Error with request: \(error)") 
     return [] 
    } 
} 

func query<T: NSManagedObject>(_ type : T.Type, search: NSPredicate?, sort: NSSortDescriptor? = nil, multiSort: [NSSortDescriptor]? = nil) -> [T] 
{ 
    let context = app.managedObjectContext 
    let request = T.fetchRequest() 
    if let predicate = search 
    { 
     request.predicate = predicate 
    } 
    if let sortDescriptors = multiSort 
    { 
     request.sortDescriptors = sortDescriptors 
    } 
    else if let sortDescriptor = sort 
    { 
     request.sortDescriptors = [sortDescriptor] 
    } 

    do 
    { 
     let results = try context.fetch(request) 
     return results as! [T] 
    } 
    catch 
    { 
     print("Error with request: \(error)") 
     return [] 
    } 

} 


func deleteRecord(_ object: NSManagedObject) 
{ 
    let context = app.managedObjectContext 
    context.delete(object) 
} 

func deleteRecords<T: NSManagedObject>(_ type : T.Type, search: NSPredicate? = nil) 
{ 
    let context = app.managedObjectContext 

    let results = query(T.self, search: search) 
    for record in results 
    { 
     context.delete(record) 
    } 
} 

func saveDatabase() 
{ 
    let context = app.managedObjectContext 

    do 
    { 
     try context.save() 
    } 
    catch 
    { 
     print("Error saving database: \(error)") 
    } 
} 

Appelez avec:

let name = "John Appleseed" 

let newContact = addRecord(Contact.self) 
newContact.contactNo = 1 
newContact.contactName = name 

let contacts = query(Contact.self, search: NSPredicate(format: "contactName == %@", name)) 
for contact in contacts 
{ 
    print ("Contact name = \(contact.contactName), no = \(contact.contactNo)") 
} 

deleteRecords(Contact.self, search: NSPredicate(format: "contactName == %@", name)) 

recs = recordsInTable(Contact.self) 
print ("Contacts table has \(recs) records") 

saveDatabase()