2017-12-30 50 views
1

내 응용 프로그램에있는 모든 엔터티를 관리하기위한 클래스를 작성하고 싶습니다. 하나의 사용자 지정 엔터티에 대한 내 코드 fore managerClass가 있지만이 컨텍스트에서 manageObject 형식을 설정하는 데 문제가 있습니다.핵심 데이터 엔터티 관리자

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) 
     } 
     } 
    } 
    } 

예를 들어 나는 모든 entityContext를 지울 수있는 메소드를 작성하려고합니다. 하지만 난이 메서드에 manageObject를 전달할 수 없습니다.

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) 
     } 
    } 
    } 

어떻게 NSManagedObject를이 방법으로 전달할 수 있습니까? 답장을 보내 주셔서 감사합니다

답변

1

여기에 우리는 우리의 프로젝트에 사용할 더 일반적인 구현입니다.

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

답장을 주셔서 감사합니다 귀하의 엔티티를 전달할 수 있습니다, 그게 완벽한 코드. – ava

0

내가 만든 CoreData 프로젝트에서는 CoreData 객체를 가져오고 저장하고 삭제하는 기능을 가진 싱글 톤을 만듭니다. 당신이 전화를해야 할 때

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 
    } 

} 

, 단지 쓰기 : 이 내 CoreDataController입니다

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

또는 다른 기능! 이 방법이 유용 할 것입니다.

모든 엔티티에 사용이 클래스는 그런 식으로 쓸 수 있습니다 :

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

답장을 보내 주셔서 감사합니다. 그런 식으로되어 있지만, 관리되는 모든 항목에 대해 하나의 클래스가 있습니다. 귀하의 경우에는 YourEntity 대신 하나의 엔티티를 추가해야합니다. – ava

+0

5 개의 엔티티가있을 때이 5 개의 엔티티 모두에 대해이 클래스를 반복해야합니다. – ava

+0

그것은 단지 예일뿐입니다. 당신은 함수 – fdanise