iOS разработчик
0,0
рейтинг
4 декабря 2015 в 14:52

Разработка → Создание приложения ToDo с помощью Realm и Swift перевод tutorial

С развитием смартфонов в последние годы было разработано много инструментов, чтобы упростить жизнь разработчикам, обеспечив их максимальной производительностью и качеством. Занимать лидирующие позиций в App Store сегодня не простое задание. А научить ваше приложение масштабироваться еще сложнее. Когда приложением пользуются миллионы пользователей, вы должны следить за приложением и при необходимости выполнять все операции моментально. Поэтому одной из проблем, с которой сталкиваются многие разработчики, является Database. Она действительно вызывает сильную головную боль для каждого из нас, и я думаю, что сегодня у вас есть только два варианта: SQLite и Core Data. Я был большим поклонником Core Data и его способностью работать с записями и сохраняющимися данными, но я понял, что впустую трачу много времени, работая с ним при разработке приложений. Недавно, я столкнулся с Realm, новой лучшей заменой SQLite и Core Data.

Realm and Swift

Что такое Realm?


Realm — кросс-платформенная мобильная база данных для iOS (доступная в Swift & Objective-C) и Android. Realm была создана, чтобы стать лучше и быстрее, чем SQLite и Core Data. Она не только лучше и быстрее, но и простая в использовании, так вы можете сделать многое с помощью всего нескольких строк кода. Realm является совершенно бесплатной, и вы можете использовать ее без каких-либо ограничений. Realm создана для мобильных приложений, и это новинка, так как в последнее десятилетие, мы не замечали инноваций в мобильных базах данных. Теперь, чтобы работать с мобильной базой данных, у вас есть только один вариант, который является SQLite или любой оберткой, которая использует SQLite. Realm разработана, чтобы быть простой в использовании, так как она не ORM, и она использует свой собственный механизм персистентности для большей производительности и скорости выполнения.

Почему Realm?


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

  • Простая в установка: об этом Вы узнаете в следующем разделе о работе с Realm. Установить Realm более легко, нежели вы можете себе представить. С помощью простой команды в Cocoapods, вы перейдете к работе с Realm.
  • Быстрая: Realm — невероятно быстрая библиотека для работы с базой данных. Realm быстрее, чем SQLite и CoreData, и сравнительные тесты здесь — лучшее доказательство для этого.
  • Кросс-платформенная: файлы базы данных Realm кросс-платформенные и могут совместно использоваться iOS и Android. Независимо от того, Вы работаете с Java, Objective-C, или Swift, Вы будете использовать высокоуровневые модели.
  • Масштабируемая: масштабируемость очень важно рассмотреть при разработке мобильного приложения, если приложение работает с большим количеством пользователей и большим количеством записей. Вы должны учесть это с самого начала при проектировании и выборе инструментов. Realm готова к масштабируемости и работе с большими объемами данных в кратчайшие сроки. Вы привнесете скорость и сглаживания к Вашему приложению при использовании Realm.
  • Хорошо документированная и есть отличная поддержка: команда Realm предоставила читаемую, хорошо организованную документацию о Realm. Если у вас возникли проблемы, вы можете связаться с ними через Twitter, Github или Stackoverflow.
  • Надежная: Realm используется компаниями в мобильных приложениях, как Pinterest, Dubsmash, и Hipmunk..
  • Бесплатная: со всеми этими удивительными функциями Realm абсолютно бесплатна.


Давайте начнем


Давайте начнем работу с Realm, используем его для создания простого приложения под iPhone с помощью Swift. Демонстрационный проект будет простым Todo приложением. Пользователь может добавить Task в Task Lists (Списки задач), каждый список сможет содержать несколько задач. У задачи есть заголовок, примечания, дата, изображение, и булевское значение, которые указывают на ее завершение или наоборот. Перед началом работы с проектом в Xcode. Мы должны сначала настроить Xcode и установить необходимые инструменты для работы с Realm.

Требования


Пожалуйста, учитывайте следующие требования:
  • iOS 8 или выше, OS X 10.9 или выше.
  • Xcode 6.3 или выше.
  • У Realm есть две версии, одна для Swift 2.0 и другая для Swift 1.2. Мы рекомендуем использовать Realm для Swift 2.0. Вы можете использовать его для Swift 1.2, но она не будет больше поддерживаться командой Realm в будущем, так что для безопасности лучше использовать версию Swift 2.0.


Настройка Xcode и необходимых Tools


Прежде чем приступить к настройке проекта в Xcode, пожалуйста, убедитесь, что вы установили CocoaPods на ваш компьютер, поскольку мы будем использовать его для установки Realm в проект Xcode. Если Вы не знакомы с CocoaPods, вы можете ознакомиться онлайн с несколькими руководствами, и почерпнуть для себя дополнительную информацию для начала работы.

Теперь, создайте новый проект в Xcode с шаблоном “Single View Application” и назовите его “RealmTasks” или как угодно. Удостоверьтесь, что Swift выбран как язык разработки. Теперь перейдите к каталогу проекта в терминале и выполните следующую команду, чтобы инициализировать CocoaPods.
pod init

Тогда откройте файл pod, сгенерированный программой Xcode, и отредактируйте его, чтобы добавить pod ‘RealmSwift’ прямо после целевого объекта, таким образом, это должно выглядеть подобным образом:

pod RealmSwift

Далее выполните команду “pod install”, чтобы загрузить Realm в проект. После окончания, вы увидите новую workspace для Xcode, созданную рядом с файлом проекта. Пожалуйста, откройте workspace, RealmTasks.xcworkspace вам больше не прийдется открывать xcodeproj. После того, как Вы откроете workspace, Вы увидите что-то вроде этого:

workspace

Теперь Xcode готов работать с Realm, но нужно установить еще некоторые инструменты, чтобы еще больше упростить работу с Realm.

Установка плагина Realm для Xcode


Команда Realm предоставила очень полезный плагин для Xсode, который можно использовать для создания моделей Realm. Для установки плагина мы будем использовать Alcatraz. Для людей, которые не знают что такое Alcatraz, это — очень простой и полезный диспетчер пакетов с открытым исходным кодом для автоматической установки плагинов, шаблонов в XCode. Чтобы установить Alcatraz, просто вставьте следующую команду в терминале и затем перезапустите Xсode.
curl -fsSL https://raw.githubusercontent.com/supermarin/Alcatraz/master/Scripts/install.sh | sh

Тогда в Xcode, выберите Window и выберите Package Manager, как на следующем изображении:

Package Manager

Тогда откроется всплывающее окно, в нем выберите какой плагин или шаблон нужно установить для Xcode, в панели поиска вы можете искать любые плагины или шаблоны для настройки вашего Xcode. Ведите “Realm” в панели поиска, и плагин “RealmPlugin” появится, затем нажмите Install.

RealmPlugin

Realm Browser


Последний инструмент, о котором я хочу упомянуть — это браузер Realm. Этот браузер помогает Вам читать и редактировать свои .realm файлы баз данных. Эти файлы создаются в Вашем приложении со всей информацией о сущностях, атрибутах и записях в таблицах базы данных. Мы уже говорили, что эти файлы могут совместно использоваться различными платформами как iOS или Android. Чтобы загрузить инструмент браузера области действия посетите магазин iTunes для загрузки последней версии. Откройте приложение, тогда выберите Tools -> Generate demo database. Это создаст тестовый realm файл базы данных, и Вы сможете открыть и посмотреть его содержимое с помощью браузера. Это будет выглядеть следующим образом, когда Вы открываете свою демонстрационную базу данных:

Realm Browser

Как видите в классе RealmTestClass1, есть 1000 записей, и он показывает различные типы параметров (столбцы) этого класса. Мы погорим о типах свойства поддержки в следующих разделах.

Теперь все готово к работе с Realm. Давайте начнем.

Классы модели для базы данных


Теперь игра началась! Сначала мы создадим классы моделей или нашу базу данных. Чтобы создать классы моделей в Realm, просто создаете обычные классы Swift, которые расширяют класс объекта. Думайте об Объекте как о базовом классе для всех классов модели Realm, также можете расширить любой класс, которые расширяют Объект в конце. Как только вы создадите свой класс, вам понадобятся свойства. Realm поддерживает различные типы свойств следующим образом:
– Int, Int8, Int16, Int32, and Int64
– Boolean
– Float
– String
– NSDate
– NSData
– Class расширяет Object - используется для отношений 'один к одному'
– List <Object> - используется для отношений 'один ко многим'

List как и класс Realm содержит коллекцию экземпляров объекта, см. скриншот демонстрационной базы данных, последний столбец был просто массивом указателей для существующих записей в другой таблице. Работая с классами Realm, Вы должны знать, что можете справиться с ними, как и с любыми другими классами Swift. Например, Вы можете добавить методы или протоколы и использовать их как любой другой класс Swift.

Болтать — не мешки ворочать, покажите мне код!

Хорошо, теперь давайте использовать плагин Realm, который мы установили в Xcode, чтобы создать класс Realm. Перейдите в XCode и создайте новый файл. На правой боковой панели выберите Realm:

realm model

Тогда выберите Swift и введите имя класса в качестве Task. Теперь вы увидите нечто вроде этого:

Task swift

Теперь класс Task готов к добавлению новых свойств.

Свойства


Конечно, мы должны добавить свойства к классу Task. У задачи будет имя (String), createdAt (NSDate), примечания (String) и isCompleted (Bool). После добавления свойств, класс будет выглядеть следующим образом:
class Task: Object {
    
    dynamic var name = ""
    dynamic var createdAt = NSDate()
    dynamic var notes = ""
    dynamic var isCompleted = false
    
    
// Specify properties to ignore (Realm won't persist these)
    
//  override static func ignoredProperties() -> [String] {
//    return []
//  }
}

Мы добавили свойства для класса Task и добавили префикс var ко всем свойствам.

Затем, давайте создадим класс TaskList, который будет используется для сохранения задачи:
class TaskList: Object {
    
    dynamic var name = ""
    dynamic var createdAt = NSDate()
    let tasks = List<Task>()
    
// Specify properties to ignore (Realm won't persist these)
    
//  override static func ignoredProperties() -> [String] {
//    return []
//  }
}

У класса TaskList есть имя, createdAt и List — список задач. Здесь у нас есть некоторые замечания:

  • List <Object> используется для отношений «один ко многим», поскольку у TaskList есть много задач.
  • Список очень похож на массив, созданный в методах и получает доступ к объектам, используя индексированное преобразование в нижний индекс. List, как видите, набирается и все объекты должны быть одного типа.
  • List <T> является универсальным типом данных, и вот почему мы не добавляли динамическое свойство прежде, чем объявить свойство задач, потому что универсальные свойства не могут быть представлены вObjective-C во время выполнения задачи.

Создавать отношений в Realm довольно просто, как вы видели в предыдущих реализациях для отношений «один ко многим». И как мы уже говорили для отношений «один к одному» вместо списка , мы будем использовать тип объекта. Рассмотрим следующий пример:
class Person: Object{
    dynamic var name = ""
}
 
class Car: Object{
    dynamic var owner:Person?
}

В предыдущем примере свойство владельца действует как отношение «один к одному» к модели данных Person.

Теперь когда были созданы основные классы, я продолжу обсуждать с вами о Realm, создав простое приложение ToDo. Сначала загрузите приложение и посмотрите его. Запустите его в Xcode 7 (или выше), и Вы увидите следующее:

realm-todo-list-app

В проекте я добавил два контроллера представления: TasksViewController и TaskListViewController. Первый контроллер используется для отображения элемента задачи, в то время как второй контроллер используется для отображения всех доступных задач. В представлении списка нажмите кнопку +, чтобы добавить список задач. Выбор списка задач продолжится на следующем экране. Там Вы можете добавить несколько задач.

С основной идеей демо-приложения теперь давайте посмотрим, как добавить новый список задач в базу данных Realm. Чтобы сделать это, вам нужно будет обработать несколько элементов:

  • Создайте новый объект модели TaskList, и сохраните в Realm.
  • Сделать запрос для чтения списка из базы данных для обновления пользовательского интерфейса


Чтобы сохранить объекты в Realm, все, что вам нужно сделать — это создать подкласс модели объекта, и затем записать объект в Realm. Вот примера фрагмента кода, который вам нужен:
let taskListA = TaskList()
taskListA.name = "Wishlist"
        
let wish1 = Task()
wish1.name = "iPhone6s"
wish1.notes = "64 GB, Gold"
        
let wish2 = Task(value: ["name": "Game Console", "notes": "Playstation 4, 1 TB"])
let wish3 = Task(value: ["Car", NSDate(), "Auto R8", false])
 
taskListA.tasks.appendContentsOf([wish1, wish2, wish3])

Мы создаем список задач путем создания экземпляра класса TaskList и затем устанавливаем его свойства. Затем мы создаем 3 объекта типа Task (wish1, wish2 и wish3). Здесь я продемонстрировал 3 способа создания объектов Realm:

  1. В объекте wish1: просто создайте класс Realm и установите свойства.
  2. В объекте wish2: Вы можете передать свойства в словарь с ключами (имена свойств) и значения.
  3. В объекте wish3: Вы можете передать свойства, используя массивы. Значения в массиве должны быть в том же порядке, как и соответствующие свойства в объявлениях модели класса.


Вложенные объекты



Еще одна особенность при создании объектов в Realm – это вложенные объекты. Эта функция может использоваться, когда у вас есть «один к одному» или «один ко многим» отношения, которые означают, что у вас есть свойства типа Object или List<Object>. В этом случае, когда вы используете подход #2 или #3, Вы можете заменить объект массивом или словарем, представляющие его свойства. Вот пример вложенных объектов:
let taskListB = TaskList(value: ["MoviesList", NSDate(), [["The Martian", NSDate(), "", false], ["The Maze Runner", NSDate(), "", true]]])

В вышеупомянутом коде мы создаем список фильмов и задаем имя, createAt, и массив задач. Каждая задача создана, используя массив свойств. Например [“The Maze Runner”, NSDate(), “”, имеют значение true] представлябт задачу с именем, createAt, примечаниями и булевской переменной isCompleted или наоборот.

Сохранение объектов в Realm


Теперь Вы должны знать, как создать объекты Realm и использовать их в любое время, вы должны сохранить их в базу данных Realm с транзакциями записи. Когда сохраняете данные в Realm, вы можете получить доступ к этим объектам в любом потоке, пока они сохраняются в Realm. Чтобы выполнить транзакцию записи, у вас должен быть объект Realm. Экземпляр Realm (также упоминается как область действия) представляет базу данных Realm. Вы можете создать экземпляр следующим образом:
let uiRealm = try! Realm()

Мы используем, чтобы добавить эту строку вверху AppDelegate.swift, чтобы совместно использовать объект через все файлы Swift. Позже вы можете легко вызвать метод записи как этот:
uiRealm.write { () -> Void in
            uiRealm.add([taskListA, taskListB])
        }

Сначала объект uiRealm создается в классе AppDelegate и будет совместно использован приложением. Объект Realm должен быть создан только один раз, потому что он не ориентирован на многопотоковое исполнение и не может быть совместно использован потоками. Если вы хотите выполнить операцию записи в другом потоке, тогда вы должны создать новый объект Realm. Я назвал его как “uiRealm”, поскольку этот экземпляр определен для UI потока.

Теперь давайте вернемся к нашему приложению, мы сохраняем списки задач после того, как пользователь нажимает кнопку Create. В displayAlertToAddTask методе TasksViewController у нас есть объект createAction:
let createAction = UIAlertAction(title: doneTitle, style: UIAlertActionStyle.Default) { (action) -> Void in
    
    let taskName = alertController.textFields?.first?.text
    
    if updatedTask != nil{
        // update mode
        uiRealm.write({ () -> Void in
            updatedTask.name = taskName!
            self.readTasksAndUpateUI()
        })
    }
    else{
        
        let newTask = Task()
        newTask.name = taskName!
        
        uiRealm.write({ () -> Void in
            
            self.selectedList.tasks.append(newTask)
            self.readTasksAndUpateUI()
        })
    }
}

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

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

Извлечение Объектов


Теперь, когда вы узнали, как записивать данные в Realm, но это бесполезно, не зная, как получить их назад! Запрашивание базы данных Realm очень просто. Вам предоставляются много опций настройки и фильтрации данных. При выполнении запроса в Realm, он возвращает список объекта Results. Просто думайте о Results как о массиве Swift, ведь его интерфейс очень похож на массив.

Когда у Вас есть экземпляр Results, вы получить данные напрямую с диска. Любые изменения данных (в транзакциях) приведут к изменению данных на диске. В Realm, чтобы запросить объекты, просто вызываете метод объекта с именем класса в качестве параметра. Давайте посмотрим, как использовать его, чтобы прочитать TaskLists и обновить UI:

Мы определили это свойство в TasksListsViewController:
var lists : Results<TaskList>!

И реализуем метод readTasksAndUpdateUI следующим образом:
func readTasksAndUpdateUI() {    
    lists = uiRealm.objects(TaskList)
    self.taskListsTableView.setEditing(false, animated: true)
    self.taskListsTableView.reloadData()
}

И в методе tableView (_: cellForRowAtIndexPath: _), мы отображаем список имен и количество задач внутри этого списка:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
    
    let cell = tableView.dequeueReusableCellWithIdentifier("listCell")
    
    let list = lists[indexPath.row]
    
    cell?.textLabel?.text = list.name
    cell?.detailTextLabel?.text = "\(list.tasks.count) Tasks"
    return cell!
}

Довольно просто, не так ли? Последнее, что нужно сделать так это, вызвать функцию readTasksAndUpdateUI в методе viewWillAppear, чтобы удостовериться, что представление всегда обновляется, при его открытии.
override func viewWillAppear(animated: Bool) {
    readTasksAndUpdateUI()
}

Вот как мы читаем и пишем списки задач с использованием Realm. Далее, вы узнаете, как выполнять операции обновления или удаления в Realm. Прежде чем начать, давайте пройдемся по некоторым фрагментам кода в шаблоне проекта для редактирования/удаления операций из списков.

Сначала у нас есть булевское значение в TaskListsViewController, названное isEditingMode, которое используется для переключения между режимами редактирования и обычным:
var isEditingMode = false

Когда нажмете на кнопку Edit, будет вызван метод didClickOnEditButton:
@IBAction func didClickOnEditButton(sender: UIBarButtonItem) {
    isEditingMode = !isEditingMode
    self.taskListsTableView.setEditing(isEditingMode, animated: true)
}

Это действие позволит включить/отключить режим редактирования UITableView с помощью метода setEditing в UITableView. В UITableView, стандартное действие в режиме редактирования в ячейках появится действие «удаления», но начиная с iOS 8.0, новый метод, под названием editActionsForRowAtIndexPath был добавлен в UITableViewDelegate, чтобы настроить действия, которые будут отображаться в ячейках, когда пользователь проводит по них пальцем.

Мы реализуем этот метод, чтобы добавить два действия: удаления и редактирование следующим образом:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
    let deleteAction = UITableViewRowAction(style: UITableViewRowActionStyle.Destructive, title: "Delete") { (deleteAction, indexPath) -> Void in
        
        //Deletion will go here
        
        let listToBeDeleted = self.lists[indexPath.row]
        uiRealm.write({ () -> Void in
            uiRealm.delete(listToBeDeleted)
            self.readTasksAndUpdateUI()
        })
    }
    let editAction = UITableViewRowAction(style: UITableViewRowActionStyle.Normal, title: "Edit") { (editAction, indexPath) -> Void in
        
        // Editing will go here
        let listToBeUpdated = self.lists[indexPath.row]
        self.displayAlertToAddTaskList(listToBeUpdated)
        
    }
    return [deleteAction, editAction]
}

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

edit mode

Вот как выглядит интерфейс приложения для удаления и обновления.

Удаление Объектов


Для удаления объектов и данных из базы данных Realm, можно просто вызвать метод delete объекта Realm, передав объект для удаления. И, конечно, это нужно сделать в транзакции записи. Взгляните на следующий код, который показывает, как мы удаляем список задач из базы данных:
let listToBeDeleted = self.lists[indexPath.row]
uiRealm.write({ () -> Void in
           uiRealm.delete(listToBeDeleted)
           self.readTasksAndUpdateUI()
    })

После удаления мы вызывали функцию readTasksAndUpdateUI, чтобы получить новые данные и обновить UI.

Вместо удаления одного объекта, есть еще одна функция под названием deleteAll, которая позволяет удалить все данные для всех классов в базе данных. Этот метод очень полезный, когда вы сохраняете данные для текущего пользователя, и хотите очистить базу данных, когда он выходит из системы.
uiRealm.write({ () -> Void in
    uiRealm.deleteAll()
})

Обновление Объектов


В Realm существуют множество способов обновить объекты, но все они должны быть выполнены внутри транзакции записи. Ниже мы рассмотрим некоторые подходы для обновления объектов.

Использование свойств



Можно обновить любой объект Realm просто набором свойств с новым значением внутри блока записи. Например, в TasksViewController, мы, просто, изменяем состояние задачи, установив свойство:
uiRealm.write({ () -> Void in
    task.isCompleted = true
})

Использование первичных ключей



Realm поддерживает маркировку одной строки или свойства int на объекте в качестве первичного ключа. При создании объекта Realm с помощью функции add(), если ключ уже существует, то объект будет обновлен новыми значениями.

Вот пример:
let user = User()
user.firstName = "John"
user.lastName = "Smith"
user.email = "example@example.com"
user.id = 1
// Updating User with id = 1
realm.write {
            realm.add(user, update: true)
        }

Идентификатор установлен как первичный ключ. Если пользователь с id 1 существует, то Realm обновит объект соответственно. В противном случае, Realm вставит объект в базу данных.

Использование KVC (Key-Value Coding)



Если вы — опытный iOS разработчик, вы должны быть знакомы с key-value coding. Классы Realm как Object, Results, и List являются KVC совместимыми. Это помогает устанавливать/обновлять свойства в среде выполнения. Еще одна интересная особенность соответствие KVC в List и Results, заключается в том, что вы можете обновить объекты коллекции в целом без необходимости итерации по каждому объекту и их обновления. Я знаю, что Вы не можете понять это полностью. Давайте рассмотрим этот пример:
let tasks = uiRealm.objects(Task)
uiRealm.write { () -> Void in
    tasks.setValue(true, forKeyPath: "isCompleted")
}

В приведенном выше коде, я сделал запрос на получение всех объектов Task, и присвоил isCompleted значение true для всех возвращаемых объектов. Это означает, что я отметил все задачи в базе данных как завершенные с помощью всего одной строки кода.

Давайте вернемся к нашему приложению ToDo. Если вы снова посмотрите на метод displayAlertToAddTaskList, то найдете следующий фрагмент кода:
// update mode
 uiRealm.write({ () -> Void in
           updatedList.name = listName!
           self.readTasksAndUpdateUI()
 })

Он выполняется, когда пользователь редактирует список имен. Мы просто обновляем список имен, задав свойство name.

Отображение задач


Я познакомил Вас с большую часть кода в TaskListViewController. Теперь давайте взглянем на TasksViewController, который используется для отображения элемента задачи в списке задач. У контроллера есть UITableView, которая разделена на два раздела: завершенные и открытые задачи. В TasksViewController, у нас есть эти свойства:
var selectedList : TaskList!
var openTasks : Results<Task>!
var completedTasks : Results<Task>!

selectedList используется для хранения выбранного списка задач, переданного TaskListsViewController. Чтобы отфильтровать задачи по состоянию: открытые или завершенных, мы объявляем две переменные: openTasks и completedTask. Для фильтрации, мы будем использовать волшебный функциональный filter() с Realm. Давайте посмотрим, как он выглядит в коде, прежде чем я объясню вам, как работает фильтрация:
func readTasksAndUpateUI(){
    
    completedTasks = self.selectedList.tasks.filter("isCompleted = true")
    openTasks = self.selectedList.tasks.filter("isCompleted = false")
    
    self.tasksTableView.reloadData()
}

В методе мы вызываем метод фильтра для фильтрации результатов. Realm обеспечивает простой способ, чтобы фильтровать Ваш запрос, используя метода filter(). Метод может вызываться экземплярами списка, результата и объекта. Он возвращает конкретные объекты на основе условия, заданного в строке фильтра. Вы можете думать о фильтре как о NSPredicate. В общем можно сказать, что они абсолютно одинаковые. Вы можете создать NSPredicate со строкой предиката и передать его, чтобы фильтровать метод как при фильтрации выполненных задач.

Давайте посмотрим на другой пример:
// using predicate string
var redCars = realm.objects(Car).filter("color = 'red' AND name BEGINSWITH 'BMW'")
 
// using NSPredicate
let aPredicate = NSPredicate(format: "color = %@ AND name BEGINSWITH %@", "red", "BMW")
redCars = realm.objects(Car).filter(aPredicate)

В приведенном выше коде, мы фильтруем эти автомобили по красному цвету, и чье название начинается с “BMW”. Первая строка кода просто использует строки фильтрации для выполнения фильтрации. В качестве альтернативы можно использовать NSPredicate для достижения тех же результатов. Вот таблица, которая кратко описывает наиболее распространенные операторы сравнения фильтра:

realm-database-info

Сортировка


Теперь, когда мы поговорили об основных операциях базы данных Realm, есть еще одна особенность, которую я хочу представить до конца этого руководства. Сортировка — это еще одна полезная функция, предоставляемая Realm. В List и Results, можете вызвать метод сортировки, чтобы отсортировать коллекцию данных. Давайте посмотрим, как использовать его, чтобы сортировать задачи в списке по алфавиту или по дате создания. Сначала в UI мы добавим сегментированное управление, чтобы отсортировать список на основе выбора:

Screen

И для выполнения сортировки, основанной на выборе, логика будет реализоваться следующим образом:
@IBAction func didSelectSortCriteria(sender: UISegmentedControl) {
        
        if sender.selectedSegmentIndex == 0{
            
            // A-Z
            self.lists = self.lists.sorted("name")
        }
        else{
            // date
            self.lists = self.lists.sorted("createdAt", ascending:false)
        }
        self.taskListsTableView.reloadData()
    }

Заключение


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

Что дальше?


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

Полный исходный код для Todo app вы можете посмотреть здесь.
Перевод: Hossam Ghareeb
Dima @yarmolchuk
карма
4,0
рейтинг 0,0
iOS разработчик
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (18)

  • +1
    Еще бы Observable сюда =)
  • +3
    Машинный перевод и куча ошибок представлено в текст, дай глазу вытекать на клавиатуру
    По сути поста: интересно, спасибо.
  • +2
    Не знаю, как там в iOS, но на Android Realm не всегда удобнее даже чистого SQLite (наследование сущностей от специального класса, создание классов строго определенным образом, собственные структуры данных, иногда рандомные ошибки, миграции, которые завезли буквально вчера-позавчера). Да и насчет скорости не уверен, основательных замеров не находил. Хотя идея интересная, конечно.
    • 0
      В прошлом году создавали с друзьями приложение на Realm. Нам важна была скорость работы базы. Не помню где, но находили статистику, которая говорит о том, что Realm в 3 раза, если не ошибаюсь, превосходить SQLite как по записи, так и по чтению.
      • +1
        Ну, это официальная статистика так говорит. Я недавно нашел тест на гитхабе, выводы такие:
        From the completed tests, we can see that Realm is slightly faster than SQL when it comes to individual transactions, but SQL still has a small advantage when it comes to bulk transactions.

        Но я не смотрел код и как он мерял, так что нельзя сказать, что это авторитетный тест. Но, по крайней мере, независимый вроде.
        • 0
          Они сами приводят статистику realm.io/news/introducing-realm/#fast
          • 0
            Ну, это официальная статистика так говорит

            Я бы удивился, если бы выставили статистику, выставляющую их в неприглядном свете :)
  • 0
    На Swift не написать приложение для iOS ниже 7ой версии, а с Realm ещё и iOS 7 за бортом?
    • 0
      iOS 7 cannot be supported because it does not allow using 3rd party dynamic frameworks, and it is impossible to build static libraries that contain Swift code.
    • 0
      Если быть точнее то по требованиям:

      Objective‑C
      Apps using Realm can target: iOS 7 or later, OS X 10.9 or later & WatchKit.

      Swift
      Apps using Realm can target: iOS 8 or later, OS X 10.9 or later & WatchKit.
      • –1
        Значит в настоящий момент это решение не для меня. Я не готов сужать аудиторию, мне хватает что пользователи iOS 5 и 6 не могут поставить мои приложения. Мне кажется, что библиотека, претендующая на замену стандартных способов хранения данных, должны быть максимально совместимыми.
        • +1
          А оправдан ли отказ от современных технологий из-за пользователей, количество которых можно пересчитать по пальцам одной руки?
          Это конечно сильно зависит от проекта, но пока у меня не хватило фантазии представить такой проект в котором действительно было бы важно сейчас поддерживать хотя бы iOS 7, т. к. iOS 8 поддерживается далеко не самыми новыми устройствами от Apple.
          • 0
            Для меня сейчас такой отказ оправдан и я это поясню.
            1) про современные технологии — это с моей стороны они более современные и удобные, пользователь не получит больше функций от того, что я сменю тип хранения данных. Если бы это была супер-фича, к примеру, возможность через камеру телефона проектировать видео на стену, я бы не сомневался)
            2) про количество устройств с iOS 7 — если коротко, то оно вполне велико. Дело в том, что для обновления на более современную версию iOS требуется место на устройстве, а у многих забитые под завязку устройства на 8/16 Гб. Они, конечно, поддерживают iOS 9, но что толку, если пользователям некуда его поставить.
            Как уже писал, мои приложения на Swift — для меня минимальная версия iOS 7.
            Вот статистика по пользователям одного из моих приложений за последний месяц: 36.5% — iOS7, 32,5% — iOS8, 31% — iOS9.

            Вы правда считаете, что мне стоит сменить тип хранения данных и потерять при этом треть аудитории пользователей iOS? Я на это пойти не готов.
  • +3
    На сколько я понял Realm – это проприетарное решение за 0$, с опенсорсными байндингами к Java и Cocoa в которое всё дружно грузят данные своих приложений.

    Это звучит хорошо и красиво, но в чём подвох?
    С точки зрения безопасности подключение подобных библиотек может сулить довольно большой брешью.
    Не то что бы я был прям таким «большой брат...» и всё такое, но вот если какие-то весёлые ребята найдут что-то и будут сливать платёжную информацию — будет весело.
    • +1
      realm-jni — это что тогда? Можете изучить код, или даже собрать сами, коль боитесь бинарника. Большинство теорий заговора появляется от поспешных выводов.
      • 0
        Наличие списка API функций и их аргументов отнють не гарантирует отсутствие дыр непосредственно в самой реализации.
        Намеренное переполнение буферов, со всеми последствиями, никто не отменял.
      • 0
        Изучить код биндингов в Java?

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