即使在上下文中保存后,核心数据也会返回0值

时间:2018-06-23 19:05:25

标签: ios core-data alamofire objectmapper

我有一个像这样的核心数据单例类:

  class CoreDataUtil {
    static let shared = CoreDataUtil()
    var  container:NSPersistentContainer? = AppDelegate().persistentContainer
    var mainContext:NSManagedObjectContext? = AppDelegate().persistentContainer.viewContext
    var backGroundContext: NSManagedObjectContext? = AppDelegate().persistentContainer.newBackgroundContext()

    init() {
      setup()
    }

    func setup(){
      mainContext?.mergePolicy =  NSMergeByPropertyObjectTrumpMergePolicy
      backGroundContext?.mergePolicy =  NSMergeByPropertyObjectTrumpMergePolicy
    }

    func getMainContext() -> NSManagedObjectContext {
      let context = CoreDataUtil.shared.mainContext
    return context!
    }

    func getBackgroundContext() -> NSManagedObjectContext {
      let context = CoreDataUtil.shared.backGroundContext
    return context!
    }

    func save()  {
      do {
          try backGroundContext?.save()
      }
      catch {
          print("Error while saving->",error)
      }
    }
  }

此外,我在APpDelegate中有如下的persistentContainer代码:

lazy var persistentContainer: NSPersistentContainer = {
    /*
     The persistent container for the application. This implementation
     creates and returns a container, having loaded the store for the
     application to it. This property is optional since there are legitimate
     error conditions that could cause the creation of the store to fail.
    */
    let container = NSPersistentContainer(name: "CoreDataAlamo")
    let urlStore = Bundle.main.url(forResource: "CoreDataAlamo", withExtension: "momd")
    let storeDirectory = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
    let url = storeDirectory.appendingPathComponent("CoreDataAlamo.momd")
    let description = NSPersistentStoreDescription.init(url:url)
    description.shouldInferMappingModelAutomatically = true
    description.shouldMigrateStoreAutomatically = true
    container.persistentStoreDescriptions = [description]

    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

            /*
             Typical reasons for an error here include:
             * The parent directory does not exist, cannot be created, or disallows writing.
             * The persistent store is not accessible, due to permissions or data protection when the device is locked.
             * The device is out of space.
             * The store could not be migrated to the current model version.
             Check the error message to determine what the actual problem was.
             */
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}

现在,我正在使用Alamofire对象映射器将其保存在上下文中(使用CoreDataUtil),但我并没有做错什么,但是每次我尝试从Core Data中获取(使用CoreDataUtil)时,它都返回0个元素。请帮忙。

我有这样使用的NSManagedObject子类:

public class ChildAnalytics: NSManagedObject, Mappable {

override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) {
super.init(entity: entity, insertInto: CoreDataUtil.shared.backGroundContext)
}

required public init?(map: Map) {
  let ctx  =  CoreDataUtil.shared.backGroundContext
  let entity = NSEntityDescription.entity(forEntityName: "ChildAnalytics", in: ctx!)
  super.init(entity: entity!, insertInto: ctx)
  mapping(map: map)
}

public func mapping(map: Map) {
  accurate_answer <- map["accurate_answer"]
  child_rank <- map["child_rank"]
  streak <- map["streak"]
  story_read <- map["story_read"]
  offline_time_spent <- map["offline_time_spent"]
  freadom_point <- map["freadom_point"]
  fread_done <- map["fread_done"]
  max_streak <- map["max_streak"]
  activity_done <- map["activity_done"]
  top_three <- map["top_three"]
  book_read <- map["book_read"]
}

}

现在,当我从API获得响应并将JSON映射到ChildAnalytics对象时, 然后在后台线程上调用“ required init”,并且如果我使用UIApplication.shared.delegate,它将无法正常工作。这就是为什么我决定使用AppDelegate()的原因。

1 个答案:

答案 0 :(得分:0)

AppDelegate()实例化一个新的AppDelegate对象,因此您将使用以下几行创建三个新的应用程序委托:

var container: NSPersistentContainer? = AppDelegate().persistentContainer
var mainContext: NSManagedObjectContext? = AppDelegate().persistentContainer.viewContext
var backGroundContext: NSManagedObjectContext? = AppDelegate().persistentContainer.newBackgroundContext()

您可能想要的是这样的东西,您可以通过AppDelegate单例来访问UIApplication.shared的相同实例:

var container = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer
var mainContext = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext
var backGroundContext = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.newBackgroundContext()

或者,为了简化一点:

extension AppDelegate {
    static let shared = UIApplication.shared.delegate as! AppDelegate
}

class CoreDataUtil {
    static let shared = CoreDataUtil()
    var container = AppDelegate.shared.persistentContainer
    var mainContext = AppDelegate.shared.persistentContainer.viewContext
    var backGroundContext = AppDelegate.shared.persistentContainer.newBackgroundContext()

    // ...
}