Материалы к модулю Вы можете скачать здесь.
В этом модуле вы изучите ограничения доступа в приложениях для Магазина Windows, способы настройки манифеста приложения для разрешения доступа к файлам, и средствам выбора файлов (File Pickers) для доступа к пользовательским файлам. Также вы узнаете о том, как можно использовать класс StorageFolder для сохранения специфических данных приложения.
Вам понадобится решение Starter из подпапки \Module_6_Assets\Starter. Это итоговый проект из предыдущего модуля.
В отличие от традиционных приложений Windows, WinRT-приложения по умолчанию ограничивают доступ к пользовательским данным и устройствам. Если WinRT-приложение требует разрешения только на чтение одного или нескольких файлов, то, скорее всего, можно использовать средство выбора файлов (File Picker) с настройками безопасности, установленными по умолчанию.
При помощи элемента управления File Picker можно:
Также можно использовать File Picker расширенно: для доступа приложений к файлам или доступа приложения к другому приложению.
Однако некоторые разрешения на доступ к файлу не включены по умолчанию из-за настроек безопасности. Если приложению требуется программный доступ к целой пользовательской библиотеке (музыка, видео или другие файлы), необходимо объявлять соответствующую возможность (характеристику) в манифесте приложения.
Например, приложение предназначено для проигрывания всей музыки из библиотеки пользователя. Так как данное приложение запрашивает все музыкальные файлы из пользовательской библиотеки программно, необходимо специально объявлять возможность musicLibrary.
| Сценарий | Необходимость объявления возможности |
|---|---|
| Открытие файла | Нет |
| Выбор места сохранения файла | Нет |
| Получение списка музыкальных файлов из пользовательской библиотеки | Да. Необходимо объявление в манифесте приложения возможности musicLibary |
| Получение списка изображений из пользовательской библиотеки | Да. Необходимо объявление в манифесте приложения |
Когда приложение представлено к сертификации в Магазина Windows, оно исследуется тщательнее, чем больше в нём используется возможностей, поэтому нужно внимательно следить за тем, все ли объявленнные возможности необходимы.
Для того, чтобы объявить возможности в приложении, необходимо редактировать манифест приложения, который является XML-файлом. В Visual Studio есть специальный редактор для редактирования этого файла.


Promise-объект для асинхронных операций
Доступ к файлам в WinRT осуществляется асинхронно. Это означает, что процесс доступа к файлу начинается отдельным потоком, а когда файловая операция завершена, происходит возвращение к вызывающему потоку. Фактически, эти операции происходят параллельно с другими (ввод данных, анимация и пр.).
В WinJS есть promise-объект, необходимый для помощи в асинхронных операциях. Promise-объект может быть использован для всех асинхронных операций, включая web-запросы, файловые операции и др., поэтому важно хорошо понимать принцип его действия.
Базовая структура вызова с использованием Promise-объекта выглядит следующим образом (псевдокод):
myObject.doSomethingAsync()
.then(onCompleteFunction1, onErrorFunction1, onProgressUpdate1)
myObject
определённый объект, например, объект запроса файла или ссылки.
doSomethingAsync
использование асинхронного метода, например, запрос на открытие файла или загрузка WEB-страницы
then
определяет, что произойдёт, когда асинхронная функция завершится или произойдет ошибка
onCompleteFunction1
функция, которая будет выполняться после завершения асинхронной операции
onErrorFunction1
(опционально) функция, которая будет выполняться, если во время выполнения асинхронной операции возникнет ошибка или исключение
onProgressUpdate1
(опционально) функция, которая будет выполняться, если promise-объект производит обновление элемента управления, позволяющего судить о ходе длительной операции. Обновления прогресса операции не обязательны, но они удобны в продолжительных операциях, где можно показать пользователю визуально, что процесс идёт (как progress bar – строка состояния)
Можно многократно объединять функции then(). Это бывает полезно, когда необходимо использовать несколько асинхронных операций, к примеру, получение данных от веб-сервиса и их последующее сохранение в файл.
Объединение нескольких методов then() может выглядеть так (псевдокод):
myObject.doSomethingAsync()
.then(onCompleteFunction1, onErrorFunction1, onProgressUpdate1)
.then(onCompleteFunction2, onErrorFunction2, onProgressUpdate2)
Другая важная функция promise – это метод done(). Метод done() похож на метод then() за исключением того, что он может инициировать ошибки, которые могут произойти. Полезно помещать эту функцию последней в цепочке функций, так как этот метод может перехватывать любые ошибки метода then() и инициировать или обрабатывать их.
Использование метода done() совместно с методом then() может выглядеть так:
myObject.doSomethingAsync()
.then(onCompleteFunction1, onErrorFunction1, onProgressUpdate1)
.done(onCompleteFunction2, onErrorFunction2, onProgressUpdate2)
Теперь вы имеете представление о том, как функционируют возможности (Capabilities) и средства асинхронного исполнения задач (Promises). Сейчас рассмотрим средство выбора файла (File Picker) для выбора изображения из библиотеки пользователя.

pickAPicture(), которая использует управление средством выбора файла, чтобы разрешить пользователю выбрать файл. Она также представляет переменную под названием picturePicked, так что выбранный файл будет позже доступен в коде.
Этот код находится в файле \Module_6_Assets\snippets\filePicker.txt
(function () {
"use strict";
function pickAPicture() {
var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
openPicker.viewMode = Windows.Storage.Pickers.PickerViewMode.thumbnail;
openPicker.suggestedStartLocation =
Windows.Storage.Pickers.PickerLocationId.picturesLibrary;
openPicker.fileTypeFilter.replaceAll([".png", ".jpg", ".jpeg"]);
openPicker.pickSingleFileAsync().then(function (file) {
if (file) {
ImageUtils.picturePicked = file;
}
Этот код находится в файле \Module_6_Assets\snippets\includeImageUtils.txt
<!-- Add in the code to manage file pick --> <script src="/js/imageUtils.js"></script>
addEventListener нужно вызвать btnAddItem. Этот код сначала создаёт переменную btnSelectImage, которая ссылается на кнопку выбора изображения во всплывающем меню. Затем создаётся переменная btnAppBarAddImage, которая ссылается на кнопку AppBarCommand на панели приложения. Далее, свойство закрепления (sticky) устанавливается в значение "истина" для всплывающего меню, которое удерживает его открытым, пока пользователь выбирает изображение. И в конце необходимо установить событие для щелчка на кнопке btnSelectImage.
Этот код находится в файле \Module_6_Assets\snippets\includeImageUtils.txt
var btnSelectImage = document.getElementById("btnSelectImage");
var appbar = document.getElementById("appbar");
var btnAppBarAddImage = document.getElementById("btnAppBarAddImage");
appbar.winControl._sticky = true;
btnAppBarAddImage.winControl.flyout._sticky = true;
Время от времени приложению может быть необходимо сохранить данные или настройки на диске. К примеру, требуется сохранить пользовательские настройки или список файлов. Для этих целей нужно использовать Local Application Data (локальные данные приложения).
Пользователю также могут понадобиться эти настройки для синхронизации между всеми устройствами. Можно использовать Roaming Application Data (перемещаемые данные приложения) для разрешения синхронизации между пользовательскими устройствами.
Некоторым приложениям могут потребоваться Temporary Application Data (временные данные) – к примеру, файлы, которые кэшируются в течение одного сеанса работы с приложением, или промежуточные файлы. Нельзя гарантировать, что после завершения работы приложения такие файлы останутся, пользователь может выполнить очистку диска для их удаления.
| Хранение данных | Описание |
|---|---|
| Local Application Data (Локальные данные приложения) | Расположены на текущем носителе до тех пор, пока приложение или пользователь не удалит их |
| Roaming Application Data (Перемещаемые данные приложения) | Расположены на всех устройствах, на которые установлено приложение (механизм их работы основан на синхронизации) |
| Temporary Application Data (Временные данные приложения) | Расположены на текущем носителе, но могут быть удалены системой в любой момент |
Описанные выше и сохранённые в папках на диске файлы хранения данных находятся в папке C:\Users\{Username}\AppData\Local\Packages\{package family ID}\
… где {Username} – это идентификатор пользователя в Windows, {package family ID} – это идентификатор пакета приложения, который можно найти на вкладке Упаковка (Packaging) в редакторе манифеста приложения.
Измените учебное приложение таким образом, чтобы в нём можно было сохранять выбранные пользователем изображения в хранилище данных приложения. Начните с добавления новой группы данных в состав предопределенных данных.
Этот код доступен в файле \Module_6_Assets\snippets\addInMyImagesGroup.txt
var sampleGroups = [
{ key: "Basketball", title: "Basketball", subtitle: "Search results …
{ key: "Soccer", title: "Soccer", subtitle: "Search results for Soccer …
{ key: "Baseball", title: "Baseball", subtitle: "Search results for …
// Add in "My Images"
{
key: "MyImages", title: "My Images",
subtitle: "My Image Collection",
backgroundImage: "/images/groupMyImages.png",
description: "This group contains images added by the user."
},
];
getItemsFromGroup).
Этот код находится в файле \Module_6_Assets\snippets\addInMyImagesGroup.txt
function addToMyImages(title, description, imageFile) {
var imageFileBase64;
imageFile.openAsync(Windows.Storage.FileAccessMode.read).then(function (_stream) {
var inputStream = _stream;
var reader = new Windows.Storage.Streams.DataReader(inputStream);
var size = inputStream.size;
if (size > 0) {
reader.loadAsync(size).then(function () {
var b = reader.readBuffer(size);
imageFileBase64 =
Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(b);
imageFileBase64 = "data:image/png;base64," + imageFileBase64;
// Add a new item to "My Images"
var item = { group: sampleGroups[3], title: title, subtitle: imageFile.name,
description: description, content: itemContent, backgroundImage: imageFileBase64 };
list.push(item);
// filter out just the "My Images" group items, and convert to an ARRAY
// with slice(0)... this is so it can be serialized properly!
var myImagesGroup = getItemsFromGroup(sampleGroups[3]).slice(0);
// serialize to JSON for storage as string
var myImagesSerialized = JSON.stringify(myImagesGroup);
// SAVE to local storage
var applicationData = Windows.Storage.ApplicationData.current;
var localFolder = applicationData.localFolder;
localFolder.createFileAsync("myimages.txt",
Windows.Storage.CreationCollisionOption.replaceExisting)
.then(function (sampleFile) {
return Windows.Storage.FileIO.writeTextAsync(sampleFile,
myImagesSerialized);
});
});
}
});
}
О сериализации
В коде, приведённом выше, вы сохранили массив объектов на диск с применением сериализации. Сериализация – это процесс преобразования объектов в формат хранения, подходящей для записи на диск или сетевой передачи. Здесь используется специальный объект JSON, который позволяет выполнять сериализацию в формате JavaScript Object Notation (объектная нотация JavaScript).
Вы узнаете о JSON в 7 модуле.
addToMyImages была доступна для вызова за пределами data.js, поэтому необходимо сделать её внешней (public), соответствующим образом описав ее при объявлении пространства имен. Добавьте выделенный код внизу data.js, в разделе объявления пространства имен.
WinJS.Namespace.define("Data", {
items: groupedItems,
groups: groupedItems.groups,
getItemsFromGroup: getItemsFromGroup,
getItemReference: getItemReference,
resolveGroupReference: resolveGroupReference,
resolveItemReference: resolveItemReference,
addToMyImages: addToMyImages
});
btnAddItem.addEventListener в функции инициализации. Удалите код диалогового сообщения (Message Dialog) и замените его выделенными строками ниже. Этот код выполняется, когда нажимается кнопка Добавить элемент, и он скрывает всплывающее меню и панель приложения и сохраняет данные изображения.
btnAddItem.addEventListener("click", function (e) {
// the following code will be executed when btnAddItem is clicked:
var title = document.getElementById("title");
var description = document.getElementById("description");
btnAppBarAddImage.winControl.flyout.hide();
appbar.winControl._sticky = false;
// save the new item to the data
Data.addToMyImages(title.value, description.value,
ImageUtils.picturePicked);
});
В некоторых случаях для доступа к пользовательским файлам в приложениях необходимо объявлять возможности. Иногда File Picker (средство выбора файла) пригодно для того, чтобы разрешить пользователю задействовать файлы в приложении. Но независимо от того, какой доступ необходим в данный момент, важно понимать асинхронную модель. Необходимо знать, когда должны использоваться методы 'then' и 'done'.
В упражнениях этого модуля вы сохраняли пользовательские изображения на локальный носитель. Каким образом можно сделать эти данные перемещаемыми (roaming), чтобы этим можно было пользоваться на всех пользовательских устройствах? Выясните это по нижеприведенной ссылке, после чего добавьте возможности по работе с перемещаемыми данными (roaming data) в ваше приложение.
http://msdn.microsoft.com/en-us/library/windows/apps/hh465123.aspx
Вы можете узнать больше о работе с файлами и о разрешениях, зайдя по следующим ссылкам.
http://msdn.microsoft.com/en-us/library/windows/apps/hh967755.aspx
Подробности о доступе к файлам и разрешений, необходимым для операций с ними.
http://msdn.microsoft.com/en-us/library/windows/apps/hh464936.aspx
Описание полного списка возможностей, которые можно объявлять в приложении.
http://msdn.microsoft.com/en-us/library/windows/apps/hh700330.aspx
Описание разработки ПО с использованием асинхронного режима.
Windows.Storage.ApplicationData разрешает сохранение специальных пользовательских данных, используя локальное хранилище данных.Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.