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 и посмотрите, какая папка создается для вас:
Поздравляю, у вас есть основной ремень безопасности. В следующей статье я буду говорить о том, как на самом деле синхронизировать контент между устройствами, которые связаны с той же учетной записью, даже если контент не был создан ни на одном из устройств.



