Быстрый старт
Делимся удовольствием!
Конечно, приятно сделать забавное собственное фото, но разделить удовольствие со всем миром - это еще приятнее. До сегодняшнего дня, однако, отправлять информацию в различные социальные сети означало использование специальных 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-строк!
увеличить изображение
Рис. 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, но я хочу предоставить вам универсальное решение, которое вы сможете использовать в своих приложениях и в других случаях.