Опубликован: 02.04.2013 | Уровень: для всех | Доступ: платный
Лекция 3:

Быстрый старт

Делимся удовольствием!

Конечно, приятно сделать забавное собственное фото, но разделить удовольствие со всем миром - это еще приятнее. До сегодняшнего дня, однако, отправлять информацию в различные социальные сети означало использование специальных API для каждого сервиса. Работоспособный, но немасштабируемый подход.

Windows 8 вместо этого предложила понятие контракта Общий доступ (Share), который используется для применения возможностей чудо-кнопки Общий доступ (Share) во всех приложениях, реализующих данный контракт. Когда вы, находясь в приложении, нажимаете на чудо-кнопку Общий доступ, Windows запрашивает у приложения исходные (source) данные. Затем система проверяет данные и генерирует список целевых (target) приложений, которые способны воспринимать данные в этом формате (в соответствии с манифестом), и отображает список приложений в панели чудо-кнопки Общий доступ. Когда пользователь выбирает целевой приложение, это приложение активируется и ему передаются исходные данные. Коротко говоря, контракт - это промежуточная абстракция, находящаяся между двумя приложениями, таким образом, приложение-источник и приложение-приемник никогда не нуждаются в информации друг о друге.

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

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

Этот запрос приходит через событие datarequested отправленное объекту Windows.ApplicationModel.DataTransfer.DataTransferManager9Так как мы, когда приложение выполняется, постоянно прослушиваем событие datarequested и добавляем прослушиватель события лишь один раз, нам не нужно беспокоиться о том, чтобы удалять его, вызывая removeEventListener. Подробности смотрите в разделе "События WinRT и removeEventListener" в "Анатомия приложения и навигация по страницам" . Для начала, нам лишь нужно установить соответствующий прослушиватель события, разместив нижеприведенный код в событии activated в файле default.js после установки прослушивателя для события click элемента img:

var dataTransferManager = Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView();
dataTransferManager.addEventListener("datarequested", provideData);

Идея текущего представления (current view) заключается в том, что это то, что мы видим в появляющихся время от времени областях. Это отражает то, что приложение может быть запущено по разным причинам - таким, как обслуживание контракта - и, таким образом, предоставлять пользователю различные страницы или представления. Эти представления (не связанные с режимами просмотра, такими, как прикрепленный, заполняющий и другие) могут быть активны одновременно. Для обработки этих состояний убедитесь в том, что ваш код реагирует на них, определенные API возвращают объекты, соответствующие текущему представлению приложения, как мы видим здесь.

В данном событии обработчик принимает объект Windows.ApplicationModel.DataTransfer.DataRequest в параметрах события (e.request), которые хранятся в объекте DataPackage (e.request.data). Для того чтобы сделать данные доступными для целей общего доступа, вы заполняете пакет данных (data package) информацией в доступном вам формате. (Мы сохраняем данные в lastPosition и lastCapture.) В нашем случае, мы убеждаемся в том, что имеем фотографию и информацию о местоположении и заполняем свойства текста и изображения (если вы хотите получить карту от сервиса Bing для передачи её в другое приложение, посмотрите материал "Получение статической карты" (http://msdn.microsoft.com/library/ff701724.aspx):

//Поместите это после capturePhoto 
function provideData(e) {
var request = e.request;
var data = request.data;

if (!lastPosition || !lastCapture) {
//Нечего передавать, поэтому выходим
 return;
}

data.properties.title = "Here My Am!";

data.properties.description = "At ("	
+ lastPosition.latitude + ", " + lastPosition.longitude + ")";	
	
//Передавая изображение, добавляем миниатюру	
var streamReference =	
Windows.Storage.Streams.RandomAccessStreamReference.createFromFile(lastCapture);
data.properties.thumbnail = streamReference;	
// Рекомендовано использовать и setBitmap и setStorageItems при передаче отдельного изображения
//так как целевое приложение может поддерживать лишь что-то одно.

//Поместим файл изображения в массив и передадим его setStorageItems data.setStorageItems([lastCapture]);

//Методу setBitmap требуется RandomAccessStream. data.setBitmap(streamReference);
}

Последняя часть этого кода представляет собой стандартную реализацию возможности по передаче изображения из файла (которое находится в lastCapture). Я взял большую часть этого кода из примера "Приложение-источник для общего доступа", (http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Source-App-d9bffd84), подробнее этот пример мы рассмотрим в "Жизненный путь приложений для Магазина Windows: Характеристики платформы Windows 8" курса "Программная логика приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript и их взаимодействие с системой".

С этим последним дополнением, и с подходящим приложением-приемником (таким, как в примере "Приложение-цель для общего доступа", (http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Target-App-e2689782), как показано на Рис. 2.22), сейчас мы получили весьма функциональное приложение, которое состоит из 35 строк HTML-кода, 125 строк CSS и 100 JavaScript-строк!

Передача данных (обезьяна увидела, обезьяна сделала!) в приложение из примера реализации целевого приложения Windows SDK. Целевое приложение частично перекрывает текущее приложение, таким образом, пользователь никогда не потеряет контекст приложения

увеличить изображение
Рис. 2.22. Передача данных (обезьяна увидела, обезьяна сделала!) в приложение из примера реализации целевого приложения Windows SDK. Целевое приложение частично перекрывает текущее приложение, таким образом, пользователь никогда не потеряет контекст приложения

Исключительное доверие: Принимаем сообщения из iframe

Вот еще один фрагмент кода, который я включил в программу "Here My Am!" для того, чтобы завершить пример базового взаимодействия между приложением и iframe: возможность отправлять сообщения из iframe назад, в приложение. В нашем случае, мы хотим знать, когда изменилось положение маркера местоположения для того, чтобы обновить lastPosition.

Для начала, вот простая стандартная функция, которую я добавил в map.html для того, чтобы включить в неё подходящий вызов postMessage, направленный к приложению, из iframe:

function function notifyParent(event, args) {
Добавляем имя события к объекту, содержащему аргументы, и конвертируем в строку для формирования сообщения
args["event"] = event;	
window.parent.postMessage(JSON.stringify(args), "ms-appx://" + document.location.host);

Эта функция берет имя события, добавляет его к объекту, содержащему параметры, конвертирует всё это в строку и отправляет результат туда, откуда её вызвали.

Когда маркер перетащили, карта Bing генерирует событие dragend, к которому мы прикрепим обработчик и обработаем событие в функции setLocator сразу после того, как маркер был создан (так же в map.html):

var pushpin = new Microsoft.Maps.Pushpin(location, { draggable: true });

Microsoft.Maps.Events.addHandler(pushpin, "dragend", function (e) {	
var location = e.entity.getLocation();	
notifyParent("locationChanged",	
{ latitude: location.latitude, longitude: location.longitude });
});

Вернемся назад, в default.js (то есть - в приложение) и добавим прослушиватель для входящих messages (сообщений) внутрь app.onactivated:

window.addEventListener("message", processFrameEvent);

Обработчик processFrameEvent ищет в сообщении информацию о событии и поступает соответствующим образом:

function processFrameEvent (message) {	
//Проверяем данные и источник (в нашем случае это - страница из веб-контекста)	
if (!message.data || message.origin !== "ms-appx-web://" + document.location.host) {
return;	
}	

if (!message.data) {
return;
}

var eventObj = JSON.parse(message.data);

switch (eventObj.event) {	
case "locationChanged":	
lastPosition = { latitude: eventObj.latitude, longitude: eventObj.longitude };
break;	

default:
break;
}
};

Ясно, что здесь больше кода, чем нам нужно для того, чтобы обработать одно сообщение или событие из iframe, но я хочу предоставить вам универсальное решение, которое вы сможете использовать в своих приложениях и в других случаях.

Владимир Мороз
Владимир Мороз
Украина, Киев, Киевская государственная академия водного транспорта имени Гетмана Петра Конашевича-Сагайдачного, 2012
Сергей Ширяев
Сергей Ширяев
Россия, г. Москва