13.03
2012

В первой части описывались основы сборки SWC библиотек.

В этой части рассмотрим случай когда необходимо собрать множество изображений в один swc-файл. Для этого будем использовать так же Apache Ant. В качестве примера возьмём библиотеку флагов famfamfam включающую в себя почти 250 png-иконок.

Для этого понадобится:

  • Для каждого изображения создать AS-класс на основе шаблона (отличие будет только в названии файла, имени класса и включенном изображении);
  • Скомпилировать созданные классы в SWC;
  • Удалить все созданные AS-классы.

В скрипте использована библиотека ant-contrib, которая дает нам FOR для обработки файлов. Она включена в архив с исходниками в конце заметки.

buildIconsLib.properties

###  buildIconsLib.properties  ###

FLEX_HOME=D:\\SDKs\\4.6.0

dir.lib = ${basedir}\\lib

# source config
src.dir = ${basedir}\\src
#src.ASTemplate = ${src.dir}\\templates\\BitmapTemplate.tpl
src.ASTemplate = ${src.dir}\\templates\\BitmapDataTemplate.tpl
#src.ASTemplate = ${src.dir}\\templates\\SoundTemplate.tpl

# asset config
 # директория с иконками
assets.dir = ${src.dir}\\com\\assets\\icons
 # путь куда будут генерироваться классы (такой же как и package)
assets.classesDir = app\\icons
assets.package = app.icons
assets.classNamePrefix = Icon_
assets.relativeDir = ../../com/assets/icons
assets.extension = png

# library config
lib.swcPath = ${dir.lib}\\icons.swc

Билд-файл состоит из 4 целей (targets):

1. createTemporaryClasses — генерируем AS классы по шаблону.

<target name="createTemporaryClasses">
	<path id="assetList">
		<fileset dir="${assets.dir}" includes="*.${assets.extension}"/>
	</path>
	<pathconvert targetos="unix" property="assetList2" pathsep="," refid="assetList">
		<mapper>
			<!--http://ant.apache.org/manual/Types/mapper.html-->
			<chainedmapper>
				<flattenmapper/>
				<globmapper from="*.${assets.extension}" to="*"/>
			</chainedmapper>
		</mapper>
	</pathconvert>
	<for param="file" list="${assetList2}">
		<sequential>
			<copy filtering="true" file="${src.ASTemplate}" tofile="${src.dir}\\${assets.classesDir}\\${assets.classNamePrefix}@{file}.as" overwrite="true">
				<filterset>
					<filter token="ASSET_PACKAGE" value="${assets.package}"/>
					<filter token="ASSET_NAME" value="@{file}"/>
					<filter token="ASSET_PATH" value="${assets.relativeDir}"/>
					<filter token="ASSET_EXTENSION" value="${assets.extension}"/>
					<filter token="ASSET_CLASS_PREFIX" value="${assets.classNamePrefix}"/>
				</filterset>
			</copy>
		</sequential>
	</for>
</target>

Создаем список файлов с иконками, а затем, pathconvert’ом убираем расширения файлов.
В цикле для каждого png файла создаем свой класс — копируем файл шаблона и задаем ему новое имя и заменем параметры.

2. build SWC — сборка сгенерированных классов

<!-- build the swc -->
<target name="build SWC">
	<path id="classList">
		<fileset dir="${src.dir}">
			<include name="${assets.classesDir}\*.as"/>
		</fileset>
	</path>
	
	<pathconvert property="classList2" pathsep=" " dirsep="." refid="classList">
		<mapper>
			<chainedmapper>
				<flattenmapper/>
				<globmapper from="*.as" to="${assets.package}.*"/>
			</chainedmapper>
		</mapper>
	</pathconvert>
	
	<!-- компилируем классы из списка в swc -->
	<compc output="${lib.swcPath}" include-classes="${classList2}">
		<source-path path-element="${src.dir}"/>
	</compc>
</target>

Создаем список сгенерированных классов. Затем pathconvert’ом конвертируем имена файлов в названия классов (полный путь включая package) для передачи в include-classes компилятора.

3. deleteTemporaryClasses — удаляем созданные временные классы

<target name="deleteTemporaryClasses">
	<delete>
		<fileset dir="${src.dir}">
			<include name="${assets.classesDir}\\*.as"/>
		</fileset>
	</delete>
	<echo>Deleted temporary classes</echo>
</target>

4. buildAssetLibrary - стартовая (deafult) процедура — только запускает остальные в порядке очереди.

<target name="buildAssetLibrary">
	<tstamp><format property="StartInstTime" pattern="dd-MMM-yyyy  hh:mm:ss" locale="en,UK"/></tstamp>
	<echo>[${StartInstTime}] Starting build..</echo>
	<antcall target="createTemporaryClasses" />
	<antcall target="build SWC" />
	<antcall target="deleteTemporaryClasses" />
	<tstamp><format property="EndInstTime" pattern="dd-MMM-yyyy  hh:mm:ss" locale="en,UK"/></tstamp>
	<echo>[${EndInstTime}] Build finished.</echo>
	<echo>Asset library built to ${lib.swcPath}</echo>
</target>

В результате у нас будет готовая для использования библиотека всех флагов.

Исходные коды со скриптами: zip-архив (220Kb)
Пояснения:
buildIconsLib.xml — билд-файл собирающий swc из иконок.
buildSWCs.xml — билд-файл создающий swc со стилями, swc с переводами и обращается к buildIconsLib.xml для создания swc с иконками.

Полезные ссылки:
Часть 1: Сборка SWC библиотек при помощи Apache Ant
Using Flex Ant Tasks
Auto-generate SWC asset libraries with Apache Ant and the Flex SDK

21.02
2012

Это первая заметка из небольшой серии, посвященной сборке, подключению и использованию swc-библиотек. Особено актуально для тех, кто собирается разрабатывать мобильные приложения под iOS, но об этом позже :)

Азы и простые примеры.

SWC — скомпилированая библиотека. Часто используемые классы или сотня-другая картинок/звуков, собранных в один swc файл, можно повторно использовать в других проектах, или, например, раздать тестерам =) При этом исходные коды останутся в одном месте. В SWC можно скомпилировать файлы переводов для добавления в приложение многоязычности, или таблицу стилей — тогда полученный swc можно будет использовать как основную или дополнительную тему в приложении.

SWC создается при помощи компилятора compc. Для автоматизации сборки SWC и приложений будем использовать Apache Ant.

Сборка SWC:

<target name="buildSWC">
	<compc output="${basedir}/swc/MyLib.swc" keep-generated-actionscript="false" incremental="false">
		<source-path path-element="${dir.src}" />
		<!-- Включить все .as файлы из данной директории -->
		<include-sources dir="${dir.src}/app/utils/" includes="*.as" />
		<!-- Включить все файлы из данной директории и поддиректорий -->
		<include-sources dir="${dir.src}/app/comps/" includes="*" />
		<!-- Включение класса -->
		<include-classes />
		<!-- Включить из конфиг-файла. По сути тоже самое, но в отдельном файле -->
		<load-config filename="${basedir}/build/classes-list.xml"/>
	</compc>
</target>

classes-list.xml

<?xml version="1.0" encoding="utf-8" ?>
<flex-config>
	<include-classes>
		<class>app.events.MyEvent</class>
		<class>app.comps.Button</class>
	</include-classes>
</flex-config>

SWC с файлами локализации:

<target name="buildSWC-locale">
	<compc output="${basedir}/swc/locale.swc">
		<locale>ru_RU</locale>
		<!-- Путь к директории с локалями -->
		<source-path path-element="${dir.src}/locale"/>
		<!-- Имя подключаемой локали (одной или более) -->
		<include-resource-bundles>Resources</include-resource-bundles>
	</compc>
</target>

Файл Resources.properties:

AppTitle = Заголовок
HelloMsg = Превед!

В случае если надо надо несколько языков иметь в одном файле:

<target name="buildSWC-locale"> 
	<compc output="${dir.lib}/locale.swc" allow-source-path-overlap="true">
		<locale>en_US</locale>
		<locale>ru_RU</locale>
		<source-path path-element="${dir.src}/locale/{locale}"/>
		<include-resource-bundles>Resources</include-resource-bundles>
	</compc>
</target>

Компилятор будет поочередно перебирать локали и подставлять их вместо {locale}.
И в данном случае надо будет добавить опцию allow-source-path-overlap=”true”.

SWC файл со стилями:

<target name="buildSWC-styles">
	<compc output="${basedir}/swc/style.swc">
		<include-file name="MyStyles.css" path="${dir.src}\css\MyStyles.css" />
	</compc>
</target>

Полезные ссылки:
Adobe: About SWC files
Adobe: Understanding SWC files
Adobe: Using the compc task
Adobe: Creating resources
Adobe: Using resource modules
Adobe: Easily compile resource bundles using Ant
Adobe: Compiling a theme SWC file
Делаем правильные swc библиотеки

11.03
2011

Порой надо загрузить на сервер файлы, сгенерированные программно – скриншоты, архивы и другое. Из-за ограничений безопасности FileReference’у [ru] необходимо участие пользователя для загрузки файлов – при выборе внешнего файла для загрузки – заполняются все его хэдеры.
Обойти это ограничение можно используя класс UploadPostHelper.

Функция загрузки будет выглядеть так:

private function uploadFile(ba:ByteArray, fileName:String):void {
var urlRequest:URLRequest = new URLRequest();
  urlRequest.url = uploadPath;
  urlRequest.contentType = 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary();
  urlRequest.method = URLRequestMethod.POST;
  urlRequest.data = UploadPostHelper.getPostData(fileName, ba);
  urlRequest.requestHeaders.push(new URLRequestHeader('Cache-Control', 'no-cache'));

  var urlLoader:URLLoader = new URLLoader();
  urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
  urlLoader.addEventListener(Event.COMPLETE, completeHandler);
  urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioError);
  urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSError);
  urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onhttp);
  urlLoader.load(urlRequest);
}

Здесь можно скачать пример проекта (flashdevelop, клиентская часть), который архивирует текстовые данные используя FZip и отправляет файл на сервер.

28.02
2011

AIR for Android: Hello World!

В конце прошлой недели компания Adobe выпустила AIR 2.6 для Android c поддержкой планшетов и Android 3.0 Honeycomb (так же поддерживаются Android 2.2 (FroYo), Android 2.3 (Gingerbread)). Список поддерживаемых устройств опубликован на adobe.com.
Обещают увеличение производительности и декодирование H.264 видео с частотой 30 кадров/сек.

Небольшое пошаговое руководство по установке и запуску простого air-приложения на эмулятор Android’a.

Читать далее …

31.01
2011

Error: Optimization gone wrong, fix code.

java.lang.RuntimeException: Optimization gone wrong, fix code.
Этими тёплыми словами приветствовал меня mxmlc при попытке сборки air приложения.
Всезнающий гугл никакой информации не дал. Слава свн’у =)
Проблема заключалась в том, что в теле одного из классов встретилась директва import. Причем компиляция flex-версии проходила успешно и работала без ошибок. Но при попытке скомпилировать air-версию всплывала эта ошибка.

04.03
2010

Появился очень простой, но очень полезный плагин для FlashDevelop’а — Ant panel plugin.
Ant task panel plugin
Для настройки надо указать либо путь к папке ant/bin в переменных среды (%PATH%), либо в Tools/Program Settings/Ant Plugin указать путь к анту.

01.03
2010

Настроить FlashDevelop для компиляции используя Flex 4 (Gumbo) SDK легко.
Намного больше времени прийдется потратить на то, что бы заставить работать подсветку AS синтаксиса, авто-заполнение mxml и много другое, без чего работать с новым sdk не комфортно:). Последний официальный релиз FD был 3.0.6 RTM от 04 ноября 2009 года. С тех пор разработчики сделали очень много изменений, включая улучшенное автозаполнение AS кода в mxml, а так же поддержку flex4.
Вытянув сегодня с официального SVN исходники получил вроде бы рабочую версию )
Flex 4 проект можно создавать сразу из меню Projects:
Create Project window - FlashDevelop
Не забудте указать в Tools/Program Settings/AS3 Content/Flex SDK Location путь в Flex SDK 4 ;)
Скачать сборку можно тут: FlashDevelop 3.1.0 r863 (.7z 4.5Mb) (сборка от 01 марта)

27.02
2010

Думаю многие уже сталкивались с такой библиотекой как as3crypto. Замечательная библиотека, позволяющая работать с такими алгоритмами шифрования как: RSA,AES, DES, 3DES, BlowFish, XTEA, RC4 + много других плюшек:). На официальной демо-странице можно оценить её возможности. Документацию по ней можно не искать — её нет. Единственный вариант — изучать исходники демки.
Но скачав последнюю (1.3) версию получил “приветствие”:
\src\com\hurlant\crypto\symmetric\AESKey.as(214): col: 29: Warning: flex2.compiler.as3.SignatureExtension.SignatureGenerationFailed[node=’ForStatement’, level=’warning’, cause=’flex2.compiler.as3.SignatureAssertionRuntimeException: Unreachable Codepath
Нашёл несколько исправлений, но рабочим оказалось только это.

Простой пример DES шифрования (исходный код с исправленным AESKey.as)


24.02
2010

Да, давненько была последняя запись. Как всегда главная проблема — количество часов в сутках:)
Попробую всё же реинкарнировать блог, но, к сожалению, все комментарии были безвозвратно утерянны (

29.05
2008

На adobe есть хороший документ:
Flex SDK coding conventions and best practices

Оказывается две главы из него уже есть на русском языке в блоге racer242:
Именование
Использование языка программирования

UPD: 29.05.2008
Три главы: Структура файла