2017-12-30 21 views
1

Ich möchte Klasse für die Verwaltung aller Entität, die ich in meiner Anwendung habe schreiben. Es gibt meinen Code for managerClass für eine benutzerdefinierte Entität, aber ich habe ein Problem, in diesem Kontext manageObject-Typ festzulegen.Kerndaten Entity Manager

public func clearEntityContex() { 

    let fetchRequest: NSFetchRequest<Shop> = Shop.fetchRequest() 

    if let fetchResult = try? self.stack.mainQueueContext.fetch(fetchRequest){ 
     for user : Shop in fetchResult { 
     self.stack.mainQueueContext.delete(user as Shop) 
     } 
     do { 
     try stack.mainQueueContext.save() 
     } 
     catch { 
     debugPrint(error.localizedDescription) 
     } 
    } 
    } 

    //MARK: _fetch Contex 
    public func fetchsShopEntity() -> [Shop]? { 

    var shops : [Shop]? 

    let fetchRequest: NSFetchRequest<Shop> = Shop.fetchRequest() 

    do { 
     let fetchResult = 
     try self.stack.mainQueueContext.fetch(fetchRequest) 

     if fetchResult.count > 0 { 

     shops = fetchResult 
     } 
    } 
    catch { 
     fatalError("Failed to fetch Account: \(error)") 
    } 

    return shops 
    } 

    //MARK: _save entity 
    public func saveEntityInModel(entityItem : Shop){ 

    if let entity = NSEntityDescription.entity(forEntityName: "Shop", in: self.stack.mainQueueContext) { 

     if let contex = NSManagedObject(entity: entity, insertInto: self.stack.mainQueueContext) as? Shop { 

     contex.packID = entityItem.packID 
     contex.packName = entityItem.packName 
     contex.packImage = entityItem.packImage 
     contex.priceDolar = entityItem.priceDolar 
     contex.packDescription = entityItem.packDescription 

     do { 
      try stack.mainQueueContext.save() 
     } 
     catch { 
      debugPrint(error.localizedDescription) 
     } 
     } 
    } 
    } 

Zum Beispiel möchte ich eine Methode schreiben, die einen beliebigen entityContext löschen kann. aber ich kann manageObject zu dieser Methode nicht übergeben.

public func clearEntityContex(entityObject: NSManagedObject) { 

    let fetchRequest: NSFetchRequest<NSFetchRequestResult> = entityObject.fetchRequest() 

    if let fetchResult = try? self.stack.mainQueueContext.fetch(fetchRequest){ 
     for entity in fetchResult { 
     self.stack.mainQueueContext.delete(entity as entityObject) 
     } 
     do { 
     try stack.mainQueueContext.save() 
     } 
     catch { 
     debugPrint(error.localizedDescription) 
     } 
    } 
    } 

Wie kann NSManagedObject gelöst werden, um diese Methode zu lösen? danke für alle Antworten

Antwort

1

Hier ist eine generische Implementierung, die wir in unseren Projekten einsetzen.

import CoreData 

class ACSwiftCoreData: ACCoreDataPlugin { 

let managedObjectModelName: String 
let databasePath: URL 

init(managedObjectModelName: String, databasePath: URL) { 
    self.managedObjectModelName = managedObjectModelName 
    self.databasePath = databasePath 
} 

// MARK: Managed Object Contexts 

private var sharedContext: NSManagedObjectContext? 

func getSharedManagedObjectContext() throws -> NSManagedObjectContext { 
    if let sharedContext = self.sharedContext { 
     return sharedContext 
    } 

    let context = try self.createManagedObjectContext() 
    self.sharedContext = context 
    return context 
} 

func createManagedObjectContext() throws -> NSManagedObjectContext { 
    let storeCoordinator = try self.getPersistentStoreCoordinator() 

    let managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) 
    managedObjectContext.persistentStoreCoordinator = storeCoordinator 
    managedObjectContext.mergePolicy = NSMergePolicy(merge: NSMergePolicyType.mergeByPropertyObjectTrumpMergePolicyType) 

    return managedObjectContext 
} 

// MARK: Creating Entities 

func createEntityInSharedContext<EntityType>(_ entityName: String) throws -> EntityType { 
    let context = try self.getSharedManagedObjectContext() 
    return try self.createEntity(entityName, context: context) 
} 

func createEntity<EntityType>(_ entityName: String, context: NSManagedObjectContext) throws -> EntityType { 
    let entity = NSEntityDescription.insertNewObject(forEntityName: entityName, into: context) 

    guard let expectedEntity = entity as? EntityType else { 
     throw self.errorWithMessage("ACSwiftCoreData: Entity for name \(entityName) does not match class \(EntityType.self).") 
    } 

    return expectedEntity 
} 

// MARK: Saving Entity 

func saveEntity(_ entity: NSManagedObject) throws { 
    guard let context = entity.managedObjectContext else { 
     throw errorWithMessage("ACSwiftCoreData: Cannot save Entity. ManagedObjectContext is missing.") 
    } 

    if context.hasChanges { 
     try context.save() 
    } 
} 

// MARK: Delete Entity 

func deleteEntity(_ entity: NSManagedObject) throws { 
    guard let context = entity.managedObjectContext else { 
     throw errorWithMessage("ACSwiftCoreData: Cannot delete Entity. ManagedObjectContext is missing.") 
    } 

    context.delete(entity) 
    try context.save() 
} 

// MARK: Fetch Requests 

func fetchEntitiesInSharedContext<EntityType: AnyObject>(_ entityName: String, predicate: NSPredicate?) -> [EntityType] { 
    guard let context = try? self.getSharedManagedObjectContext() else { 
     return [EntityType]() 
    } 

    return self .fetchEntities(entityName, context: context, predicate: predicate) 
} 

func fetchEntities<EntityType: AnyObject>(_ entityName: String, context: NSManagedObjectContext, predicate: NSPredicate?) -> [EntityType] { 
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName) 
    fetchRequest.predicate = predicate 

    let results = try? context.fetch(fetchRequest) 

    guard let resultEntitys = results as? [EntityType] else { 
     return [EntityType]() 
    } 

    return resultEntitys 
} 

// MARK: Technical Details 

private var storeCoordinator: NSPersistentStoreCoordinator? 

private func getPersistentStoreCoordinator() throws -> NSPersistentStoreCoordinator { 
    if let storeCoordinator = self.storeCoordinator { 
     return storeCoordinator 
    } 

    let model = try self.getManagedObjectModel() 

    let storeCoordinator = NSPersistentStoreCoordinator(managedObjectModel: model) 

    var options = [AnyHashable: Any]() 
    options[NSMigratePersistentStoresAutomaticallyOption] = true 
    options[NSInferMappingModelAutomaticallyOption] = true 

    try storeCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: self.databasePath, options: options) 

    self.storeCoordinator = storeCoordinator 
    return storeCoordinator 
} 

private var objectModel: NSManagedObjectModel? 

private func getManagedObjectModel() throws -> NSManagedObjectModel { 
    if let objectModel = self.objectModel { 
     return objectModel 
    } 

    let momName = self.managedObjectModelName 
    guard let modelUrl = Bundle.main.url(forResource: momName, withExtension:"momd") else { 
     throw self.errorWithMessage("ACSwiftCoreData: DataModel Url could not be created.") 
    } 

    guard let objectModel = NSManagedObjectModel(contentsOf: modelUrl) else { 
     throw self.errorWithMessage("ACSwiftCoreData: DataModel could not be loaded.") 
    } 

    self.objectModel = objectModel 
    return objectModel 
} 

// MARK: Error handling 

private func errorWithMessage(_ message: String) -> NSError { 
    let userInfo = [NSLocalizedDescriptionKey: message] 
    let error = NSError(domain: "com.appcron.accomponents", code: 0, userInfo: userInfo) 
    return error 
} 

} 
+0

Danke für die Antwort, das ist perfekter Code. – ava

0

In einigen Projekten, die ich gemacht habe und wenn ich CoreData verwendet habe, erstelle ich normalerweise einen Singleton mit Funktion zum Abrufen, Speichern und Löschen eines CoreData-Objekts. Das ist mein CoreDataController:

import Foundation 
import CoreData 
import UIKit 

final class CoreDataController { 

    static let sharedInstances = CoreDataController() 
    private var context: NSManagedObjectContext 

    private init(){ 
     let application = UIApplication.shared.delegate as! AppDelegate 
     self.context = application.persistentContainer.viewContext 
    } 

func loadAll() { 
    print("Fetch from CoreData") 

    let fetchRequest: NSFetchRequest<YourEntity> = YourEntity.fetchRequest() 

    do { 
     let entityArray = try self.context.fetch(fetchRequest) 

     guard entityArray.count > 0 else { 
      print("There aren't element in CoreData "); return} 

    } catch let error { 
     print("FetchRequest error") 
     print(" Print error: \n \(error) \n") 
    } 
} 

func save(entityToSave: String, item: String){ 

    let entity = NSEntityDescription.entity(forEntityName: entityToSave, in: self.context) 

    let newItem = YourEntity(entity: entity!, insertInto: self.context) 
    newItem.name = item 
    do { 
     try self.context.save() 
    } catch let error { 
     print("Problem with \(newItem)") 
     print(" Print error: \n \(error) \n") 
    } 

    print("Element \(newItem) saved in CoreData") 


} 

func loadFromName(entityName:String, name: String) -> Any { 

    let request = NSFetchRequest<NSFetchRequestResult>(entityName: entityName) 
    request.returnsObjectsAsFaults = false 

    let predicate = NSPredicate(format: "yourEntityAttribute = %@", yourEntityAttribute) 

    request.predicate = predicate 

    let items = self.loadFromFetchRequest(request: request) 

    return items[0] 
} 



private func loadFromFetchRequest(request: NSFetchRequest<NSFetchRequestResult>) -> [Any] { 
    var array = [Any]() 
    do { 
     array = try self.context.fetch(request) 

     guard array.count > 0 else {print("There aren't element in CoreData"); return []} 

     for item in array { 
      print("Item: \(item)") 
     } 

    } catch let error { 
     print("FetchRequest Error") 
     print(" Print Error: \n \(error) \n") 
    } 

    return array 
} 


func delete(entityName: String, name: String) { 
    let item = self.loadFromName(entityName: entityName, name: name) 

    self.context.delete(item as! NSManagedObject) 

    do { 
     try self.context.save() 
    } catch let error { 
     print("Deleting problem") 
     print("Print Error: \n \(error) \n") 
    } 
} 


func loadData(entity: String) -> [YourEntity] { 
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity) 
    fetchRequest.returnsObjectsAsFaults = false 
    var data = [YourEntity]() 

    do { 
     data = try self.context.fetch(fetchRequest) as! [YourEntity] 

    } catch let error { 
     print("Print Error: \n \(error) \n") 
    } 

    return data 
    } 

} 

Wenn Sie zu nennen haben, schreiben Sie einfach:

CoreDataController.sharedInstances.save(entityToSave: "Profile", item: textfield.text!) 

oder andere Funktionen !!! Ich hoffe, das ist nützlich für Sie.

Für die Verwendung dieser Klasse mit jeder Entität können Sie so schreiben:

let entity = NSEntityDescription.entity(forEntityName: entityToSave, in: self.context) 
    let newItem: Any 

    switch entityToSave { 

    case "YourEntity": 
     newItem = YourEntity(entity: entity!, insertInto: self.context) 
     (newItem as! YourEntity).entityAttribute = firstItem 
     (newItem as! YourEntity).entityAttribute = secondItem 

    case "YourEntity2": 
     newItem = YourEntity2(entity: entity!, insertInto: self.context) 
     (newItem as! YourEntity2).entityAttribute = firstItem 
     (newItem as! YourEntity2).entityAttribute = secondItem 

    case "YourEntity3": 
     newItem = YourEntity3(entity: entity!, insertInto: self.context) 
     (newItem as! YourEntity3).entityAttribute = firstItem 
     (newItem as! YourEntity3).entityAttribute = secondItem 

    case "YourEntity4": 
     newItem = YourEntity4(entity: entity!, insertInto: self.context) 
     (newItem as! YourEntity4).entityAttribute = firstItem 
     (newItem as! YourEntity4).entityAttribute = secondItem 
    default: 

     fatalError("Error in entityToSave function") 
    } 

    do { 
     try self.context.save() 
    } catch let error { 
     print("Problem to save \(newItem)") 
     print("Print Error: \n \(error) \n") 
    } 

    print("Element \(newItem) saved correctly") 


} 
+0

danke für die antwort, ich habe so etwas, aber ich habe eine klasse für verwaltet alle entität. In deinem Fall sollte ich stattdessen eine Entität hinzufügen. – ava

+0

Wenn ich fünf Entitäten habe, sollte ich diese Klasse für alle fünf Entitäten wiederholen. – ava

+0

Das war nur ein Beispiel. Sie können Ihre Entität übergeben durch Argument der Funktion – fdanise