麻烦预备核心数据 - 我在哪里失败?

时间:2017-04-09 15:57:18

标签: core-data

我正在跟踪tutorial小组中过时的RayWenderlich,该小组通过使用命令行工具应用程序来重新填充Core Data支持的应用程序。

到目前为止,我已经完成了配置项目并准备保存NSManagedObject子类对象的所有步骤。但是,在我尝试获取Currencies.json文件的路径时,应用程序失败。该文件已添加到目标中,但是当我尝试获取路径时,由于fatalError()调用,它只会崩溃。

我不确定为什么我无法访问该路径。

我的CoreDataStack模型用于与CoreData进行交互:

/// The object that is responsible for managing interactions with Core Data.
internal class CoreDataStack {

    // MARK: - Properties

    /// The name of the `NSManagedObjectModel` object used for storing information with Core Data.
    private let modelName: String

    /// The `NSManagedObjectContext` object that is associated with the main queue.
    internal lazy var mainContext: NSManagedObjectContext = {
        return self.storeContainer.viewContext
    }()

    /// The `NSPersistentContainer` object that encapsulates the application's Core Data stack.
    private lazy var storeContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: self.modelName)
        container.loadPersistentStores { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        }
        return container
    }()

    // MARK: - Initialization

    /// Returns an instance of `CoreDataStack`.
    /// - parameter modelName: The name of the `NSManagedObjectModel` object used for storing information with Core Data.
    internal init(modelName: String) {
        self.modelName = modelName
    }

    /// Attempts to save items to Core Data by committing changes to `NSManagedObject`s in a `NSManagedObjectContext`.
    /// - parameter context: The `NSManagedObjectContext` of which changes should be committed.
    internal func saveContext(_ context: NSManagedObjectContext) {
        context.perform {
            do {
                try context.save()
            } catch let error as NSError {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        }
    }
}

CurrencyPreloader类用于预加载CoreData

internal final class CurrencyPreloader {

    // MARK: - Properties

    private let coreDataStack = CoreDataStack(modelName: "CurrencyConverter")

    // MARK: - Preload

    internal func preloadCurrencies() {
        let path = pathForCurrencyJSON()
        let url = urlForCurrencyJSON(from: path)
        let data = dataForCurrencyJSON(from: url)
        let dictionary = dictionaryOfCurrencies(from: data)
        saveCurrencies(from: dictionary)
    }

    // MARK: - Helpers

    private func pathForCurrencyJSON() -> String {
        guard let path = Bundle.main.path(forResource: "Currencies", ofType: "json") else {
            fatalError("Invalid path for currency JSON")
        }
        return path
    }

    private func urlForCurrencyJSON(from path: String) -> URL {
        return URL(fileURLWithPath: path)
    }

    private func dataForCurrencyJSON(from url: URL) -> Data {
        do {
            return try Data(contentsOf: url)
        } catch {
            fatalError("Could not create data object from currency JSON file")
        }
    }

    private func dictionaryOfCurrencies(from data: Data) -> Dictionary<String, String> {
        do {
            guard let dictionary = try JSONSerialization.jsonObject(with: data, options: []) as? Dictionary<String, String> else {
                fatalError("Invalid JSON object type")
            }
            return dictionary
        } catch {
            fatalError("Invalid JSON structure")
        }
    }

    private func saveCurrencies(from dictionary: Dictionary<String, String>) {
        guard let entityDescription = NSEntityDescription.entity(forEntityName: "Currency", in: coreDataStack.mainContext) else {
            fatalError("Invalid entity description")
        }
        for (abbreviation, name) in dictionary {
            let currency = Currency(entity: entityDescription, insertInto: coreDataStack.mainContext)
            currency.name = name
            currency.abbreviation = abbreviation
            let filteredSavedCurrencies = savedCurrencies.filter({ (filteredCurrency) -> Bool in
                return filteredCurrency.abbreviation == abbreviation
            })
            if filteredSavedCurrencies.count == 0 {
                do {
                    try coreDataStack.mainContext.save()
                } catch {
                    fatalError("Save failed")
                }
            }
            print("\(abbreviation): \(name)")
        }
    }

}

当我在CurrencyPreloader().preloadCurrencies()中致电Main.m时发生了失败;具体而言,在CoreDataPreloader

private func pathForCurrencyJSON() -> String {
    guard let path = Bundle.main.path(forResource: "Currencies", ofType: "json") else {
        fatalError("Invalid path for currency JSON")
    }
    return path
}

无法找到Currencies.json的路径。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

我在目标的Build Phases菜单中徘徊,我解决了我的问题。

Build Phases&gt;下Copy Files,我取消选中copy only when installing的{​​{1}}选项,解决了这个问题。现在,我的Currencies.json正在保存。

Screenshot of the Copy Files section of the Build Phases menu for the target