Windows Phone обладает широкими возможностями по синхронизации «коробочного» контента, например изображений и видео. Однако с выпуском платформы Windows Phone 8 разработчики также получили доступ к внешнему хранилищу (SD-карте). Чаще всего вы хотите убедиться, что контент, который вы делаете доступным через ваше приложение, синхронизирован, независимо от того, какое устройство пользователь в данный момент держит в своих руках, если оно связано с той же учетной записью.
В этой статье я собираюсь показать вам, как этого добиться с помощью Microsoft SkyDrive и учетной записи Microsoft .
Учитывая, что у вас уже установлен Windows Phone SDK , создайте новое приложение C # для Windows Phone. В MainPage.xaml убедитесь, что вы удалите весь ненужный контент — мы создадим все с нуля
Теперь к важной части — добавление ссылки на Microsoft Live SDK. Вы можете получить его бесплатно через менеджер пакетов NuGet. Просто щелкните правой кнопкой мыши на References для вашего проекта в Solution Explorer и выберите Manage NuGet Packages.
,
В диспетчере пакетов вы можете легко получить Live SDK, если вы используете его имя в качестве поискового запроса в официальном репозитории NuGet. Найдя его, установите его, и ссылка на нужные библиотеки будет автоматически добавлена в ваш проект.
Добавьте ссылку на пространство имен XML в MainPage.xaml , которая позволит вам использовать кнопку входа, предоставляемую через Live SDK:
xmlns:live="clr-namespace:Microsoft.Live.Controls;assembly=Microsoft.Live.Controls"
И теперь, очевидно, пришло время добавить кнопку фактического входа на страницу:
<live:SignInButton Height="100" VerticalAlignment="Top"></live:SignInButton>
Здесь возникает интересный аспект использования Live SDK — так же, как и с любым другим API, вам необходимо каким-то образом идентифицировать ваше приложение для Microsoft, чтобы всегда было известно, какое приложение пытается получить доступ к данным пользователя.
Для этого вам необходимо убедиться , что вы создаете свой ключ тождественного собственного приложения здесь . Просто создайте новое приложение и скопируйте присвоенный ему идентификатор клиента. Важно отметить, что само приложение должно быть помечено как мобильное .
Получив идентификатор клиента, вставьте его в качестве значения свойства ClientId в только что созданный SignInButton:
<live:SignInButton Height="100" VerticalAlignment="Top" ClientId="YOUR_ID_HERE"></live:SignInButton>
Давайте также поговорим о сферах. Когда вы создаете приложение, которое использует учетную запись Microsoft пользователя, вы должны четко указать, к каким данным вы хотите получить доступ и когда вы хотите получить к ним доступ. В Live API это определяется с помощью областей .
Для нашего примера приложения нам понадобятся следующие области:
- wl.signin
- wl.basic
- wl.skydrive
- wl.skydrive_update
-
wl.offline_access
Все это описано в вышеприведенном документе MSDN по областям, поэтому не стесняйтесь зацикливать его, если вы не уверены, что охватывает каждый из элементов. Эти области должны быть включены в свойство Scopes в кнопке входа, каждая из которых разделена пробелом:
Scopes="wl.signin wl.basic wl.skydrive wl.skydrive_update wl.offline_access"
На этом этапе вы сможете успешно направить пользователя на страницу входа:
Кроме того, если вы войдете в систему с активной учетной записью Microsoft, вы увидите подробную разбивку возможностей, которые будет использовать приложение, учитывая, что пользователь разрешает доступ к учетной записи для данного приложения.
Отлично, но это все еще бессмысленно — что происходит, когда пользователь входит в систему? В этой ситуации нам нужно убедиться, что мы записали сессию. Чтобы сделать это, в XAML вам нужно обязательно подключить событие SessionChanged для SignInButton:
SessionChanged="SignInButton_SessionChanged"
Перейдите к выделенному коду и создайте объект-заполнитель для LiveConnectSession, с которым мы будем работать (в любом месте класса MainPage):
LiveConnectSession _currentSession;
Когда происходит событие SessionChanged, в случае успешного входа в систему вы получите LiveConnectSession в результате:
private void SignInButton_SessionChanged(object sender, Microsoft.Live.Controls.LiveConnectSessionChangedEventArgs e) { if (e.Status == Microsoft.Live.LiveConnectSessionStatus.Connected) { _currentSession = e.Session; } }
Фантастика, теперь давайте создадим вспомогательную функцию, которая позволит мне извлекать содержимое текущей связанной учетной записи SkyDrive. Прежде всего, функция, которая позволяет мне динамически указывать имя папки, к которой я хочу обратиться:
public async static Task<List<SkyDriveEntity>> GetFolderContents(LiveConnectSession session, string folderId) { List<SkyDriveEntity> data = new List<SkyDriveEntity>(); try { LiveConnectClient client = new LiveConnectClient(session); LiveOperationResult result = await client.GetAsync(folderId + "/files"); List<object> container = (List<object>)result.Result["data"]; foreach (var item in container) { SkyDriveEntity entity = new SkyDriveEntity(); IDictionary<string, object> dictItem = (IDictionary<string, object>)item; string type = dictItem["type"].ToString(); entity.IsFolder = type == "folder" || type == "album" ? true : false; entity.ID = dictItem["id"].ToString(); entity.Name = dictItem["name"].ToString(); data.Add(entity); } return data; } catch { return null; } }
Поскольку возвращенные данные уже отформатированы, мне нужно убедиться, что я извлек их и назначил их модели. Обратите внимание, что существует класс SkyDriveEntity, который не является частью официального SDK. Я создал вспомогательную модель, которая позволила бы мне легко управлять и запрашивать содержимое облачного хранилища:
public class SkyDriveEntity { public string Name { get; set; } public string ID { get; set; } public bool IsFolder { get; set; } }
Мне также нужно было бы иметь корневую папку, в которой я мог бы хранить синхронизированный контент — обычно это плохой подход, чтобы выгружать все непосредственно в корень SkyDrive из стороннего приложения, поэтому давайте добавим эту функцию:
public async static Task<string> CreateRootFolder(LiveConnectSession session) { string folderId = string.Empty; try { var data = await GetFolderContents(session, "me/skydrive"); if (data != null) { var targetRootFolder = (from c in data where c.IsFolder && c.Name == "SYNCFOLDER" select c).FirstOrDefault(); if (targetRootFolder == null) { LiveConnectClient client = new LiveConnectClient(session); LiveOperationResult result = await client.PostAsync("me/skydrive", "{\"name\":\"SYNCFOLDER\",\"description\":\"SYNCED FOLDER\"}"); folderId = result.Result["id"].ToString(); } else { folderId = targetRootFolder.ID; } } return folderId; } catch { return folderId; } }
Теперь, вернувшись в обработчик событий SessionChanged, вы можете добавить эту строку, чтобы создать корневую папку приложения:
var coreContent = await CreateRootFolder(_currentSession);
Запустите приложение, войдите в систему с учетной записью Microsoft и посмотрите, какая папка создается для вас:
Поздравляю, у вас есть основной ремень безопасности. В следующей статье я буду говорить о том, как на самом деле синхронизировать контент между устройствами, которые связаны с той же учетной записью, даже если контент не был создан ни на одном из устройств.