核心数据实体经理

时间:2017-12-30 14:26:52

标签: ios swift core-data

我想写一个类来管理我在我的应用程序中拥有的所有实体。 我的代码在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传递给此方法? 感谢所有回复

2 个答案:

答案 0 :(得分: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
}

}

答案 1 :(得分:0)

在我制作的一些项目中,当我使用CoreData时,我通常会创建一个带有获取,保存和删除CoreData对象的函数的Singleton。 这是我的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
   }

}

当你需要打电话时,只需写下:

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


}