Статьи

Основные данные iPhone: ваши первые шаги

Core Data — это инфраструктура, которую Apple предоставляет разработчикам, которая описывается как «управляемая схемой структура графов объектов и постоянство». Что это на самом деле означает? Инфраструктура управляет тем, где хранятся данные, как они хранятся, кэширование данных и управление памятью. Он был портирован на iPhone из Mac OS X с выпуском 3.0 iPhone SDK.

В этом руководстве я собираюсь рассказать вам о процессе создания проекта с использованием Core Data и покажу, как его использовать с простым UITableViewController. Это будет простая однотабличная база данных, в которой будут храниться данные о времени прохождения круга и отображаться время и их различия в UITableView.

Прежде чем мы начнем, важно понять, почему вы можете использовать Core Data с SQLite для хранения списков свойств, пользовательского формата XML или прямого доступа к базе данных SQLite. Базовый API данных позволяет разработчикам создавать и использовать реляционную базу данных, выполнять проверку записей и выполнять запросы, используя условия без SQL. По сути, он позволяет вам взаимодействовать с SQLite в Objective-C и не беспокоиться о соединениях или управлении схемой базы данных, и большинство этих функций знакомы людям, которые использовали технологии объектно-реляционного отображения (ORM), подобные тем, которые реализованы в Ruby. на Rails, CakePHP, LINQ или других библиотеках и средах, которые абстрагируют доступ к базе данных. Основным преимуществом этого подхода является то, что он устраняет время разработки, в противном случае необходимо писать сложные запросы SQL и вручную обрабатывать SQL и вывод этих операций.

Пример приложения, которое мы будем создавать сегодня, — простой таймер круга. Это создаст новую запись в Базовом хранилище данных для каждого круга, который мы делаем. UITableView покажет разницу между текущим и последним кругами.

основной таймер круга данных окончательный предварительный просмотр

Для начала мы откроем XCode и создадим новый проект. Назовите его как хотите, я назвал его «LapTimer». Мы будем создавать «оконное приложение» из шаблона «Новый проект». Убедитесь, что установлен флажок «Использовать основные данные для хранения».

новый экран проекта основных данных

Проект должен быть знаком с тем, что вы, возможно, видели раньше, если ранее разрабатывали приложения для iPhone.

Не так много настроек, так как опция «Использовать базовые данные для хранения» в шаблоне «Приложение на основе окна» автоматически установила для нас некоторые важные переменные и созданные файлы в проекте.

В файле LapTimer.xcdatamodel мы определим схему для нашей базы данных SQLite. Базовая структура данных также была добавлена ​​в проект для включения файлов для доступа к API. Другие изменения вносятся в файлы приложения по умолчанию. В частности, файлы делегатов приложения имеют методы для настройки основного хранилища данных в нашем приложении и ссылки на него в дочерних UIViewControllers.

На данный момент нас интересует файл LapTimer.xcdatamodel в разделе «Ресурсы». Этот файл дает вам визуальную карту вашей схемы, показывающую сущности и атрибуты.

В Базовых данных используются некоторые разные термины и фразы, которые могут быть слабо связаны с обычными именами баз данных, но они не идентичны.

«Сущность», также известная как «управляемый объект», похожа на таблицу. Это определение объекта, который будет содержать коллекцию данных. Объект сущности содержит «атрибуты». Они могут быть слабо связаны со столбцами, но эти атрибуты не ограничиваются только хранением данных. Атрибуты могут определять отношения между двумя объектами, динамически извлекаемое свойство или определять свойство для хранения данных.

диаграмма данных ядра iphone

На диаграмме выше вы можете почувствовать, насколько гибкими являются объекты, полученные из сущностей базовых данных. Для этого примера приложения нам понадобится действительно простая сущность. Мы назовем объект «Событие», который будет хранить записи наших кругов.

модель данных ядра iphone

Чтобы создать эту сущность, мы нажмем кнопку [+] в первом (слева) верхнем столбце. Это создаст новый объект в списке и визуально на карте схемы под столбцами.

управляемый объект данных ядра iphone

Это хороший визуальный редактор для вашей модели. Core Data действительно делает тяжелую работу, когда дело доходит до «M» (модель) части MVC. Визуальный редактор показывает отношения, свойства и сущности хранилища, пока схема динамически создается и управляется всеми для вас. Это похоже на Интерфейсный Разработчик, поскольку он заботится о распределении, управлении и размещении объектов для вас в UIView без единой строки кода.

С новой сущностью Event мы хотим создать «свойство». Поскольку это свойство будет хранить данные, мы установим его как «атрибут». Таким образом, этот новый атрибут будет просто хранить текущую дату, когда была создана запись. В нашем примере приложения мы будем использовать это для ссылки на наше время круга.

В следующем столбце справа мы определяем наши свойства (убедитесь, что выбран объект Event). Итак, создайте новое свойство, используя кнопку [+] в столбце, выберите «Добавить атрибут».

атрибуты данных ядра iphone

Мы будем называть атрибут «timeStamp» и устанавливать его тип «Date». В раскрывающемся списке выбора типов есть типы данных столбцов, аналогичные тем, которые доступны в системах реляционных баз данных, таких как PostgreSQL или MySQL, включая типы данных, такие как целые числа, числа с плавающей запятой, строки, логические значения, даты и двоичные данные (большие двоичные объекты).

Для этого атрибута нам не нужны никакие другие параметры, выбранные или измененные.

Вот и все для файла xcdatamodel, и мы можем перейти к его интеграции в наше приложение. Сейчас самое время сохранить вашу работу.

Если вы использовали инфраструктуру MVC, которая имеет определения модели базы данных, определяющие структуру или поведение таблицы, то это будет знакомая задача.

Нам нужно начать с создания определения сущности. Мы делаем это путем создания класса NSManagedObject объекта и определяем переменные, которые есть в хранилище.

Это простой процесс. Выберите объект «Событие» в файле LapTimer.xcdatamodel и выберите «Файл»> «Новый файл». Вы увидите, что в разделе «Класс касания какао» появился новый шаблон файла, который называется «Класс управляемых объектов».

новый класс управляемых объектов

Выберите шаблон и нажмите «Далее». Следующий экран просто определяет, где мы сохраняем файл и цель, к которой он будет добавлен. По умолчанию все это правильно, поэтому снова нажмите «Далее». На следующем экране вы определяете, для каких сущностей вы хотите создать классы NSManagedObject. Если он не выбран, выберите «Событие» и убедитесь, что установлены флажки «Сгенерировать средства доступа» и «Сгенерировать свойства Obj-C 2.0», в настоящее время нам не нужны проверки. Нажмите Finish.

генерация класса управляемого объекта

Итак, теперь у нас есть 2 новых файла в нашем приложении. Event.m и Event.h. Они определяют класс NSManagedObject для сущности Event, которую мы создали в нашем Базовом хранилище данных. Они определяют поле timeStamp, поэтому, когда мы хотим использовать класс Event, мы можем получить доступ к атрибуту.

Event.h

Event.m

Как и определения моделей в других платформах и языках, вы можете добавлять собственные методы для всех записей в сущности Event. Вы заметите, что атрибут timeStamp был добавлен и назначен как объект NSDate.

Теперь с настройкой Core Data пришло время поработать над некоторой логикой контроллера в приложении. Мы будем использовать UITableViewController в качестве основного интерфейса приложения, чтобы показывать время прохождения круга, а также записывать новое время.

Итак, мы создадим новый UITableViewController с File> New File. Затем в разделе iPhone выберите «UIViewController subclass» и установите флажок «UITableViewController subclass», но не устанавливайте флажки, связанные с использованием XIB или для ориентации на iPad. Мы не будем использовать XIB для этого контроллера. Вызовите новый файл «TimeTableController» и завершите работу мастера файлов.

В этом контроллере нам понадобятся 2 свойства: ссылка на NSManagedObjectContext и массив для хранения записей для UITableView. Помимо определения этих свойств, мы импортируем файл Event.h, чтобы мы могли использовать класс.

TimeTableController.h

Что такое NSManagedObjectContext? Он называется «блокнотом» для Core Data в приложении для управления извлечением, обновлением и созданием записей в хранилище. Он также управляет несколькими фундаментальными функциями в Core Data, включая проверки и управление отменой и повторением записей.

Контекст управляемого объекта — это связь между вашим кодом и хранилищем данных. Все операции, которые вы будете выполнять для Базовых данных, будут выполняться в контексте управляемого объекта. Когда запрос выполняется, контекст управляемого объекта будет затем общаться с постоянным координатором хранилища, который отвечает за сопоставление объектов с данными для хранилища данных. Это позволяет базовым данным быть гибкими между различными форматами хранилища данных. Вот схема того, как это выглядит.

диаграмма данных ядра iphone 2

Определив заголовочный файл, мы должны распространить выделенные свойства и методы в файле реализации.

TimeTableController.m

Это довольно много кода, поэтому давайте пройдемся по каждому методу в отдельности. Есть код от того, когда вы создаете файл из шаблона, закомментированные методы, такие как viewDidUnload, которые я только что исключил из приведенного выше.

Мы начинаем с обычного звонка в суперкласс. Затем мы определяем заголовок UINavigationBar. После этого нам нужно определить кнопку, которую мы будем использовать для добавления записи в хранилище Core Data. Когда кнопка нажата, мы говорим ей вызвать селектор addTime: который затем будет взаимодействовать с Core Data. После необходимых выпусков мы переходим к вызову функции fetchRecords, что объясняется ниже.

Это срабатывает при нажатии UIBarButtonItem в верхнем правом углу UINavigationBar. Нам нужно создать новую запись о событии с текущей NSDate и сохранить ее в базе данных.

Мы создаем новую запись события, которая называется NSEntityDescription. Это ваша строка в базе данных для новой записи. Для этого мы определяем имя сущности, к которой принадлежит запись, и предоставляем NSManagedObjectContext. Текущая дата затем устанавливается на атрибут timeStamp.

Затем выполняется операция сохранения, но существует условие для обработки ошибки в случае сбоя вставки. Обычно вы бы выдавали UIAlertView, говоря, что запись не была создана, и, возможно, предлагали бы пользователю повторить попытку или закрыть и снова открыть приложение.

Запись должна быть добавлена ​​в массив, из которого поступает UITableView. Затем необходимо указать UITableView для перезагрузки данных. Вы можете сделать это более графически с помощью анимации, но ради учебника давайте сделаем это проще.

Этот метод получит данные из хранилища и добавит их в массив, который есть в контроллере. Для получения дополнительной информации о получении записей давайте внимательно рассмотрим NSFetchRequest.

Core Data использует другой подход для извлечения данных из своей базы данных. Это хранилище данных NoSQL, означающее, что все условия запроса основаны на методах. Это замечательно, поскольку базовое хранилище, которое представляет собой SQLite, может быть изменено на любую другую технологию баз данных, и единственное, что нужно изменить, это подключение и драйверы для базы данных.

Итак, для создания запроса мы создаем объект NSFetchRequest. Это базовый объект, против которого будут установлены условия запроса. Мы можем определить условия для сопоставления конкретного свойства на основе порядка упорядочения записей. Вы можете узнать больше о Базовых данных и их условиях для NSFetchRequests в их документации.

Создать новый запрос NSFetch просто. Вам просто нужно определить сущность, от которой вы хотите получить записи, и NSManagedObjectContext.

Сущность определяется с использованием объекта NSEntityDescription, для которого требуется имя сущности и NSManagedObjectContext. Запрос выборки тогда создан, передавая описание объекта. Это будет соответствовать первой части инструкции SQL:

В нашем примере приложения мы сортируем данные по timeStamp по убыванию. Для этого мы используем NSSortDescriptor.

NSSortDescriptor создан, и мы определяем атрибут, который мы хотим отсортировать, и убираем ли он по возрастанию, в этом случае мы хотим, чтобы он спускался, поэтому для него установлено значение NO. Запрос на выборку может принимать много дескрипторов сортировки, поэтому он принимает массив при установке дескрипторов сортировки. Поскольку нам нужен только один, нам просто нужно создать массив с одним объектом в нем. Мы устанавливаем массив дескрипторов для запроса на выборку, и это все.

Для определения условия соответствия содержимому записи в игру вступает класс NSPredicate. Это позволяет запросу выборки соответствовать или определять диапазон, которому должно соответствовать содержимое записи. Это эквивалент ваших равных, больше и меньше совпадений в SQL. Он имеет больше, чем ваши основные функции SQL, которые вы можете увидеть здесь.

Установка предиката может быть очень простой.

Использование NSPredicate ForexateWithFormat: это простой и знакомый метод, который позволяет определять условия запроса. Для подробного объяснения NSP-предикатов в документации Apple есть несколько замечательных руководств.

Когда вы определили условия в своем запросе на выборку, вы можете выполнить его.

Это вернет массив объектов-сущностей, NSManagedObjects, для использования в ваших данных.

Получив данные из Core Data и сохранив их в eventArray, мы теперь можем вывести эти записи в UITableView.

Прежде всего, нужно сообщить таблице, что нам потребуется только 1 раздел и сколько строк нам нужно использовать.

Выдержка из TimeTableController.m

Если вы ранее использовали UITableViewController, следующая функция должна быть прямой.

В ячейке будут отображаться 2 значения из стиля UITableViewCellStyleValue1. Слева будет время круга, а справа будет разница в секундах от предыдущей записи.

Поскольку этот метод повторяется, мы должны быть особенно внимательны с нагрузкой, которую оно может поставить под устройство, если оно не управляется правильно. По этой причине NSDatFormatter хранится как статическая переменная, поэтому его можно использовать повторно в каждой итерации, не выделяя и не освобождая его каждый раз.

Ленивая загрузка — это метод, при котором вы максимально задерживаете запрос или выделение свойства. Это помогает сохранить память и во время итеративных функций это имеет первостепенное значение. Знание того, когда и как распределять данные, крайне важно для поддержания скорости мобильного приложения. Распределение объекта также важно, чем раньше, тем лучше.

cellForRowAtIndexPath: является итеративным методом, и любые данные, обрабатываемые или выделяемые в этом методе, особенно необходимо сохранять как минимум. Этот метод запускается всякий раз, когда в поле зрения появляется ячейка, поэтому, когда пользователь быстро прокручивает этот конкретный метод, в зависимости от размера набора записей, его можно вызывать очень часто подряд.

Следующая задача — получить объект события, связанный со строкой таблицы, которую необходимо отобразить. Поскольку нам нужно получить предыдущую запись для сравнения времени, существует простая проверка, чтобы увидеть, есть ли предыдущая запись, и сохранить ее в previousEvent. Если предыдущее событие существует, то мы вычисляем разделение, используя [NSDate timeIntervalSinceDate: (NSDate)]. Затем textLabel и detailsTextLabel устанавливаются с помощью вычисленных нами значений.

С установкой UITableViewController и источником данных таблицы, работающим с хранилищем базовых данных, все, что нужно, это загрузить контроллер при запуске приложения.

В контроллере приложения необходимо определить свойство UINavigationController. Затем метод applicationDidFinishLaunching просто должен выделить контроллер, и все готово.

LapTimerAppDelegate.h

Выдержка из LapTimerAppDelegate.m

Файл TimeTableController.h включается в делегат приложения и затем выделяется с помощью UINavigationController.

Это должно быть так. Создайте приложение, чтобы проверить наличие ошибок. Некоторые примеры кода были только выдержками, ни один код, созданный при создании файла, не был удален, а только заполнен. Если вы столкнетесь с ошибками, которые не можете взломать, вы можете скачать файл проекта, прикрепленный к этому учебному пособию. который вы можете затем скомпилировать и сравнить.

Запустите приложение. Вы увидите навигационный контроллер и кнопку добавления. Нажмите кнопку добавления, и вы получите новое время в таблице.

В этом руководстве мы создали пример приложения для хранения простых данных в хранилище Core Data. Приложение прошло процедуру начальной настройки при создании приложения с Core Data, определении структуры данных и извлечении записей из хранилища данных.

Надеемся, что вы ознакомились с Core Data и увидели, как легко им пользоваться и как они могут повысить производительность и функциональность ваших приложений.

Если вы хотите узнать больше о Core Data или детально взглянуть на структуру фреймворка, то документация для разработчиков Apple — идеальное место.

Документация для разработчиков Apple:

Введение в программирование основных данных

Основная миграция данных и управление версиями

Руководство по программированию NSPredicate: