В этой статье я расскажу как создать простое нативное расширение для платформы
iOS. А так же разберем как созданное расширение применяется в
ActionScript проекте. Нам понадобятся компиляторы
Adobe Flash Builder и
Xcode. Подразумевается что вы знаете как создавать
swc библиотеки и actionscript-приложения в
Adobe Flash Builder. Если вы не знаете как это делается, советую почитать соответствующую литературу. Знаний по
ObjectiveC/Xcode не требуется.
Разработка нативного расширения делится на три этапа:
- создание библиотеки SWC
- создание библиотеки Xcode
- сборка пакета ANE
Разберем каждый этап подробнее.
Создание библиотеки SWC.
Ниже приведен листинг класса HelloAne.as
package com.anedevelop.helloane
{
import flash.events.EventDispatcher;
import flash.external.ExtensionContext;
public class HelloAne extends EventDispatcher
{
private var context:ExtensionContext;
public function HelloAne()
{
try {
context = ExtensionContext.createExtensionContext('com.anedevelop.helloane', '');
} catch (error:Error) {
// если context не создается - проверьте правильность указания
// ID расширения: com.anedevelop.helloane
// это же значение необходимо указать в файле extension.xml
}
}
public function run():String
{
if (context != null) {
return context.call('runHelloAne') as String;
}
return null;
}
}
}
Разберем его подробнее. В конструкторе класса мы создаем экземпляр класса
ExtensionContext используя идентификатор расширения:
com.anedevelop.helloane. Вы можете использовать любой идентификатор. Второй параметр в методе
createExtensionContext может понадобится в том случае если вы хотите использовать в одном расширении разную логику. Мы не будем рассматривать эту возможность в рамках этой статьи.
В методе
run класса
HelloAne мы вызываем медом
runHelloAne у созданного экземпляры
ContextInterface. Далее
FlashPlayr вызовет метод с именем
runHelloAne в проекте
Xcode. Собираем из полученного класса библиотеку
helloaneLib.swc. Когда создаете библиотеку SWC необходимо в настройках проекта
Flash Builder поставить галочку
Include Adobe AIR libraries.
Создание библиотеки Xcode.
Создайте проект библиотеки
Xcode выбрав пункт меню:
File->New->Project. В появившемся окне в левой колонке кликаем на пункт
Framework & Library раздела
iOS, в правой части панели выбираем проект с именем
Cocoa Touch Static Library и нажимаем кнопку
Next:
На предыдущем скрине вы наверняка обратили внимание на пункт
AIR Native Extension в списке шаблонов проекта. Это шаблон который позволяет быстро создавать проект для компиляции статической библиотеки и сборки пакета ANE. Об этом шаблоне я подробно расскажу в последующих статьях. А пока попробуем разобраться со стандартными средствами :)
На следующем шаге указываем имя проекта
helloane, и другую не очень важную на данный момент информацию. Нажимаем кнопку
Next:
На последнем этапе выбираем каталог для проекта и сохраняем его:
Создав проект необходимо положить в каталог проекта файл
FlashRuntimeExtensions.h и добавить его с помощью пункта меню
File->Add files to "helloane". Файлик должен появится в проекте как указано на скриншоте.
По умолчанию Xcode компилирует результат во временный системный каталог. В своих проектах я настраиваю Xcode так что бы он компилировал результат в каталог build, рядом с каталогом приложения. Для этого кликните на название проекта(
helloane) в левой части Xcode. А затем в центральной части Xcode кликаем на
targets->
helloane. В правой части Xcode откроется окно с настройками, кликаем на вкладку
Build Settings и находим поле с
Pre-configuration Build Products Path и пишем туда:
$(PROJECT_DIR)/build/.
Разработку Xcode приложения для вашего нативного расширения можно условно разделить на 3 шага:
- Глобальная инициализация
- Локальная инициализация
- API компонента для вашего приложения
- Глобальная инициализация это два метода которые вызывает
Flash Player в момент создания/уничтожения вашего нативного расширения. В нашем примере эти методы называются
helloaneExtInitializer и
helloaneExtFinalizer. Назовем их
методами Глобальной инициализации.
- Локальная инициализация подразумевает
создание функций которые будут вызваны из методов глобальной
инициализации для создания/уничтожения вашего компонента. Возникает
вопрос зачем два метода инициализации? Честно говоря, на момент
написания это статьи я не знал ответа, если кто то сможет объяснить
зачем это нужно - милости просим к обсуждению.
- API компонента это те методы, которые вы будете вызывать из
flash-приложения. В нашем случае один метод
runHelloAne.
Возможно вы уже заметили в проекте два основных файла:
helloane.h и
helloane.m. Файл с расширением
.h содержит прототипы всех функций которые мы будем использовать в файле с расширением
.m.
Рассмотрим листинг файла
helloane.h:
/*
Здесь мы создаем прототип нашего приложения.
*/
#import <Foundation/Foundation.h>
#import "FlashRuntimeExtensions.h"
/////// Шаг первый. Глобальная инициализация кмопонента **************
// Создание компонента
void helloaneExtInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet, FREContextFinalizer* ctxFinalizerToSet);
// Уничтожение компонента
void helloaneExtFinalizer(void* extData);
/////// Шаг второй. Локальная инициализация **************
// Создание компонента
void ContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx, uint32_t* numFunctionsToTest, const FRENamedFunction** functionsToSet);
// Уничтожение компонента
void ContextFinalizer(FREContext ctx);
/////// Шаг третий. API компонента для вашего приложения **************
// Метод который будет доступен из flash-приложения
FREObject runHelloAne(FREContext ctx, void *data, uint32_t argc, FREObject argv[]);
Давайте попробуем понять значения аргументов используемых функций.
Описание этих функций на инглише можно почитать на сайте
Adobe . А теперь по-русски.
helloaneExtInitializer
-
void** extDataToSet : указатель на указатель (смешные они, ObjectiveC-разработчики :) ) данных для кастомной инициализации нативного расширения. Как пользоваться этим, пока не разобрался возможно расскажу в следующих статьях.
- FREContextInitializer* ctxInitializerToSet : указатель на метод локальной инициализации
- FREContextFinalizer* ctxFinalizerToSet : указатель на метод локальной финализации
ContextInitializer
- void* extData : судя по всему это такая же шляпа что и в методе helloaneExtInitializer.
- const uint8_t* ctxType : тип нативного расширения, здесь передается значение которые вы передаете во втором аргументе в методе ExtensionContext.createExtensionContext в библиотеке SWC, в нашем случае используется пустая строка.
- FREContext ctx : объект обеспечивающий связь между xcode и flash приложениями. Например через него можно отправить вызов из xcode приложения во flash.
- uint32_t* numFunctionsToTest : указатель на количество наших api-методов, которые мы будем вызывать из flash проекта.
- const FRENamedFunction** functionsToSet : массив api-методов
runHelloAne
- FREContext ctx : ссылка на объект обеспечивающий связь между xcode и flash
- void *data : эта шляпа как то связана с данными которые передаются в extDataToSet и extData. Когда нибудь я разберусь как это работает :)
- uint32_t argc : Количество аргументов переданных из flash приложения
- FREObject argv[] : массив аргументов переданных из flash приложения.
Разобравшись с прототипами функций, давайте посмотрим на их реализацию в файле helloane.m