Предисловие
Это продолжение перевода серии статей о создании расширений для OpenFL от Laurent Bédubourg. В первой части мы создали простое расширение и скомпилировали его для нативных платформ (Linux/Windows, Android, iOS). Во этой части мы добавим в наше приложение на iOS возможность отправлять твиты.
Что мы узнаем:
- как структурировать исходный код нашего расширения для различных платформ
- как связать код на haxe и функции из нашего расширения
- как линковаться с iOS фреймворками (с фреймворком Twitter, в частности)
Что делать?
Давайте начнем с того, что посмотрим как структурирован, например, проект NME.
На первый взгляд Build.xml выглядит сложно и мы вернемся в нему позже. Посмотрев на содержимое каталога, мы увидим следующее:
- include/ содержит заголовочные файлы, которые будут реализованы в common/ и plaforms
- common/ платформо-независимый c++ код (более менее платформо-независимый, мы можем использовать #if defined(HX_xxxx) чтобы добиться максимальной платформо-независимости)
- common/ExternalIterface.cpp экспортирует функции в среду исполнения (DEFINE_PRIM)
- platform в данном каталоге содержатся реализации под конкретные платформы (iPhone, maс, windows и другие)
На мой взгляд такая структура выглядит довольно удобной, давайте и мы будем ее использовать.
Начнем с нашего предыдущего расширения, мы должны объявить функцию Tweet() в существующем файле include/Util.h (по уму, мы должны использовать отдельный заголовочный файл, но я сегодня слишком ленив для этого).
namespace testextension { int SampleMethod(int inputValue); bool Tweet(const char* msg); }
Теперь нам необходимо реализовать ее для платформы iphone:
cd project mkdir iPhone
Создадим файл iPhone/Tweet.mm:
#import <Foundation/Foundation.h> #import <Twitter/Twitter.h> namespace testextension { bool Tweet(const char* message){ // Простите за этот кусок кода на Objective-C // Я просто скопировал его из другого поекта // Мы должны проверить инициализирован ли клиент твитера // Но я оставлю эту задачу читателю для самостоятельного решения :) NSString* str = [[NSString alloc] initWithUTF8String:message]; TWTweetComposeViewController* tweetView = [[TWTweetComposeViewController alloc] init]; [tweetView setInitialText:str]; TWTweetComposeViewControllerCompletionHandler completionHandler = ^(TWTweetComposeViewControllerResult result) { [[[[UIApplication sharedApplication] keyWindow] rootViewController] dismissModalViewControllerAnimated:YES]; }; [tweetView setCompletionHandler:completionHandler]; [[[[UIApplication sharedApplication] keyWindow] rootViewController] presentModalViewController:tweetView animated:YES]; return true; } }
И зарегистрируем функцию Tweet в haxe, для этого отредактируем файл common/ExternalInterface.cpp:
static value testextension_tweet(value message){ // мы знаем, что message это строка и просто получим ее значение const char* cStr = val_get_string(message); // вызовем нашу функцию Tweet и вернем в haxe true или false if (testextension::Tweet(cStr)) return val_true; return val_false; } // зарегистрируем нашу функцию, наша функция принимает один аргумент DEFINE_PRIM(testextension_tweet, 1)
DEFINE_PRIME, val_get_string, val_true и всё остальное являются частью hxcpp и определены в hx/CFFI.h.
Изучение ExternalInterface.cpp из NME поможет вам понять, как зарегистрировать ваши функции.
Часть haxe находится в TextExtension.hx и выглядит вот так:
class TestExtension { // загружаем нашу функцию private static var testextension_tweet = Lib.load("testextension", "testextension_tweet", 1); // внутри типизированного метода вызываем нативную функцию public static function tweet(message:String) : Bool { return testextension_tweet(message); } }
Как скомпилировать
Мне пришлось приложить усилия, чтобы разобраться как скомпилировать и слинковать проект, но в результате все оказалось довольно просто.
Сперва необходимо создать файл project/Build.xml:
<!-- мы добавили этот список файлов для ios --> <files id="iphone"> <file name="iPhone/Tweet.mm"/> </files> <!-- Я также был вынужден скомпилировать расширение для Мака, чтобы избавиться от следующей ошибки: "Library TestExtension version dev does not have a neko dll for your system" --> <files id="mac"> <file name="Mac/Tweet.mm"/> </files>
В секцию с id = NDLL необходимо добавить файлы, которые будут компилироваться:
<files id="mac" if="mac"/> <files id="iphone" if="ios"/>
И, наконец, мы должны добавить фреймворк Twitter в зависимости в include.xml. Через этот файл hxcpp узнает какие фреймворки необходимо добавить в наше приложение.
<dependency name="Twitter.framework" if="ios"/>
Я скомпилировал расширение, также как я делал это в первой части.
haxelib run hxcpp Build.xml -Dmac haxelib run hxcpp Build.xml -Diphoneos -DHXCPP_ARMV7 haxelib run hxcpp Build.xml -Diphonesim
Как запустить
Чтобы протестировать работу расширения, я добавил в свое тестовое приложение следующий вызов:
TestExtension.tweet("This is my tweet message");
И запустил его в симуляторе и на моем iOS устройстве:
cd TestApp openfl test project.xml iphone -simulator openfl test project.xml iphone
Мы можем твитить используя нативный API из нашего приложения! Круто, не правда ли?! 🙂
Хочу отметить одну очень важную вещь — способ, которым я получал информацию — находил ее в исходном коде hxcpp и nme, на гитхабе.
Пытаясь заставить все это работать я столкнулся с несколькими проблемами. Если вы экспериментируете и у вас что-то не получается, не забывайте очищать каталоги ndl/ и project/obj и пересобирать весь проект. Я продолжал экспериментировать, пока не нашел подходящий формат для Build.xml и include.xml.
Единственной реальной сложностью является недостаток документации по формату Build.xml в hxcpp. Но, слава богу, есть примеры, на которых можно учиться.
Следующее, что я хочу сделать, попробовать собрать расширение под андроид, чтобы убедиться, что и на этой платформе все работает. Говорят, что не только разработать расширение на java, но и описать это процесс будет полезным 🙂
Я обновил репозиторий расширения на гитхабе, в надежде, что мой небольшой вклад будет полезен другим хаксерам! Надеюсь данное руководство будет работать на вашей системе… хотя иногда все идет не так как задумывается 😉
ссылка на оригинал статьи http://habrahabr.ru/post/186722/
Добавить комментарий