Статьи

SkyDrive Sync на Windows Phone — базовый комплект

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 и посмотрите, какая папка создается для вас:

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