CoreData и сохранение данных в iOS

Насколько важна сохраняемость данных! Как бы вы смогли продолжить с того места, где мы остановились в этой игре, или закончить документ, над которым вы работали? Возможность сохранения данных является важной функцией практически для каждого приложения. В этом руководстве мы рассмотрим, как реализовать CoreData в iOS для обеспечения сохраняемости данных. Я постараюсь изложить его кратко и по существу, чтобы его было легко понять. Давайте начнем!

Настройка вашего AppDelegate.swift

Прежде чем мы начнем строить нашу модель данных, нам нужно добавить код в наш файл AppDelegate.swift. Добавьте следующий код в класс AppDelegate:

  // MARK: - Core Data stack
  
lazy var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "URLSchemeTest")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()

    // MARK: - Core Data Saving support

    func saveContext () {
        let context = persistentContainer.viewContext
        if context.hasChanges {
            do {
                try context.save()
            } catch {
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    }

Создание модели данных

Чтобы начать построение модели данных, добавьте новый файл в xcode, щелкнув File > New > File…, а затем выберите Data Model. Дайте ему имя, например DataModel.xcdatamodeld.


Снимок экрана 2019-04-28 в 17.05.52 PM.pngДобавьте новый файл в свой проект, щелкнув File > New > File… и выбрав Data Model.

Снимок экрана 28.04.2019 в 17.10.19.png

Дайте модели соответствующее название.

CoreData поставляется с графическим интерфейсом пользователя для разработки вашей модели данных (Data Model). Ниже приведен пример объекта, который хранит идентификатор и состояние уведомления. Ваша модель данных работает аналогично стандартному классу в Swift. Сущность эквивалентна классу. Атрибуты эквивалентны свойствам в классе. В CoreData ваша модель данных определяет объект данных, который вы хотите сохранить.


Снимок экрана 2019-04-28 в 5.36.16 PM.pngВ CoreData ваша модель данных определяет объект данных, который вы хотите сохранить.

Назовите сущность и атрибуты чем-нибудь, что определяет то, что они представляют. В приведенном выше случае объект назван «Notifications», а атрибуты – «notificationId» и «notificationState». Эти атрибуты будут тем, что вы сохраните позже. Теперь, когда мы определили нашу модель данных, давайте перейдем к коду.

Работа с вашей моделью данных

Первым шагом в работе с вашей моделью CoreData является создание подклассов NSManaged. Я показал шаги на изображениях ниже.


Снимок экрана 2019-05-30 в 2.37.37 PM.pngШаг 1. Пусть Xcode сгенерирует ваши подклассы NSManaged.

Снимок экрана 2019-05-30 в 14.41.10 PM.pngШаг 2. Выберите вашу модель данных.

Снимок экрана 2019-05-30 в 14.41.25.pngШаг 3. Выберите сущности, которые вы хотите подклассифицировать.

После того, как вы создали свои подклассы, у вас останется пара файлов .swift, которые выглядят следующим образом.

import Foundation
import CoreData

@objc(Notifications)
public class Notifications: NSManagedObject {

}

import Foundation
import CoreData


extension Notifications {

    @nonobjc public class func notificationFetchRequest() -> NSFetchRequest<Notifications> {
        return NSFetchRequest<Notifications>(entityName: "Notifications")
    }

    @NSManaged public var notificationId: Int64
    @NSManaged public var notificationState: Bool

}

Небольшая заметка о файле, который содержит расширение Notifications. Я изменил имя функции с fetchRequest() на notificationFetchRequest(). Сгенерированный код изначально называется fetchRequest, но он не сможет скомпилировать, если вы попытаетесь вызвать функцию. Это связано с тем, что объект Notifications является подклассом объекта NSManaged, который уже содержит функцию с именем fetchRequest(). Добавление функции с тем же именем в расширение уведомлений означает, что теперь есть две функции с именами fetchRequest(). Итак, переименуйте вашу функцию fetchRequest в расширении. Надеюсь, это сэкономит вам время на отслеживание этой проблемы.

Загрузка и сохранение в вашей модели

Я включил в это руководство класс, чтобы показать вам, как работать с созданным нами подклассом Notifications.

import UIKit
import CoreData

class CoreDataNotifications{
    
    private static func setContext() -> NSManagedObjectContext {
        let appDelegate = UIApplication.shared.delegate as! SwiftAppDelegate
        let context = appDelegate.persistentContainer.viewContext
        return context
    }
    
    static func saveNewNotifications(newNotificationIds: [Int], newNotificationState: Bool){

        let context = setContext()
        for newId in newNotificationIds {
            let newNotification = Notifications(context: context)
            newNotification.notificationId = Int64(newId)
            newNotification.notificationState = newNotificationState
        }
        do
        {
            try context.save()
            print("Saved new notifications.")
        }
        catch { fatalError("Unable to save data.") }
    }
    
    static func loadWithCompletion(completion: @escaping ([Notifications]) -> Void) {
        
        let extractValues: [Notifications]
        let context = setContext()
        let request = Notifications.notificationFetchRequest()
        request.returnsObjectsAsFaults = false
        do
        {
            extractValues = try context.fetch(request)
        }
        catch { fatalError("Could not load Data") }
        completion(extractValues)
    }
}

Сохранение в вашей модели

Шаги по сохранению и загрузке довольно просты. Во-первых, вам нужно установить свой контекст. Вы можете увидеть, как это делается в setContext() функция, которая затем возвращает контекст в saveNewNotifications(newNotificationIds: [Int], newNotificationState: Bool). Затем вы создаете объект уведомлений, используя только что полученный контекст. Примерно так: let newNotification = Notifications(context: context)

Как только это будет сделано, вы можете установить для свойств объекта Notifications значение. newNotification.notificationState = newNotificationState
Примерно так : они соотносятся с атрибутами сущности, определенными в модели CoreData. Как только это будет сделано, останется только позвонить context.save. Убедитесь, что вы заключили его в do {} блок, как в приведенном выше классе. Теперь вы сохранили свой первый набор данных в CoreData!

Загрузка с вашей модели

После использования функции сохранения, загрузка будет казаться знакомой. Первым шагом в загрузке является установка контекста. Сделайте это, используя тот же метод, что и в функции сохранения. Затем установите запрос с помощью объекта Notifications и переименованной функции fetchRequest следующим образом: let request = Notifications.notificationFetchRequest()
Кроме того, не забудьте установить request.returnsObjectsAsFaults для параметра значение true. Если вы этого не сделаете, загрузка вернет записи, но не значение свойств. Вы можете прочитать об этом немного больше здесь Stackoverflow . Наконец, установите для переменной [Notification] типа значение context.fetch(request). Как это: extractValues = try context.fetch(request). Обязательно заключите это в do {} блок тоже. Я добавил в функцию некоторую логику завершения, чтобы убедиться, что ваши приложения получают загруженные данные перед продолжением работы. Вы можете прочитать больше о завершении в этом посте .

Заключение

CoreData – мощный и полезный фреймворк. Это продемонстрировало основы настройки модели CoreData. Если вам понравился этот пост и вы хотите узнать больше о CoreData, дайте мне знать, что еще вы хотели бы знать, в комментариях ниже. Спасибо за прочтение!

Ответить