Tempo de Execução do Windows

Dados em roaming entre os aplicativos do Windows Store e Windows Phone Store

Tony Champion

Existe um conjunto completamente diferente de padrões e expectativas para aplicativos de hoje em relação aos aplicativos de desktop de uma década atrás. Uma dessas expectativas é que os aplicativos funcionem e compartilhem dados entre vários dispositivos. Se um usuário tiver o mesmo aplicativo instalado em seu desktop e laptop, ele esperará que ambos os aplicativos mantenham a mesma configuração e funcionem no mesmo conjunto de dados. Indo um pouco mais além, se o mesmo aplicativo está disponível em vários dispositivos, os usuários esperarão ser capazes de compartilhar dados entre os dispositivos.

No mundo dos aplicativos orientadas aos dados, você pode lidar com essas expectativas, principalmente no banco de dados back-end. Um aplicativo em vários dispositivos pode consultar o mesmo banco de dados remoto e dar ao usuário acesso aos mesmos dados. No entanto, suportar aplicativos com um banco de dados remoto acrescenta uma enorme sobrecarga em termos de arquitetura, desenvolvimento e manutenção. Isso simplesmente não é necessário para todos os aplicativos. Mesmo aplicativos que requerem bancos de dados podem não querer suportar informações específicas do aplicativo em um banco de dados projetado para vários propósitos.

Os aplicativos do Windows Store e Windows Phone Store atendem a essa necessidade com o conceito de dados em roaming. Cada aplicativo recebe automaticamente uma pequena quantidade de armazenamento em nuvem por usuário. O usuário pode usar isso para salvar informações sobre o aplicativo e as compartilhar através de várias instalações do aplicativo. Os aplicativos do Windows Phone Store e Windows Store pega esta outra etapa e permite que os usuários compartilhem dados entre aplicativos de dispositivos diferentes. Aqui, eu olharei para os usos de dados em roaming em seus aplicativos e como usar esses dados de forma eficaz através dos dispositivos.

Esse artigo usará os aplicativos universais para demonstrar o compartilhamento dos dados em roaming através dos dispositivos, no entanto, essas mesmas técnicas funcionam nos aplicativos Windows Phone Store e Windows Store em separado. Os dados em roaming também funcionam tão bem em toda a HTML - e os aplicativos com base em XAML.

Use dados em roaming

Um dos aspectos mais agradáveis de usar dados em roaming em seus aplicativos é que está automaticamente disponível e não requer nenhuma configuração ou outras definições. Simplesmente use a API de dados em roaming disponível para deixar seu aplicativo aproveitar os dados em roaming.

O que é roaming A primeira pergunta que a maioria dos desenvolvedores fazem é que tipo de dados é bom para as configurações em roaming. Tenha em mente que existe um limite de tamanho apertado sobre a quantidade de dados que podem realizar roaming. Isso significa que você precisa fazer um planejamento avançado.

Algumas das coisas mais comuns para o roaming são as preferências e configurações definidas pelo usuário - aspectos como cores, fontes, opções e assim por diante. Esses valores podem assumir diferentes significados, se você está compartilhando entre os aplicativos do Windows Store e Windows Phone Store, mas proporcionando uma experiência semelhante e entre plataformas será uma grande vitória para seu aplicativo.

A navegação atual dentro de seu aplicativo pode ser um poderoso recurso. Se um usuário puxa um relatório sobre um Windows Phone e, em seguida, registra em um computador no trabalho, por que a versão do Windows Store do aplicativo não pula direto para o mesmo relatório? Se um usuário está assistindo a um vídeo no desktop, por que a versão do Windows Phone não pode pular para o mesmo vídeo?

Os dados temporários podem ser outro candidato ao roaming. Se um usuário está no meio da digitação de um email em um laptop, ele devem ser capaz de continuar esse mesmo email em seu desktop.

Grandes conjuntos de dados normalmente não são candidatos aos dados em roaming. No entanto, você pode colocar uma chave para o conjunto de dados nos dados em roaming e puxar o grande conjunto de dados para baixo para o novo cliente com base na chave que você compartilha.

A lista continua, mas a meta é a mesma. Os dados em roaming devem permitir que o usuário sempre se sinta conectado ao seu aplicativo.

Ativar dados em roaming Existe alguns pré-requisitos para os seus aplicativos sincronizarem dados entre dispositivos com sucesso. Em primeiro lugar, os usuários têm que fazer logon no dispositivo usando uma conta da Microsoft. As configurações de roaming estão associadas a um aplicativo e uma conta de usuário Microsoft. Se o usuário não estiver usando uma conta da Microsoft, está faltando uma parte dos dados de sua chave. 

Em segundo lugar, é importante que o usuário não tenha desativado as capacidades dos dados em roaming para o dispositivo. Um usuário pode fazer isso manualmente ou pode ser uma política de dispositivo aplicada por administradores do sistema. Se os dados em roaming está desativado, os dados não serão sincronizados.

Se os dados em roaming não estão ativados em um dispositivo, os dados ainda estão disponíveis localmente. Portanto, o seu aplicativo não precisa se preocupar com a verificação para ver se os dados em roaming está sincronizando e usando um fluxo de trabalho diferente.

Explorar a API

Você encontrará a API para os dados em roaming no objeto Windows.Storage.ApplicationData. Cada aplicativo mantém uma única instância do ApplicationData que você pode fazer referência com a propriedade estática atual:

var appData = Windows.Storage.ApplicationData.Current;

A API não inclui um mecanismo para forçar os dados em roaming a sincronizar. Esse processo é deixado para o próprio dispositivo gerenciar.

Você pode usar dois tipos de dados em roaming. Você encontrará o primeiro na propriedade RoamingSettings do ApplicationData, que é um ApplicationDataContainer que gerencia pares de chave/valor. As configurações são gerenciadas na propriedade RoamingSettings.Values e você pode acessá-las como uma matriz indexada na cadeia de caracteres. As chaves podem ter qualquer cadeia de caracteres de até 255 caracteres. O valor pode ser um objeto, enquanto ele é um tipo de dados do Windows Runtime suportado. Isso significa que você não pode armazenar objetos personalizados nas configurações em roaming.

Você pode acessar as configurações em roaming através da propriedade Valores anexada. Adicionar ou atualizar uma configuração alterando a propriedade Valores principal indexada para o novo valor. Use o método Values.Remove para remover uma configuração. O código a seguir mostra um exemplo de criação, leitura e remoção de uma configuração em roaming:

var roamingSettings = ApplicationData.Current.RoamingSettings;
// Create setting
roamingSettings.Values["setting1"] = "My First Setting";
// Read setting
var settings1 = roamingSettings.Values["setting1"];
// Remove setting
roamingSettings.Values.Remove("setting1");
// Clear all settings
roamingSettings.Values.Clear();

Armazenar tipos de dados do Windows Runtime simples funcionará em alguns casos. No entanto, existem momentos em que o armazenamento de todo o objeto faz sentido. Há algumas maneiras de armazenar classes em dados em roaming, mas você pode usar um ApplicationDataCompositeValue para armazenar objetos mais complexos em RoamingSettings.

Um ApplicationDataCompositeValue é uma coleção de pares de chave/valor armazenados juntos. Essa é uma ótima maneira de agrupar itens que permanecerão sincronizados como uma unidade única. O código a seguir mostra um exemplo de criação de um ApplicationDataCompositeValue e a adição ao RoamingSettings:

var compositeValue = new ApplicationDataCompositeValue();
compositeValue["firstName"] = "Tony";
compositeValue["lastName"] = "Champion";
compositeValue["age"] = 38;
roamingSettings.Values["personalInfo"] = compositeValue;

O downfall para esta abordagem é que não há mecanismo para automaticamente ir para e de um objeto complexo para um ApplicationDataCompositeValue. Uma abordagem para resolver isso é criar funções auxiliares para as classes que lidarão com a conversão para você. A Figura 1 mostra uma classe de Pessoa com dois métodos estáticos - ToCompositeSetting e FromCompositeSetting. Esses métodos convertem os dados armazenados no exemplo anterior para um objeto de Pessoa, que fará coisas como ligação de dados muito menos complexa.

Figura 1 Converter do ApplicationDataCompositeValue para Classe Person

public class Person
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public int Age { get; set; }
  public static Person 
    FromComposite(ApplicationDataCompositeValue composite)
  {
    return new Person()
    {
      FirstName = (string)composite["firstName"],
      LastName = (string)composite["lastName"],
      Age = (int)composite["age"]
    };
  }
  public static ApplicationDataCompositeValue ToComposite(Person person)
  {
    var composite = new ApplicationDataCompositeValue();
    composite["firstName"] = person.FirstName;
    composite["lastName"] = person.LastName;
    composite["age"] = person.Age;
    return composite;
  }
}

A Figura 2 usa a nova classe Person para obter e armazenar as informações pessoais em RoamingSettings.

Figura 2 Obter e armazenar informações no RoamingSettings

var person = new Person()
{
  FirstName = "Tony",
  LastName = "Champion",
  Age = 38
};
roamingSettings.Values["personalInfo"] = Person.ToComposite(person);
if (roamingSettings.Values.ContainsKey("personalInfo"))
{
  var composite =
    (ApplicationDataCompositeValue)roamingSettings.Values["personalInfo"];
  var roamingPerson = Person.FromComposite(composite);
}

Existe uma chave especial nas configurações em roaming que você pode usar para os dados que você precisa sincronizar imediatamente. Adicionar HighPriority para qualquer configuração o terá sincronizado o mais rápido possível. Isso é ótimo para itens como um número de página do livro atual, uma estrutura de vídeo pausada e qualquer outra coisa que ajudará a fornecer uma experiência de conexão entre os dispositivos. Por exemplo, se um usuário está assistindo a um filme no seu aplicativo do Windows Store, você poderia fornecer o aplicativo do Windows Phone Store com o suporte de dados apropriado para o local atual do usuário no filme:

var roamingSettings = ApplicationData.Current.RoamingSettings;
var composite = new ApplicationDataCompositeValue();
composite["movieId"] = myVidPlayer.MovieId;
composite["position"] = myVidPlayer.CurrentTime;
roamingSettings.Values["HighPriority"] = composite;

Os arquivos são o segundo tipo de dados em roaming. O objeto ApplicationData contém uma propriedade RoamingFolder que devolve uma instância StorageFolder onde o seu aplicativo pode ler e gravar arquivos para serem sincronizados.

Você pode adicionar praticamente qualquer tipo de arquivo ao RoamingFolder. No entanto, o nome do arquivo deve estar em conformidade com certas especificações. Em primeiro lugar, o nome do arquivo e comprimento da extensão máximos é de 256 caracteres. Além disso, o nome do arquivo não pode ter espaços entre linhas. Há também um grupo de caracteres Unicode que não são permitidos.

Há também vários tipos de arquivos que não são permitidos, pois eles agem como pastas, como .zip e .cab. Se você adicionar um arquivo ao RoamingFolder que não atende a esses requisitos, o arquivo não será sincronizado, mas ainda estará disponível para acesso local.

Um uso para o RoamingFolder está armazenando objetos complexos. Aqui está um exemplo de assumir o mesmo objeto Person, serializando e gravando em um arquivo no RoamingFolder:

var roamingFolder = ApplicationData.Current.RoamingFolder;
// Create file and open a stream to write to
StorageFile personFile = await roamingFolder.CreateFileAsync(
  "personInfo.txt", CreationCollisionOption.ReplaceExisting);
var writeStream = await personFile.OpenStreamForWriteAsync();
// JSON serialize object
var serializer = new DataContractJsonSerializer(typeof(Person));
serializer.WriteObject(writeStream, person);
// Flush the stream
await writeStream.FlushAsync();

A serialização JSON é usada sobre o XML para considerações de tamanho. Com as restrições de tamanho para os dados em roaming no local, cada byte conta.

Você pode usar a lógica reversa para recuperar um objeto do RoamingFolder. O seguinte código demonstra a leitura desse mesmo arquivo e retorna um objeto Person:

// Create file and open a stream to write to
var readStream = await 
  roamingFolder.OpenStreamForReadAsync("personInfo.txt");
// JSON deserialize object
var serializer = new DataContractJsonSerializer(typeof(Person));
var roamingPerson = (Person)serializer.ReadObject(readStream);

Agora você pode ler e gravar dados em roaming a serem sincronizados entre os dispositivos, mas como você saberá quando eles foram atualizados? Isso é manipulado pelo evento DataChanged em ApplicationData. Todas as vezes que um dispositivo recebe novos dados em roaming, o evento DataChanged dispara, passando o objeto ApplicationData atualizado. Isso permite que você faça os ajustes no seu aplicativo, quando os dados foram alterados. Não há nenhum evento correspondente para que você saiba quando os dados foram empurrados a partir do dispositivo. O código a seguir demonstra como ouvir o evento DataChanged:

private void HandleEvents()
{
  ApplicationData.Current.DataChanged += Current_DataChanged;
}
void Current_DataChanged(ApplicationData sender, object args)
{
  // Update app with new settings
}

Se seu aplicativo está aproveitando o evento DataChanged, o método SignalDataChanged no ApplicationData é útil. Toda vez que você atualizar qualquer dados em roaming localmente, você pode chamar esse método e que ele acionará o evento DataChanged e permitirá quaisquer manipuladores de atualização que você precisa executar:

// Update settings locally and raise DataChanged event
roamingSettings.Values["favoriteColor"] = "Black";
ApplicationData.Current.SignalDataChanged();

É importante manter o controle da quantidade de dados que você está tentando realizar roaming. Cada dispositivo tem uma quantidade máxima de dados que pode sincronizar entre dispositivos, que atualmente é de 100 KB. O problema potencial é que se trata de uma abordagem de tudo ou nada. Se a quantidade total de dados que você está tentando sincronizar exceder o limite, então nada sincronizará entre os dispositivos. A classe ApplicationData contém uma propriedade RoamingStorageQuota que devolve o tamanho total dos dados permitidos de serem sincronizados em kilobytes. No entanto, o ApplicationData não contém qualquer mecanismo para determinar a quantidade atual de dados que você está usando, então por enquanto cabe a você manter o controle.

Novas versões do seu aplicativo poderiam significar configurações novas ou modificadas a partir de versões anteriores, bem como dados de versões anteriores que deixaram de ser necessários. Para resolver esse problema, o tempo de execução do Windows permite a versão de seus dados em roaming. Você encontrará a versão de dados em roaming atual para que o aplicativo esteja definido no ApplicationData.Current.Version. Esse número de versão é independente do número de versão do aplicativo e, por padrão, está definido para zero. O aplicativo sincronizará os dados que correspondem ao seu número de versão. Isso permite que você crie novas estruturas de dados sem medo de quebrar versões mais antigas.

Você pode mudar a versão do aplicativo através do método ApplicationData.SetVersionAsync. Esse método tem dois parâmetros, o novo número de versão e um ApplicationDataSetVersionHandler, para permitir que você grave qualquer código necessário para fazer alterações no aplicativo baseado na nova versão.

O manipulador contém um único parâmetro SetVersionRequest. Isso fornece a versão atual através da propriedade CurrentVersion, bem como a nova versão na propriedade DesiredVersion. Seu aplicativo pode usar estes dois valores para lidar com quaisquer migrações em uma abordagem iterativa. Ele também contém um GetDeferralMethod que permite que você mantenha o thread aberto até que você tenha a oportunidade de concluir a migração. Dessa forma, se você tiver quaisquer chamadas assíncronas, como arquivos de leitura ou gravação, você pode executar essas funções antes do processo de mudança de versão estar completo. A Figura 3 mostra como migrar para uma nova versão.

Figura 3 Atualizar versão dos dados em roaming

void SetVersionHandler(SetVersionRequest request)
{
  SetVersionDeferral deferral = request.GetDeferral();
  if (request.CurrentVersion < 1)
  {
    // Handle upgrade from 0 to 1
  }
  if (request.CurrentVersion < 2)
  {
    // Handle upgrade from 1 to 2
  }
  deferral.Complete();
}
async void SetVersion()
{
  var appData = ApplicationData.Current;
  if (appData.Version < 2)
  {
    await appData.SetVersionAsync(
      2, new ApplicationDataSetVersionHandler(SetVersionHandler));
  }
}

Compartilhar entre aplicativos Windows Store e Windows Phone Store

Agora que você já implementou as definições de roaming em ambos os aplicativos do Windows Store e Windows Phone Store, a próxima etapa lógica é para que os dois aplicativos da empresa sejam capazes de compartilhar os seus dados de roaming.

Tecnicamente falando, para que um aplicativo do Windows Phone Store e um aplicativo do Windows Store compartilhem dados em roaming, eles devem ter o mesmo pacote com o nome de família. Esse campo é gerado com base no nome do pacote. Portanto, os dois aplicativos devem ter o mesmo nome do pacote. Você pode localizar estes valores, associando os aplicativos com nomes em suas respectivas lojas.

A primeira etapa para o envio de um aplicativo em qualquer loja é atribuir um nome ao aplicativo. Você pode criar um novo nome ou associar o aplicativo com um nome existente. A lista de nomes existentes é uma combinação de nomes reservados para a loja que você está dentro e uma lista de aplicativos que você tem na outra loja. A seleção de um aplicativo na outra loja vinculará o seu aplicativo, lhe dando o mesmo nome e deixando os aplicativos compartilharem dados em roaming. Você pode ler mais sobre o que significa para vincular um aplicativo do Windows Store e Windows Phone Store em bit.ly/10Pl2Xi.

Pelo fato de as lojas ainda estarem separadas, a experiência de vincular seus aplicativos é um pouco diferente. Se você tiver um aplicativo Windows Store existente, você pode vincular um aplicativo do Windows Phone Store ao selecionar o aplicativo do Windows Store na seção de informações do aplicativo, conforme mostrado na Figura 4. Você também pode vincular um aplicativo Windows Store a um aplicativo Windows Phone Store existente na seção do nome do aplicativo, como mostrado na Figura 5.

Vincular um aplicativo do Windows Phone Store a um aplicativo do Windows Store
Figura 4 Vincular um aplicativo do Windows Phone Store a um aplicativo do Windows Store

Vincular um aplicativo do Windows Store a um aplicativo do Windows Phone Store
Figura 5 Vincular um aplicativo do Windows Store a um aplicativo do Windows Phone Store

Depois de ter criado e vinculado os aplicativos nas lojas, a última etapa é associar cada um dos seus aplicativos no Visual Studio para esses nomes. Clique com o botão direito do mouse na sua principal solução do Windows Store e Windows Phone Store e selecione Loja | Aplicativo associado com a Store. Em seguida, siga o assistente e selecione o nome correto. Isso atualizará seu Package.appxmanifest com as informações inseridas na loja.

Nesse ponto, seus aplicativos serão capazes de compartilhar dados de roaming. Lembre-se, é importante controlar o tamanho dos dados que você está em roaming. Se as cotas de armazenamento são diferentes em todas as plataformas, você precisará planejar para o menor dos dois com seu limite.

Depurar dados de roaming

Testar suas configurações de roaming é simples. Novamente, é uma situação de tudo ou nada. O seu roaming de dados é sincronizado entre os dispositivos, ou não é. Ao testar o processo de sincronização, bloqueia o dispositivo forçará o aplicativo para tentar sincronizar os dados. Se isso não acontecer, existe algumas coisas a considerar:

  • A causa mais comum de não sincronização de dados é que o aplicativo ultrapassou a cota de armazenamento de roaming. Se o tamanho total excede o limite, o aplicativo não tentará sincronizar seus dados de roaming.
  • Se estiver armazenando seus dados em arquivos, certifique-se de ter fechado todos os manipuladores de arquivos. Deixar os arquivos abertos manterá um bloqueio sobre eles e também impede a sincronização.

Conclusão

Usar dados de roaming em seus aplicativos fornece a seus usuários uma experiência consistente e sempre conectada. Compartilhar configurações, preferências e estado do aplicativo atual em um dispositivo e levá-lo para outro dispositivo permite que os usuários se sintam como se fosse o mesmo aplicativo, não importa o dispositivo. Adicionar a capacidade de compartilhar dados entre os aplicativos do Windows Store e Windows Phone amplifica essa experiência e abre um vasto leque de oportunidades.


Tony ChampionVice-Presidente da Microsoft, é o presidente da Champion DS e está ativo na comunidade como palestrante, blogger e autor. Ele mantém um blog em tonychampion.net. Entre em contato com ele em tony@tonychampion.net.

Agradecemos ao seguinte especialista técnico da Microsoft pela revisão deste artigo: Robert Green