(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Разработка Web-приложений для мобильных устройств с помощью WebSphere Portal и IBM Worklight: Часть 2. Поддержка разных устройств на страницах WebSphere Portal

Источник: IBM

Решения IBM WebSphere Portal и IBM Exceptional Web Experience более десятилетия остаются лидером рынка систем для работы с Web. IBM Worklight ― это новая корпоративная платформа, предназначенная для создания "родных", гибридных и Web-приложений для мобильных устройств. В этой статье объясняется, как при помощи интеграции WebSphere Portal и Worklight обеспечить поддержку как Android-, так и iOS-приложений. Предлагаемое упражнение дополняет пример, приведенный в Части 1, и демонстрирует, как построить iOS-приложение и динамически добавлять соответствующие ресурсы Worklight.

Введение

Получить Worklight: Загрузите бесплатную и бессрочную версию IBM Worklight Developer Edition 5.0!

Платформа IBM Worklight позволяет создавать приложения для многих устройств, включая устройства на платформе iOS, Android и Blackberry. С помощью технологии Apache Cordova, которую использует и предоставляет Worklight, можно вызывать "родные" функции посредством команд JavaScript, включаемых в web-разметку.

Эта статья знакомит читателя с процессом создания гибридного iOS-приложения, которое интегрируется с IBM WebSphere Portal. В ней обсуждается процесс определения устройства, которое имеет доступ к порталу, и включения соответствующих ресурсов ― для iOS или Android ― с целью поддержки собственных возможностей ОС в пределах приложения.

Предварительные условия

Эта статья дополняет информацию, представленную в Части 1 настоящего цикла. Прежде чем выполнять описанные здесь шаги, выполните весь пример решения из Части 1.

В дополнение к предварительным условиям, указанным в Части 1, нужно установить Apple Xcode для сборки описанного здесь примера гибридного приложения. Эта статья основывается на гибридном приложении Worklight с поддержкой Apple iPhone. Пример протестирован с Apple Xcode версии 4.4.1 и работает только на Apple OS X.

Создание среды iOS в Worklight

  1. Чтобы создать новую среду для iPhone в Worklight, откройте Project Explorer и щелкните правой кнопкой на WLPortalApp в папке приложений, затем выберите New > Worklight Environment (рисунок 1).

    Рисунок 1. Создание новой среды Worklight
    Рисунок 1.  Создание новой среды Worklight

  2. Появится панель New Worklight Environment (рисунок 2). Для этого конкретного примера выберите iPhone. Чтобы создать среду для других iOS-устройств, таких как iPad, на этой панели можно указать соответствующие дополнительные опции. Нажмите кнопку Finish.

    Рисунок 2. Среда Worklight в Eclipse
    Рисунок 2. Среда Worklight в Eclipse

  3. Worklight Studio обновляет проект с добавлением "родного" приложения для устройств iPhone (рисунок 3).

    Рисунок 3. В проект добавлено "родное" приложение для iPhone
    Рисунок 3. В проект добавлено родное приложение для iPhone

  4. Далее, откройте файл основного класса родного приложения для iOS (рисунок 4). Это файл \WLPortal\apps\WLPortalApp\iPhone\native\classes\WLPortalApp.m. Его нужно будет изменить, как файл WLPortalApp.java в Части 1. Все iOS-приложения написаны на языке Objective-C.

    Рисунок 4. Файл основного класса родного iOS-приложения
    Рисунок 4. Файл основного класса родного iOS-приложения

  5. Чтобы отобразить портал внутри iOS-приложения, метод запуска нужно будет изменить для загрузки URL-адреса портала. Это метод didFinishLaunchingWithOptions (листинг 1), который в основном запускает внутренний HTML-файл, созданный по умолчанию.

    Листинг 1. Метод didFinishLaunchingWithOptions в WLPortalApp.m

    /** * Это основной шаг после инициализации приложения, * здесь выполняется настройка представлений и свойств. */ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions { BOOL ret = [super application:application didFinishLaunchingWithOptions: launchOptions]; /* * Если требуется дополнительная специфическая инициализация приложения, * ее можно выполнить здесь. **/ return ret; }

  6. Замените блок кода из листинге 1 кодом из листинга 2. Новый код запустит приложение автоматически в режиме Web-представления и направит его на портал.

    Листинг 2. Метод didFinishLaunchingWithOptions, направляющий приложения по URL-адресу портала

    -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions { BOOL superResult = [super application:application didFinishLaunchingWithOptions: launchOptions]; NSURL* remoteURL = [NSURL URLWithString:@"http://9.99.999.999:10039/wps/portal"]; NSURLRequest* request = [NSURLRequest requestWithURL:remoteURL]; [self.viewController.webView loadRequest:request]; return superResult; }

    IP-адрес в этом примере должен быть адресом сервера WebSphere Portal, который нужно отобразить в гибридном приложении.

  7. Откройте файл Cordova.plist, расположенный в папке \WLPortal\apps\WLPortalApp\iphone\native.
  8. Найдите ключ атрибута OpenAllWhitelistURLsInWebView и присвойте ему значение true (листинг 3).

    Листинг 3. Присвоение OpenAllWhitelistURLsInWebView значения true

    <key>OpenAllWhitelistURLsInWebView</key> <true/>

  9. Теперь, когда приложение настроено, его нужно скомпоновать и развернуть. Как видно на рисунке 5, команда Build All and Deploy означает, что "родное" приложение будет переустановлено с учетом изменений в Web-приложении. Выполните команду Build All and Deploy, щелкнув правой кнопкой на приложении и выбрав Run As > Build All and Deploy.

    Рисунок 5. Выбор команды Build All and Deploy
    Рисунок 5. Выбор команды Build All and Deploy

  10. Когда начнется процесс сборки, за его ходом можно следить по индикатору нижней правой панели состояния Eclipse. После завершения процесса на консоли Worklight должно появиться сообщение Application 'YourApp' deployed successfully with all environments (Приложение YourApp успешно развернуто во всех средах). Оба приложения iOS и Android обновлены.
  11. Теперь нужно проверить приложение в эмуляторе iOS. Для этого щелкните правой кнопкой на iphone в проекте в Eclipse и выберите Run as > Xcode project (выполнить как проект Xcode ― рисунок 6). Запустится Xcode, и приложение появится на консоли (рисунок 7).

    Рисунок 6. Запуск приложения как проекта Xcode
    Рисунок 6. Запуск приложения как проекта Xcode

    Рисунок 7. Приложение в Xcode
    Рисунок 7. Приложение в Xcode

  12. Поскольку приложение создано для устройств iPhone, смените эмулятор для iPhone, щелкнув на стрелке рядом со значком Run в верхней левой части консоли, и выберите iPhone 5.1 Simulator (рисунок 8).

    Рисунок 8. Заменена эмулятора на iPhone
    Рисунок 8. Заменена эмулятора на iPhone

  13. Выберите значок Run в левом верхнем углу (рисунок 9), и эмулятор запустит ваше приложение (рисунок 10).

    Рисунок 9. Кнопка Run в Xcode
    Рисунок 9. Кнопка Run в Xcode

    Рисунок 10. Приложение работает в эмуляторе iPhone
    Рисунок 10. Приложение работает в эмуляторе iPhone

Обновление темы WebSphere Portal для iOS и Android

Теперь нужно обновить тему WebSphere Portal, чтобы определить операционную систему мобильного устройства и включить нужный набор файлов для передачи в ресурсы Worklight. Операционная система мобильного устройства определяется механизмом класса устройств в WebSphere Portal. Готовые клиенты для смартфонов Android и iOS объединены в один класс устройств smartphone. Требуется разделить клиенты для загрузки ресурсов в зависимости от операционной системы.

  1. Чтобы обновить клиент iPhone таким образом, чтобы он определялся иначе, чем Android, запустите сценарий xmlaccess, приведенный в листинге 4.

    Листинг 4. Сценарий XMLAccess для изменения класса устройств для iPhone и Adroid Mobile

    <?xml version="1.0" encoding="UTF-8"?> <request type="update" version="8.0.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PortalConfig_8.0.0.xsd"> <portal action="locate"> <client action="update" domain="rel" manufacturer="Apple" markup="html" uniquename="wps.client.iphone"> <useragent-pattern>.*iPhone.*</useragent-pattern> <client-capability update="remove">com.ibm.portal.devicesupport.deviceclass= smartphone</client-capability> <client-capability update="set">com.ibm.portal.devicesupport.deviceclass= smartphone-ios</client-capability> <client-capability update="set">HTML_4_0</client-capability> </client> </portal> </request>

    Если вы уже использовали класс устройств smartphone, вам придется обновить всю специальную логику или статические шаблоны для использования нового класса smartphone-ios.

  2. В части 1 мы создали специальную тему, а в рамках этой темы ― новый EAR Web-приложения, содержащий специальные динамические ресурсы. Откройте файл head.jsp, расположенный в папке /<wp_profile>/installedApps/<node>/<custom_ear>/<custom_war>/themes/html/dynamicSpots/. В конец файла head.jsp добавьте код, приведенный в листинге 5, который извлекает класс устройств и устанавливает его в переменную JSP.

    Листинг 5. Извлечение класса устройств

    <c:set var="deviceClass" scope="request" value="${wp.clientProfile['DeviceClass']}" />

  3. После строки кода для извлечения класса устройств используйте полученную информацию для проверки смартфонов iOS или Android (листинг 6).

    Листинг 6. Логика для проверки смартфонов iOS или Android

    <c:if test="${deviceClass == 'smartphone'}"> <!--android devices --> <c:if test="${deviceClass == 'smartphone-ios'}"> <!--ios devices --> </c:if>

  4. Теперь, когда тема способна определить устройство, получившее доступ к порталу, iOS-файлы из Worklight можно переместить в WebSphere Portal. Многие файлы, используемые в Части 1, одинаковы для обоих устройств, а остальные будут содержать пространство имен iOS. Файл с кодом JavaScript, который должен быть включен в WebSphere Portal, это файл WLPortalApp.html, расположенный в папке \WLPortal\apps\WLPortalApp\iphone\native\www\default\.
  5. Первый файл, который нужно создать специально для iPhone, это файл статических свойств. Статические свойства определены в начале HTML-файла (листинг 7).

    Листинг 7. Статические свойства устройств iPhone

    var WL = WL ? WL : {}; /** * Переменные конфигурации WLClient. * Значения вводит deployer, который упаковывает гаджет. */ WL.StaticAppProps = { "APP_DISPLAY_NAME": "WLPortalApp", "APP_SERVICES_URL": "\/apps\/services\/", "APP_VERSION": "1.0", "ENVIRONMENT": "iphone", "LOGIN_DISPLAY_TYPE": "embedded", "WORKLIGHT_ROOT_URL": "\/apps\/services\/api\/WLPortalApp\/iphone\/" };

  6. Возьмите JavaScript из этого HTML-файла (листинг 7) и включите его в новый файл JavaScript с именем staticprops.ios.js. Поместите этот новый файл сюда: fs-type1:themes/<customTheme>/worklight/common/js/ (рисунок 11).

    Рисунок 11. Создан новый файл staticprops.ios.js
    Рисунок 11. Создан новый файл staticprops.ios.js

  7. Другой файл, который нужно переименовать и скопировать в общую папку JavaScript, это wlcommon.js, расположенный в папке: \WLPortal\apps\WLPortalApp\iphone\native\www\default\common\js\.

    Рисунок 12. Файл wlcommon.js переименован для iOS
    Рисунок 12. Файл wlcommon.js переименован для iOS

  8. Следующая группа файлов, которые нужно скопировать из Worklight в портал, расположена в папке wlclient. Эти файлы нужно переименовать с использованием пространства имен iOS:
    • checksum.js
    • cordova.js
    А эти файлы, расположенные в папке \WLPortal\apps\WLPortalApp\iphone\native\www\default\wlclient\js\, можно скопировать как есть:
    • json2.js
    • wpgap.ios.js
    После переименования скопируйте все четыре файла в папку WebSphere Portal fs-type1:themes/<customTheme>/worklight/wlclient/js/.

    Рисунок 13. Новые файлы в папке JavaScript wlclient
    Рисунок 13. Новые файлы в папке JavaScript wlclient

  9. Теперь все необходимые файлы для API Worklight готовы, и их нужно помещать на страницу в зависимости от устройства, которое обращается к WebSphere Portal. Код JavaScript, который нужно включить для Android, можно взять непосредственно из модуля wl_client, созданного в Части 1. Добавьте соответствующий сценарий включения элементов в head.jsp для мобильных устройств Android (листинг 8).

    Листинг 8. JavaScript для мобильных устройств Android, добавленный в head.jsp

    <c:if test="${deviceClass == 'smartphone'}"> <!--android devices --> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/common/js/staticprops.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/cordova.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/common/js/wljq.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/common/js/base.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/messages.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/common/js/wlcommon.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/diagnosticDialog.js" allowRelativeURL= "true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/deviceAuthentication.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/window.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/worklight.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/wlclient.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/wlfragments.js" allowRelativeURL= "true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/encryptedcache.js" allowRelativeURL= "true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/checksum.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/wlgap.android.js" allowRelativeURL=" true" mode="download" lateBinding="false"/>'></script> </c:if>

  10. Далее, добавьте в head.jsp соответствующий код JavaScript для iOS-устройств. Это, по существу, тот же список, что и для Android-устройств, который можно просмотреть с помощью включенного сценария, определённого в WLPortalApp.html, расположенный в папке \WLPortal\apps\WLPortalApp\iphone\native\www\default\. Однако вместо соответствующих Android-файлов подставляются файлы с пространством имен iOS, и добавляется json2.js (листинг 9).

    Листинг 9. Код JavaScript для мобильных устройств iOS, добавленный в head.jsp

    <c:if test="${deviceClass == 'smartphone-ios'}"> <!-- ios devices --> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/common/js/staticprops.ios.js" allowRelativeURL= "true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/cordova.ios.js" allowRelativeURL= "true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/common/js/wljq.js" allowRelativeURL="true" mode= "download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/common/js/base.js" allowRelativeURL="true" mode= "download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/messages.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/common/js/wlcommon.ios.js" allowRelativeURL= "true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/diagnosticDialog.js" allowRelativeURL= "true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/deviceAuthentication.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/window.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/worklight.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/wlclient.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/wlfragments.js" allowRelativeURL= "true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/encryptedcache.js" allowRelativeURL= "true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/checksum.ios.js" allowRelativeURL= "true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/json2.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> <script type="text/javascript" src='<r:url uri="dav:fs- type1/themes/customTheme/worklight/wlclient/js/wlgap.ios.js" allowRelativeURL="true" mode="download" lateBinding="false"/>'></script> </c:if>

    При передаче проекта в производство целесообразно создать уровни JavaScript для каждого набора файлов, зависящих от устройства. Это уменьшит число запросов к странице и повысит производительность.

  11. Теперь, когда файлы Android JavaScript включены в файл head.jsp, нужно удалить модуль wl_client из файла profile_worklight.json, расположенного в папке fs-type1:themes/<customTheme>/profiles/.

    Листинг 10. Оригинальный набор модулей profile_worklight.json

    "moduleIDs": [ "wp_theme_portal_80", "wp_portlet_css", "wp_one_ui", "wp_one_ui_dijit", "wp_legacy_layouts", "wp_client_ext", "wp_status_bar", "wp_theme_menus", "wp_theme_skin_region", "wp_theme_high_contrast", "wp_layout_windowstates", "wl_client", "wl_init" ],

    Листинг 11. Файл profile_worklight.json после удаления wlclient

    "moduleIDs": [ "wp_theme_portal_80", "wp_portlet_css", "wp_one_ui", "wp_one_ui_dijit", "wp_legacy_layouts", "wp_client_ext", "wp_status_bar", "wp_theme_menus", "wp_theme_skin_region", "wp_theme_high_contrast", "wp_layout_windowstates", "wl_init" ],

  12. Так как модуль wl_client удален из профиля, необходимо удалить prereq из модуля wl_init. Для этого откройте файл вклада worklight.json, расположенный в папке fs-type1:themes/<customTheme>/contributions, и удалите определение prereq.

    Листинг 12. Оригинальное определение модуля wl_init

    { "id":"wl_init", "prereqs":[{ "id":"wl_client" },{ "id":"wp_client_main" },{ "id":"wp_client_ext" }], "contributions":[{ "type":"config", "sub-contributions":[{ "type":"js", "uris":[{ "value":"/worklight/common/js/init.js" }] }] }] }

    Листинг 13. Модуль wl_init с удаленным определением prereq wl_client

    { "id":"wl_init", "prereqs":[ { "id":"wp_client_main" },{ "id":"wp_client_ext" }], "contributions":[{ "type":"config", "sub-contributions":[{ "type":"js", "uris":[{ "value":"/worklight/common/js/init.js" } ] }] }] }

Теперь есть все, чтобы портал мог определить устройство, которое обращается к WebSphere Portal, и включить набор файлов, необходимый для правильной интеграции с Worklight.

Тестирование приложения

Поскольку это упражнение ― продолжение упражнения из Части 1, пример для тестирования Worklight API уже существует. Этот пример отображает в верхней части страницы имя и версию устройства. Тест подтвердит, что эта информация отображается правильно для обоих эмуляторов Android и iOS.

  1. Еще раз соберите и разверните приложение, щелкнув на нем правой кнопкой мыши и выбрав команду Build All and Deploy. Вы увидите ход процесса на панели состояния Eclipse внизу справа.
  2. После завершения процесса щелкните правой кнопкой на WLPortalWLPortalAppAndroid и выберите Run As... > Android Application. Запустится эмулятор Android, и приложение отобразит ваш WebSphere Portal.
  3. После отображения приложением WebSphere Portal перейдите на страницу, к которой вы применили специальную тему и профиль Worklight. Если эта страница не поддерживает анонимный доступ, войдите и перейдите на эту страницу. Понадобится несколько секунд на загрузку настроек в устройство, и вы увидите их в верхней части страницы, как показано на рисунке 14.

    Рисунок 14. Эмулятор Android отображает портал с примером API Worklight
    Рисунок 14.  Эмулятор Android отображает портал с примером API Worklight

  4. Щелкните правой кнопкой на iphone под WLPortalApp и выберите Run As > Xcode project. Запустится приложение Xcode, и вам нужно будет запустить приложение в эмуляторе iOS. После запуска приложение отобразит WebSphere Portal.
  5. Еще раз перейдите на страницу со специальной темой и профилем Worklight. В верхней части страницы вы увидите имя и версию устройства, как показано на рисунке 15.

    Рисунок 15. Эмулятор iOS отображает WebSphere Portal с API Worklight
    Рисунок 15. Эмулятор iOS отображает WebSphere Portal с API Worklight

Заключение

IBM WebSphere Portal позволяет легко адаптировать собственные возможности устройства для многоканальных Web-приложений. Оболочку Worklight для Android и iOS можно упаковать в готовый пакет и опубликовать его в app store или развернуть посредством MDM. В результате вы получите все возможности по управлению многоканальным Web-сайтом WebSphere Portal, дополненные "родными" службами для разных устройств. Следующая статья из этого цикла будет посвящена конфигурации для единого входа и интеграции соответственно Worklight и Web Exeperience Factory.

Загрузка

Описание

Имя

Размер

Метод загрузки

Пример приложения Part2-sample_files.zip 9 КБ HTTP 



 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 04.04.2013 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
ABBYY Lingvo x6 Многоязычная Домашняя версия, электронный ключ
ABBYY Lingvo x6 Многоязычная Профессиональная версия, электронный ключ
Raize Components 6
VMware Workstation 14 Player for Linux and Windows, ESD
VMware Horizon 7 Standard : 10 Pack (CCU)
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Программирование на Visual Basic/Visual Studio и ASP/ASP.NET
Краткие описания программ и ссылки на них
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100