Предисловие
Приветствую вас хабролюди. Недавно сбылась мечта всей моей жизни и я купил себе 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 (что радует) и видим настройки нашего проекта (они показываются если в панельке слева выбрать пункт с названием проекта). Здесь же сразу идем на вкладку “Build Settings” и ставим “Objective-C Automatic Reference Counting” в “No”, т.к. в iOS нет сборщика мусора.
Обзор созданного мастером проекта
Самое интересное вот здесь:
В дропбоксе “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.
ПС: не судите строго, это моя первая проба пера! Но всяческие замечания приветствуются.
Автор: sokal32