Базовые данные возвращают 0 значений даже после сохранения в контексте - PullRequest
0 голосов
/ 23 июня 2018

У меня есть одноэлементный класс основных данных, подобный этому:

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

Кроме того, у меня есть код persistentContainer в моем APpDelegate следующим образом:

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, и "требуемый init" вызывается в фоновом потоке, и если я использую UIApplication.shared.delegate, он не работает. Поэтому я решил использовать AppDelegate ().

1 Ответ

0 голосов
/ 23 июня 2018

AppDelegate() создает новый объект AppDelegate, поэтому вы создаете три новых делегата приложения со следующими строками:

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

Вероятно, вам нужно что-то вроде этого, когда вы получаете доступ к одному и тому же экземпляруAppDelegate, пройдя через UIApplication.shared singleton:

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

    // ...
}
...