Pull to refresh

UITableView+sqlite3 для самых маленьких

Reading time 6 min
Views 31K
Предисловие

Приветствую вас хабролюди. Недавно сбылась мечта всей моей жизни и я купил себе Mac (13’ unibody). Поздний 2008, но для нашей деревни сойдет. С тех пор начал потихоньку вникать в разработку приложений для iOS (в частностни для iPhone).

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



Но даже для написания такого простого приложения мне пришлось биться головой об стены, т.к. в интернете мало статей для трактористов (коим я по сути и являюсь). Вот я и решил восполнить данный недостаток. Если будут восхищенные отзывы то я эту тему буду продолжать. И сразу же предупреждаю, что русский язык знаю далеко не идеально. Ну ок, поехали!

Настройка окружения и проекта

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

Дальше качаем Xcode (IDE в которой будем создавать приложение) отсюда: developer.apple.com/xcode (вместе с IDE мы получим компилятор, отладчик, профайлер и симулятор iPhone). Для того чтобы скачать необходимо зарегистрироваться, думаю это не составит трудности. Устанавливаем и запускаем.

При запуске Xcode предложит нам создать новый проект, выбираем “Create new Xcode project”:



Дальше нам предлагают несколько каркасов для нового приложения, мы пойдем вразрез со многими рекоммендациями интернетов и создадим Single View Application (это приложение в котором один единственный вид, который мы и увидим после запуска приложения):



Далее мы указываем название нашего приложения (ActiveTable) и прочую чепуху (обратите внимание на то что установлена галочку Use Storyboards; что это такое можно посмотреть здесь habrahabr.ru/post/131128):



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

Обзор созданного мастером проекта

Самое интересное вот здесь:



В дропбоксе “Main Storyboard” мы можем выбрать storyboard который будет загружен при старте приложения (для нас был автоматически создан и присвоен storyboard с именем “MainStoryboard”), а под дорпбоксом список поддерживаемых ориентаций нашего девайса (в симуляторе “Симулятор iOS” можно осуществить поворот выбрав “Аппаратура-Повернуть влево” или “Аппаратура-Повернуть вправо”). Слева мы видим вот что:



Здесь у нас кнопка “Run” для запуска приложения в “Симулятор iOS”, а ниже дерево проекта:

  • AppDelegate.h / AppDelegate.m — класс для обработки событий нашего приложения;
  • MainStoryboard — файл с нашими видами и переходами;
  • ViewController.h / ViewController.m — класс для управления нашей дефаултной вьюшкой, которую для нас создал мастер создания проекта.

Остальные файлы и папки не особо интересны в контексте данной статьи. А вот по поводу ViewController я еще скажу. Если выбрать в дереве проекта (панель слева) MainStoryboard-ViewController-выбрать в панельке справа закладку “Show the Identity inspector”, то увидим что в “Custom Class-Class” в качестве управляющего контроллера выбран класс ViewController, который как раз и описан в файлах ViewController.h / ViewController.m:



Создание БД и подключение sqlite к проекту

Ну что ж, пришло время создать базу данных sqlite. Для этого открываем наш любимый терминал (о да, он сводит меня с ума. Понимаете, mac os как ubuntu, только совсем не так, а намного лучше!), переходим в папку с проектом и создаем там базу (сразу же создадим таблицу и заполним ее данными):

$ cd ~/Documents/Projects/ActiveTable/ActiveTable
$ sqlite3 Base.db
sqlite> create table animals (id integer primary key, name text);
sqlite> insert into animals(name) values('Cat');
sqlite> insert into animals(name) values('Dog');
sqlite> insert into animals(name) values('Horse');
sqlite> .quit

База готова. Теперь необходимо добавить файл с базой в проект. Для этого выполняем:



В диалоге выбираем файл Base.db. Теперь подключим libsqlite3.0.dylib. Для этого идем в настройки проекта (корень дерева проекта слева)-TARGETS-ActiveTable-Build Phases-Link Binary With Libraries, нажимаем на плюсик и находим libsqlite3.0.dylib.



Теперь внимание, еще один момент. Работа с sqlite3 будет сплошным кошмаром если не написать толковый враппер. Но к счастью есть готовая и очень симпотная библиотека FMDB (https://github.com/ccgus/fmdb). Есть так же неплохой туториал по юзанью сего чуда www.icodeblog.com/2011/11/04/simple-sqlite-database-interaction-using-fmdb. Итак нам необходимо скачать эту библиотеку. Если Git не стоит, то его необходимо скачать отсюда code.google.com/p/git-osx-installer. Клонируем себе FMDB (находясь в папке с проектом):

$ git clone https://github.com/ccgus/fmdb

Далее добавляем в проект так же как и Base.db папку fmdb. После этого нужно найти и удалить из дерева проекта fmdb/src/main.m (это файл для сборки библиотеки FMDB). Ну вот, наконец мы можем поднакодить! :)

Доработка контроллера для TableView

Для начала нам необходимо создать TableView. Для этого переходим в MainStoryboard, находим в правой панельке внизу в спике TableView



и перетаскиваем его на наш ViewController:



TableView у нас есть. Теперь нам необходим делегировать обработку событий и получение данных одному из контроллеров. Для этого мы выбираем наш TableView, в панельке справа переходим на вкладку “Show the Connections inspector” и перетягиваем маркер возле “delegate” на значек нашего контроллера (тот который ViewController):



Также делаем и для “dataSource”. Связь создана, теперь TableView будет знать к какому контроллеру обращаться за получением необходимых ему данных.

Объявляем в классе ViewController (ViewController.h) поле для хранения данных таблицы:

@interface ViewController : UIViewController
{
    NSMutableArray *_items;
}

В реализации ViewController (ViewController.m) уже есть два методя для обработки событий входа и выхода из вида, добавим в них загрузку и освобождение данных:

- (void)viewDidLoad
{
    [super viewDidLoad];
    _items = [[NSMutableArray alloc] init];
	[self loadItems];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    [_items release];
}

Как видно из примера выше, для загрузки записей мы создаем метод loadItems:

- (void)loadItems
{
    //определяем путь к файлу с базой
    NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Base.db"];
    //создаем подключение к базе
    FMDatabase *database;
    database = [FMDatabase databaseWithPath:path];
    database.traceExecution = true; //выводит подробный лог запросов в консоль
    [database open];

    //выполняем выборку из таблицы animals
    FMResultSet *results = [database executeQuery:@"select * from animals"];
    while([results next]) {
        NSString *name = [results stringForColumn:@"name"];
        //atIndex - текущее кол-во элементов, чтобы новый элемент добавлялся в конец списка
        [_items insertObject:name atIndex:[_items count]];
    }
    
    //удаляем подключение к базе
    [database close];
}

Ссылка на туториал по использованию FMDB приведена выше, думаю здесь все прозрачно, главное не забыть включить хидер FMDB (#import «fmdb/src/FMDatabase.h»).

Вот у нас есть данные, а это значит что мы потихоньку подошли к развязке! Далее три основных метода которые необходимы (кроме numberOfSectionsInTableView, его привожу для полноты картины) для того чтобы в TableView появились данные. Метод “numberOfSectionsInTableView” возвращает кол-во секций таблицы. Таблица с секциями выглядит как-то так:



Поскольку у нас таблица без секций, то мы просто возвращаем единицу:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

А вот метод “numberOfRowsInSection” как раз таки возвращает кол-во строк в секции. Для односекционной таблицы это просто общее кол-во строк:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [_items count];
}

Ну и собственно метод который возвращает ячейку для отрисовки:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //для возврата ячейки мы используем один ее экземпляр, если он не создан, создадим
    //здесь "Cell" это придуманный нами для повторного использования идентификатор ячейки
    NSString *cellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    
    if (cell == nil)
    {
        //здесь можно не просто создать ячейку, можно добавить в нее даже картинки
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
    }
    
    //в indexPath.row нам передают номер строчки для отображения
    NSString *item = [_items objectAtIndex:indexPath.row];
    //мы же в label выведем название животного
    cell.textLabel.text = item;
    
    return cell;
}

Запускаем и наслаждаемся:



Заключение

Разработка под iOS занятие весьма интересное. Встроенные компоненты очень мощные и достаточно кастомизируемы. IDE и ее сопутствующий инструментарий впечатляет. Ну реально, вывести таблицу вообще можно без проблем.

Готовый проект (File-Download): docs.google.com/open?id=0B-5edA19iu-TSXZ6QUpoVWtUN28.

ПС: не судите строго, это моя первая проба пера! Но всяческие замечания приветствуются.
Tags:
Hubs:
+28
Comments 72
Comments Comments 72

Articles