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, нажав Файл > Создать > Файл…, а затем выберите Модель данных. Дайте ему имя, например DataModel.xcdatamodeld.
Снимок экрана 28 апреля 2019 г., 17.05.52.pngДобавьте новый файл в свой проект, нажав «Файл» > «Создать» > «Файл…» и выбрав «Модель данных».

Скриншот 28.04.2019 в 17.10.19.pngДайте модели подходящее имя.

CoreData поставляется с графическим интерфейсом для разработки вашей модели данных. Ниже приведен пример объекта, который хранит идентификатор и состояние уведомления. Ваша модель данных работает аналогично стандартному классу в Swift. Сущность эквивалентна классу. Атрибуты эквивалентны свойствам в классе. В CoreData ваша модель данных определяет объект данных, который вы хотите сохранить.
Снимок экрана 28 апреля 2019 г., 17:36:16.pngВ CoreData ваша модель данных определяет объект данных, который вы хотите сохранить.

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

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

Первым шагом в работе с моделью CoreData является создание подклассов NSManaged. Я показал шаги на изображениях ниже.
Снимок экрана 30 мая 2019 г., 14:37:37.pngШаг 1. Попросите Xcode сгенерировать ваши подклассы NSManaged.

Снимок экрана 30 мая 2019 г., 14:41:10.pngШаг 2. Выберите свою модель данных.

Снимок экрана 30 мая 2019 г., 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(). Почему Apple заставляла свой сгенерированный код делать это, мне не понятно. Итак, переименуйте вашу функцию fetchRequest в файле extension. Надеюсь, это сэкономит вам время на отслеживание этой проблемы.

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

Я включил класс в это руководство, чтобы показать вам, как работать с подклассом 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). Затем вы создаете объект Notifications, используя только что полученный контекст. Как это :
let newNotification = Notifications(context: context)
Как только это будет сделано, теперь вы можете установить свойства объекта Notifications в значение. Как это: newNotification.notificationState = newNotificationState
Они соответствуют атрибутам сущности, определенным в модели CoreData. Как только это будет сделано, останется только позвонить context.save. Убедитесь, что вы заключили его в do {} блок, как в приведенном выше классе. Вы сохранили свой первый набор данных в CoreData!

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

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

Вывод

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

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *