Статьи

iBoost Ваш iOS-код Часть 1: Введение и макросы

В ходе разработки многих приложений для iOS для различных клиентов, таких как Управление спорта, Федеральный кредитный союз ВМС, Fuzz Alert, Map My Fitness и другие, вы начинаете ощущать закономерность того, как вы используете iOS SDK и что ваши практики кодирования находятся в Objective-C. Ошеломляющее ощущение, что вы делаете одно и то же снова и снова — почти максимально многословно. Посмотрим правде в глаза, Objective-C — это не только уродливый язык, но в SDK отсутствует множество базовых функций, позволяющих сделать вашу работу более лаконичной.

Вот почему я создал и поддерживаю библиотеку iBoost . Это небольшой модуль, который служит своего рода помощником в вашем обычном развитии. Идея пришла ко мне (и ее первоначальному со-разработчику Шону Кристманну) после серии проектов, в которых мы использовали фреймворк Three20. Обещание Three20 заключалось в том, что он предоставил вам инструменты и дополнительные функции, необходимые для экономии времени при проектировании вашего приложения, чтобы вы могли сосредоточиться на бизнес-логике.

Так много для обещаний, верно?

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

Что еще хуже, Three20 использует традиционный SDK. Если вы используете его во всех его возможностях, вы будете строить навигацию без использования UITabBar или UINavigationController, вы больше не будете использовать каркас табличного представления, вы потеряетесь в изменении цвета строки состояния, и вы будете заперт в громоздкой рамке для укладки. Затем, когда выйдет iOS 5, вам нужно ждать целого ряда новых обновлений.

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

И вот я сделал iBoost.

родился iBoost

Цели iBoost просты:

  1. Создайте библиотеку, которая дополняет iOS SDK, а не переопределяет ее.
  2. Сделайте его настолько простым и интегрированным, что новый функционал будет выглядеть как родной
  3. Сделать это быстро и легко установить в свой проект!

Когда вы импортируете iBoost в свой проект, вы получаете набор классов, категорий и макросов, которые расширяют ваши ежедневные разработки таким образом, чтобы ускорить его, не скрывая SDK от вас. Вы можете тренировать каждый аспект этого или вообще ничего. Если вы используете новые методы Core Data для упрощения доступа, вы также можете использовать стандартные методы в любое время. Это твой выбор.

Это также на 100% проверено. Он использует GHUnit, чтобы убедиться, что все, что добавлено в iBoost, работает и не подведет вас. Я надеюсь, что iBoost ускорит вашу разработку, не требуя, чтобы стать экспертом низкого уровня по его коду для правильного использования.

Установка проста!

Библиотека iBoost размещена на github и предлагает уникальный метод установки после ее загрузки. Вы устанавливаете миниатюру iBoost, которая инкапсулирует всю библиотеку в одну пару .h / .m!

(ПРИМЕЧАНИЕ: вам понадобится Python 3, установленный в вашей системе, если вы хотите минимизировать данные из источника. Если у вас его нет или вы хотите его, вы можете просто скопировать подкаталог iBoost / в ваш проект.)

Запустите minifier с помощью следующих команд:

cd iBoost/iBoost
../minifier/minify.py all

Это создает минификацию, включающую полную систему iBoost. Если вы не хотите использовать компоненты пользовательского интерфейса, вы также можете запустить это вместо:

cd iBoost/iBoost
../minifier/minify.py core

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

Вам также нужно добавить каркас CoreData в ваш проект, и все. Теперь давайте посмотрим, что вы получили!

Начиная

Первое, что вы захотите проверить в iBoost, — это макросы. Если вы хотите просмотреть их, они находятся в Macros.h. Вот некоторые основные моменты.

Бокс и Распаковка номеров

Прошли времена громоздкой упаковки NSNumber!

#define BOX_BOOL(x) [NSNumber numberWithBool:(x)]
#define BOX_INT(x) [NSNumber numberWithInt:(x)]
#define BOX_SHORT(x) [NSNumber numberWithShort:(x)]
#define BOX_LONG(x) [NSNumber numberWithLong:(x)]
#define BOX_UINT(x) [NSNumber numberWithUnsignedInt:(x)]
#define BOX_FLOAT(x) [NSNumber numberWithFloat:(x)]
#define BOX_DOUBLE(x) [NSNumber numberWithDouble:(x)]

#define UNBOX_BOOL(x) [(x) boolValue]
#define UNBOX_INT(x) [(x) intValue]
#define UNBOX_SHORT(x) [(x) shortValue]
#define UNBOX_LONG(x) [(x) longValue]
#define UNBOX_UINT(x) [(x) unsignedIntValue]
#define UNBOX_FLOAT(x) [(x) floatValue]
#define UNBOX_DOUBLE(x) [(x) doubleValue]

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

Управление памятью

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

#define SAFE_RELEASE(obj) ([obj release], obj = nil)
#define SAFE_TIMER_RELEASE(obj) ([obj invalidate]; [obj release]; obj = nil)
#define SAFE_ASSIGN(obj, expr) ([(expr) retain], [obj release], obj = (expr))

Я использую их все в моем коде. Если бы мне пришлось печатать их вручную, я бы, вероятно, в конечном итоге вырезал и вставлял их, и, без сомнения, я иногда что-то пропускал и либо терял память, либо обнулял неправильные вещи. Они сохраняют мою безопасность, оставаясь ответственным — и они лаконичны и информативны.

Прямоугольники

Манипуляции с прямоугольниками могут потребовать некоторого громоздкого кода. Например, стандартная процедура изменения размера представления состоит в том, чтобы скопировать фрейм, изменить некоторую его часть и затем переназначить его обратно в представление. Это 3 или более строк кода, и он переписывается так часто, что требует очистки. Эти макросы делают это.

#define RECT_WITH_WIDTH_HEIGHT(rect, width, height) CGRectMake((rect).origin.x, (rect).origin.y, (width), (height))

#define RECT_WITH_WIDTH(rect, width) CGRectMake((rect).origin.x, (rect).origin.y, (width), (rect).size.height)

#define RECT_WITH_HEIGHT(rect, height) CGRectMake((rect).origin.x, (rect).origin.y, (rect).size.width, (height))


#define RECT_INSET_BY_LEFT_TOP_RIGHT_BOTTOM(rect, left, top, right, bottom) CGRectMake(rect.origin.x + (left), rect.origin.y + (top), rect.size.width - (left) - (right), rect.size.height - (top) - (bottom))

#define RECT_INSET_BY_TOP_BOTTOM(rect, top, bottom) CGRectMake(rect.origin.x, rect.origin.y + (top), rect.size.width, rect.size.height - (top) - (bottom))

#define RECT_INSET_BY_LEFT_RIGHT(rect, left, right) CGRectMake(rect.origin.x + (left), rect.origin.y, rect.size.width - (left) - (right), rect.size.height)


#define RECT_STACKED_OFFSET_BY_X(rect, offset) CGRectMake(rect.origin.x + rect.size.width + (offset), rect.origin.y, rect.size.width, rect.size.height)

#define RECT_STACKED_OFFSET_BY_Y(rect, offset) CGRectMake(rect.origin.x, rect.origin.y + rect.size.height + (offset), rect.size.width, rect.size.height)

Первая партия макросов возвращает копию CGRect с измененной шириной и / или высотой. Они пригодятся, когда вы просто хотите изменить размер представления.

Второй пакет возвращает вставку CGRects из оригинала (используйте отрицательную вставку, чтобы развернуть прямоугольник). Обратите внимание, что CGRectInset похож на них, но принимает только одно значение для координат X и Y.

Третий пакет дублирует CGRect и затем смещает их друг от друга. Другими словами, если вы размещаете набор из 3 UIB-кнопок в горизонтальном стеке (например, LinearLayout в Android), вы можете написать такой код:

UIButton *a = ...create my button somewhere...;

UIButton *b = ...create new button...'
RECT_STACKED_OFFSET_BY_X(a.frame, 10);

UIButton *c = ...create new button...'
RECT_STACKED_OFFSET_BY_X(b.frame, 10);

Это приводит к тому, что три кнопки движутся слева направо с промежутками в 10 пикселей между ними.

Помощники по математике

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

#define DEG_TO_RAD(degrees) ((degrees) * M_PI / 180.0)
#define RAD_TO_DEG(radians) ((radians) * 180.0 / M_PI)

#define RGB256_TO_COL(col) ((col) / 255.0f)
#define COL_TO_RGB256(col) ((int)((col) * 255.0))

Их использование должно быть понятным. :-)

Другие полезные лакомые кусочки

Среди многих других, вот некоторые, которые вы можете найти наиболее интересными.

#define SEL(x) @selector(x)

#define IS_EMPTY_STRING(str) (!(str) || ![(str) isKindOfClass:NSString.class] || [(str) length] == 0)
#define IS_POPULATED_STRING(str) ((str) && [(str) isKindOfClass:NSString.class] && [(str) length] > 0)

#define DEVICE_UDID ([UIDevice currentDevice].uniqueIdentifier)

#define DOCUMENTS_DIR ([NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject])

Макрос SEL (x) — это тот, который вызывает больше всего шума. Для меня это единственная цель — сократить громоздкий вызов @selector (x).

Куда мы идем отсюда?

Во второй части я рассмотрю Core Data Store, удобный набор методов, которые значительно упрощают использование Core Data!