Maio de 2016

Volume 31 - Número 5

Aplicativos da Plataforma Universal do Windows - Aplicativos Web Hospedados para o Enterprise

Por Tim Kulp | Maio de 2016

Desenvolvedores que trabalham em uma empresa estruturada sabem que nem sempre é fácil implementar novas tecnologias. Apresentar algo novo para a empresa como um projeto de aplicativo UWP (Plataforma Universal do Windows) pode representar um desafio quando você não tem equipes versadas (ou que confiam) em seu conhecimento de fornecer este tipo de aplicativo. Muitas empresas têm um significativo investimento em seus aplicativos Web da intranet e mas equipes que dão suporte a eles. HWAs (Aplicativos Web Hospedados) oferecem uma ponte para unir os aplicativos Web da intranet ou Windows Store para Empresas com pouco esforço.

Neste artigo, converterei um aplicativo Web da Intranet existente em um aplicativo UWP para a Windows Store e aprimorarei o aplicativo com funcionalidades nativas do Windows. Como mostrado na Figura 1, o aplicativo Web é um aplicativo de reconhecimento social chamado “Gotcha” que permite que funcionários da Contoso Corp. reconheçam seus colegas por seus atos de gentileza ou demonstrem seu apreço. O Gotcha serve para que os colegas celebrem uns aos outros e formem uma equipe mais forte e contente. Este aplicativo Web é um excelente candidato para a Windows Store, pois ele fornece uma integração fácil com contatos, compartilhamento e a câmera.

Aplicativo Web Gotcha
Figura 1 aplicativo Web Gotcha

Pontes e Aplicativos Web Hospedados para Empresas

Para desenvolvedores empresariais, as Pontes de UWP e HWAs fazem sentido porque eles podem manter suas ferramentas, processos e sistemas de implantação existentes em seus aplicativos. O conceito de erguer Pontes para habilitar que os desenvolvedores tragam seus aplicativos iOS, Android, Win32 e Web existentes para a UWP e a Windows Store de plataforma cruzada. A meta é possibilitar que os desenvolvedores tragam sua base de código existente para a UWP com a capacidade de expandir a experiência do usuário com funcionalidades específicas do Windows, como as conquistas do Xbox.

As pontes facilitam a tarefa de trazer código para a UWP, porém os desenvolvedores empresariais enfrentam outros desafios que podem dificultar a conversão do seu código. Os desenvolvedores de uma corporação podem enfrentar restrições quanto ao editores de código disponíveis ou quanto aos locais em que o código pode ser implantado com base na confidencialidade das informações contidas no aplicativo. O real valor das Pontes UWP para a empresa não é sua facilidade em converter aplicativos, mas sim o valor agregado da capacidade de manter as ferramentas, práticas e gerenciamento de alterações do desenvolvimento de software existentes da empresa para fornecer aplicativos UWP por meio da Windows Store.

Como um exemplo disso, HWAs (chamados de “Project Westminster”) possibilitam que os desenvolvedores insiram aplicativos Web em um aplicativo UWP. Depois que o aplicativo UWP é criado para usar o conteúdo HWA, os desenvolvedores podem usar suas práticas existentes para manter o aplicativo Web, que atualizará automaticamente a experiência do aplicativo Web do aplicativo UWP. Usando a Ponte HWA, os desenvolvedores podem se concentrar em seu aplicativo Web e incluir funcionalidades específicas à UWP por meio da detecção de recursos. Trabalhar com uma intranet existente é um excelente uso de caso para Pontes UWP, mas os desenvolvedores fora de empresas também aproveitar HWAs para levar seus aplicativos Web para a Windows Store. Qualquer site da Web pode se tornar um HWA desde que o site passe pelo processo de certificação da Windows Store.

As noções básicas de HWAs são abordadas na postagem de blog de Kiril Seksenov, “Project Westminster in a Nutshell” (“Project Westminster em resumo”) (bit.ly/1PTxxW4). Recomendo ler esta postagem para aprofundar seu conhecimento das ideias por trás de HWAs.

Iniciando um projeto HWA Web

Para iniciar a conversão do aplicativo Web Gotcha para HWA, eu criei um novo aplicativo UWP JavaScript no Visual Studio. Depois de ter criado o aplicativo, abri o manifesto do pacote e definir a página inicial do aplicativo como a URL do aplicativo Web, como mostrado na Figura 2. Neste caso, o aplicativo Web Gotcha é executado do localhost:6107. Com a página inicial definida, o aplicativo exibirá a página da Web no endereço especificado em vez do conteúdo local do aplicativo.

Definir a página inicial no manifesto do pacote
Figura 2 definir a página inicial no manifesto do pacote

Por fim, defini os URIs do conteúdo no manifesto do pacote. Esses URIs dirão ao aplicativo quais páginas podem acessar as bibliotecas do WinRT (Windows Runtime) e qual nível de acesso os URIs podem ter. Já ouvi dizer que isso é como definir onde o aplicativo para e a Internet começa, e acho que essa é uma ótima perspectiva de como usar os URIs de conteúdo. No aplicativo Web Gotcha existente, há distinções claras entre o que o aplicativo faz e o que ele pode usar a Internet para fazer. Por exemplo, no Gotcha, os usuários podem compartilhar reconhecimento para redes sociais como o LinkedIn. O site da Web do LinkedIn não faz parte do aplicativo UWP do Gotcha; ele faz parte da Internet. Eu incluiria apenas URIs que são usados diretamente dentro do aplicativo e aqueles que precisam de acesso às APIs da UWP.

Usar os URIs de conteúdo permite ao desenvolvedor proteger os usuários do aplicativo impedindo o acesso de URIs não registrados às bibliotecas de WinRT. Para cada URI, especifique o nível de acesso às bibliotecas WinRT necessário:

  • Tudo: O código JavaScript em execução no aplicativo Web (neste caso o Gotcha) pode acessar toda e qualquer API da UWP definida por meio dos Recursos do Aplicativo.
  • Permitir apenas para Web: O código JavaScript em execução no aplicativo Web pode executar componentes WinRT personalizados incluídos no pacote do aplicativo, mas não consegue acessar todas as APIs da UWP.
  • Nenhum: O código JavaScript em execução no aplicativo Web não pode acessar as APIs UWP locais (esta é a configuração padrão).

Ao definir URIs de conteúdo, lembre-se que este é um componente-chave da segurança do aplicativo para o usuário do aplicativo UWP. Forneça o mínimo de permissões necessárias para um URI para as funções necessárias do aplicativo UWP, conforme mostrado na Figura 3. Tente evitar definir o Acesso a WinRT de URI da raiz para Tudo se não for realmente necessário dentro do aplicativo.

Definir os URIs de conteúdo para o privilégio mínimo necessário para executar o aplicativo
Figura 3 definir os URIs de conteúdo para o privilégio mínimo necessário para executar o aplicativo

Não recomendo remover o conteúdo existente que vem com o processo de criação de projeto (como as pastas .css, .js e WinJS). Este conteúdo existente concede aos desenvolvedores uma excelente estrutura que pode ser usada para adicionar conteúdo local ao HWA Web. Posteriormente neste artigo, usarei essas pastas para conteúdo local para criar algumas funcionalidades que complementam a experiência offline do HWA Web.

Com o manifesto do pacote configurado, execute o aplicativo UWP. Como mostrado na Figura 4, o aplicativo Web aparecerá agora em uma janela de aplicativo como qualquer outro aplicativo UWP.

Aplicativo Gotcha pronto para a Windows Store
Figura 4 aplicativo Gotcha pronto para a Windows Store

Depurar um Aplicativo Web Hospedado

HWAs têm uma experiência de depuração ligeiramente diferente de uma aplicativo puramente nativo. Com o aplicativo UWP aberto, pressione F12. Isso mostrará as Ferramentas de Desenvolvedor F12 para o aplicativo UWP. Por meio das Ferramentas de Desenvolvedor F12, posso depurar, criar perfil e testar o aplicativo Web da mesma forma que em um navegador. Embora todas as funcionalidades das Ferramentas de Desenvolvedor F12 sejam úteis para desenvolvedores de HWA, os componentes que eu acho mais úteis são a depuração fora do Visual Studio e a atividade de rede de criação de perfil. Uso esses recursos para mergulhar nos comportamentos de um aplicativo específico e compreender os problemas (como cache) que estão proporcionando uma experiência inesperada no aplicativo.

Da mesma forma que usar F12 em um navegador, os desenvolvedores podem alterar o DOM e testar diferentes experiências de interface do usuário com base no tamanho da tela ou da janela. Isso também pode ser usado para explorar mudanças de layout de um aplicativo Web com base nas necessidades de resposta do aplicativo. Por exemplo, ajustar o aplicativo UWP para exibir uma barra lateral deverá refluir o aplicativo para apresentar uma ótima experiência. Se o redimensionamento não refluir o aplicativo, as Ferramentas de Desenvolvedor F12 poderão ser usadas para determinar por que isso não ocorreu e conduzir experimentos com o DOM para ver o que é necessário para atingir o refluxo desejado.

Adicionando funcionalidades ao seu aplicativo UWP

Com o HWA básico pronto, mergulharei nas funcionalidades do aplicativo Web para habilitar algumas APIs de UWP e expandir a experiência do usuário. Aplicativos Web da Intranet podem ter algumas limitações que HWAs não têm. Usando APIs de UWP, um HWA pode ter acesso a muitas funcionalidades locais do dispositivo UWP (como câmera, localização e outros sensores). Para começar, pense sobre os casos de uso que estão impulsionando a implementação do aplicativo Web para um aplicativo Web hospedado. No aplicativo Gotcha, desejo que os usuários possam selecionar seus Contatos para conceder um prêmio em vez de apenas digitar o nome da pessoa e anexar uma imagem ao reconhecimento.

Para começar, crio um arquivo de código GotchaNative.js remoto no aplicativo Web (o arquivo de script GotchaNative.js ficará no servidor de aplicativos Web remoto) que detectará os namespaces da API nativa e executará o código para disparar nossos usos de caso nativos. Adicione o seguinte código ao arquivo de código NativeGotcha.js:

var GotchaNative = (function () {
  if (typeof Windows != 'undefined') {
    // Add find contact here
    // Add capture photo here
  }});

Esse código cria o objeto GotchaNative, que conterá todas as funcionalidades das APIs de UWP. Centralizar essas APIs permite que um único arquivo contendo funcionalidade da API de UWP adicional seja incluído nas páginas. Isolo este arquivo para que eu possa declarar explicitamente os URIs de conteúdo que incluem este arquivo específico como URIs com acesso as APIs de UWP necessárias. Desta forma, posso implementar o conceito de segurança de privilégio mínimo e conceder permissões apenas aos URIs que precisarem de acesso às APIs de UWP.

Outro benefício de isolar este arquivo é preparar-se também para outras plataformas nativas. Explorarei isso posteriormente neste arquivo, porém, por hora, considere este arquivo como a página inicial para todas as funcionalidades nativas que serão incluídas no aplicativo Web Gotcha.

Estendendo a funcionalidade existente

Agora que criei o objeto GotchaNative, posso adicionar a funcionalidade específica para conectar o HWO às APIs de UWP. Para o primeiro caso de uso, o aplicativo Web Gotcha permite aos usuários inserirem uma pessoa para reconhecimento. Na UWP, os usuários têm o aplicativo Pessoas que armazena os contatos, sendo muito mais fácil para o usuário selecionar em vez de digitar o nome da pessoa. Substitua o comentário “Adicione como encontrar o contato aqui” no arquivo de código GotchaNative.js pelo seguinte:

this.FindContact = function () {
  var picker = new Windows.ApplicationModel.Contacts.ContactPicker();
  picker.desiredFieldsWithContactFieldType.append(
    Windows.ApplicationModel.Contacts.ContactFieldType.email);
  return picker.pickContactAsync();
}

Este código é uma conexão básica com a API ContactPicker para selecionar um contato de uma lista de contatos. Uma lista de APIs de UWP que podem ser ajustadas a HWAs Web pode ser encontrada em rjs.azureWebsites.net. Este site da Web lista algumas das APIs mais populares com código pronto para copiar e colar para ajudar a criar um projeto HWA Web.

A funcionalidade de adicionar uma pessoa pode ser encontrada no Modelo de Exibição de Pessoa para o site da Web do Gotcha. Adicione o código na Figura 5 ao Modelo de Exibição de Pessoa.

Figura 5 Código a ser adicionado ao Modelo de Exibição de Pessoa

if (Windows != undefined) {
  var nativeGotcha = new NativeGotcha();
  nativeGotcha.FindContact().done(function (contact) {
    if (contact !== null) {
      $("#txtWho").val(contact.displayName);
    } else {
      // Write out no contact selected
    }
  });
}
else {
  $('#add-person').on('shown.bs.modal', function () {
    $("#txtWho").focus();
}

O código na Figura 5 usa o método FindContact se o objeto do Windows estiver definido, pois o script será executado como um HWA. Se o objeto do Windows não for definido, o aplicativo Web continuará a usar a janela modal de inicialização para coletar informações sobre a pessoa a ser reconhecida. Esse código permite que o aplicativo Web use uma abordagem para inserir uma pessoa para reconhecimento enquanto a UWP pode aproveitar uma experiência diferente, mais adequada ao usuário.

Adição de nova funcionalidade

Às vezes, habilitar APIs de UWP permitirá novas funcionalidades que normalmente não existiriam no aplicativo Web. No HWA do Gotcha, quero permitir que os usuários tirem fotos e enviem tais fotos como reconhecimento para outros usuários do Gotcha. Essa funcionalidade seria nova no aplicativo e não existiria no aplicativo Web. Ao criar um HWA, considere as oportunidades que as APIs de UWP abrem para o aplicativo.

Para começar a implementar esta nova funcionalidade, primeiro substituo o comentário “Adicionar captura de foto” pelo código a seguir no arquivo de código GotchaNative.js:

this.CapturePicture = function () {
  var captureUI = new Windows.Media.Capture.CameraCaptureUI();
  captureUI.photoSettings.format =
    Windows.Media.Capture.CameraCaptureUIPhotoFormat.png;
  return captureUI.captureFileAsync(
    Windows.Media.Capture.CameraCaptureUIMode.photo);
}

Neste código, abro e capturo a interface do usuário, permitindo que o usuário tire uma foto e envie a foto de volta para o chamador. Este novo recurso precisa ser habilitado no aplicativo Web se o objeto do Windows estiver definido. Usando a detecção de recurso como fiz no Modelo de Exibição de Pessoa, adiciono o código na Figura 6 ao Modelo de Exibição de Página Inicial, que é onde fica o código para adicionar o reconhecimento.

Figura 6 Código de detecção de recurso para ser adicionado ao Modelo de Exibição de Página Inicial

$('#give-modal').on('shown.bs.modal', function () {
  if (typeof Windows != 'undefined') {
    var gotchaNative = new NativeGotcha();
    $("#btnCamera").click(function () {
      gotchaNative.CapturePicture().then(function (capturedItem) {
        // Do something with capturedItem;
      });
    }).show();
  }
  else {
    $("#btnCamera").hide();
  }
})

No código na Figura 6, oculto btnCamera se o objeto do Windows for indefinido. Se o objeto do Windows não for indefinido, configuro o evento de clique para disparar a função CapturePicture. Para resumir, deixei um comentário sobre o que fazer com a imagem. Ao habilitar a câmera, preciso ter em mente que este HWA ainda é um aplicativo UWP e precisa de funcionalidade de Webcam habilitada para o aplicativo, o que pode ser feito por meio do manifesto do pacote.

Aplicativos Web empresariais podem ser convertidos em para aproveitar as APIs de UWP da Windows Store. Usar aplicativos Web existentes facilita o acúmulo de aplicativos UWP na Windows Store, mas HWAs supõem que há uma conexão com a Internet. Em seguida, mostrarei como garantir que um aplicativo funcione mesmo sem acesso à Internet.

Conectando offline

O aplicativo UWP pode ter arquivos locais para fornecer uma experiência offline ou local. Usar conteúdo local permite desconectar parte das chamadas à API de UWP do aplicativo Web hospedado. Como na detecção de recurso que já foi realizada, o vínculo a um conteúdo local pode ser feito por meio de links de ativação. Para o Gotcha, adicionarei um recurso de mapeamento que usará os controle de mapeamento local.

No HWA, posso usar o mesmo recurso de detecção que foi usada anteriormente no Modelo de Exibição de Página Inicial. Usar o esquema de URI correto permitirá que o HWA alterne entre os conteúdos Web e local. Na página inicial, adiciono o seguinte link:

<a href="ms-appx:///default.html" id="lnkMap">
  <span class="glyphicon glyphicon-map-marker">&nbsp;</span> Show Map
</a>

O link se conecta ao esquema ms-appx:///, que permite que o aplicativo se conecte ao conteúdo local dentro do pacote de aplicativos. Ao trabalhar dentro do esquema ms-appx, o aplicativo pode conectar às APIs de UWP necessárias. Isso é semelhante a usar os URIs de conteúdo para declarar qual nível de acesso uma página tem para acessar as APIs. Usar ms-appx é como marcar um URI como Tudo. Neste caso, a página default.html tem acesso às APIs de UWP. Quando o link aparecer dentro do HWA, os usuários podem clicar nele para trabalhar dentro do pacote do aplicativo.

Para desenvolvedores empresariais, este recurso permite isolar casos de uso específicos à UWP e não necessariamente conectados ao aplicativo Web. Conectar ao conteúdo do pacote também pode permitir evitar fornecer acesso às APIs de UWP para o aplicativo Web e manter todo esse acesso dentro do pacote.

E quanto a mais de uma Loja?

Dependendo da empresa, pode existir um ambiente Traga seu próprio dispositivo. Isso significa que uma empresa poderia já ter aplicativos existentes voltados para dispositivos iOS e Android. Aplicativos Android e iOS têm conceitos similares a HWAs chamados controle WebView. O WebView permite que os desenvolvedores forneçam uma janela dentro do aplicativo para um aplicativo Web existente e interagir com este aplicativo como se ele fizesse parte do aplicativo nativo (parece familiar?). HWAs podem ser compilados para funcionar bem com outros, adequando a funcionalidade de um aplicativo Web existente à plataforma que fornece o aplicativo Web. Em seguida, atualizarei o GotchaNative.js para dar suporte a Android e mostrar como o código de HWA poderia existir lado a lado com JavaScript voltado para outras plataformas.

Antes, configurei o GotchaNative.js, que serve para conter todo o código nativo no aplicativo. O ViewModels processará a saída desses métodos nativos. Usar APIs em qualquer plataforma é semelhante aos HWAs: Primeiro, o aplicativo deve determinar se as APIs nativas estão disponíveis e deve então chamar a API apropriada. Para começar a atualizar o GotchaNative.js, adicionarei uma propriedade que indica que a plataforma nativa (se houver) foi reconhecida. Para os exemplos a seguir, estou supondo que o aplicativo Android está usando um WebView que declara “Android” como o namespace do script local:

this.Platform = function () {
  if (Windows != 'undefined')
    return "Windows";
  else if (Android != 'undefined')
    return "Android";
  else
    return "Web";
}

Esta função permite que meu código determine com qual plataforma ele trabalhará para que eu possa adequar o código e a resposta à plataforma. Daqui em diante, cada método dentro do GotchaNative.js pode verificar a plataforma para saber como proceder, como mostrado na Figura 7.

Figura 7 Métodos do GotchaNative.js verificando a plataforma

this.CapturePicture = function () {
  switch (this.Platform()) {
    case "Windows":
      var captureUI = new Windows.Media.Capture.CameraCaptureUI();
      captureUI.photoSettings.format =
        Windows.Media.Capture.CameraCaptureUIPhotoFormat.png;
      return captureUI.captureFileAsync(
        Windows.Media.Capture.CameraCaptureUIMode.photo);
      break;
    case "Android":
      Android.CaptureFile(); // Calls Android code in Native app
      break;
    default:
      return null;
      break;
}

Agora, em ViewModels, o código será atualizado para usar a detecção de plataforma para saber o que fazer com a saída dos métodos do GotchaNative. Veja a seguir uma atualização do evento do botão de câmera do HomeViewModel:

$("#btnCamera").click(function () {
  switch (gotchaNative.Platform()) {
    case "Windows":
      gotchaNative.CapturePicture().then(function (capturedItem) {
        // Do something with capturedItem;
      });
      break;
    case "Android":
      // Handle Android output
      break;
  }
}).show();

Agora, como o aplicativo dá suporte a mais plataformas, possuo um local único no meu código para aumentar as funcionalidades para todas as plataformas. Se um novo sistema operacional popular for lançado amanhã, a equipe de desenvolvimento poderia adaptar o código para a nova plataforma.

Conclusão

Desenvolvedores empresariais enfrentam diversos desafios em seu trabalho. Processos e ferramentas padronizados podem ser vistos como uma barreira para implementar novas tecnologias como aplicativos UWP. Usando as Pontes UWP, os desenvolvedores empresariais podem trazer seus aplicativos Web da intranet ou externos existentes para a Windows Store (pública ou Windows Store para Empresas). Pontes para HWAs podem transformar um aplicativo Web em um aplicativo UWP de plataforma cruzada, aproveitando as APIs de UWP para expandir a experiência do usuário.

Neste artigo, explorei como converter um aplicativo Web existente em HWA adicionando funcionalidades específicas de aplicativo UWP como acesso a câmeras e contatos. Usando o esquema ms-appx, mostrei como alternar seu aplicativo Web hospedado para conteúdo local dentro do pacote do aplicativo. Por fim, mostrei, com certo planejamento, como os HWAs podem ser criados com muitas plataformas diferentes, permitindo à empresa acompanhar o mundo em constante expansão dos dispositivos móveis. Usando essas técnicas, os HWAs podem aproveitar os investimentos existentes em aplicativos Web, ajudando empresas a ingressarem no ecossistema da Windows Store.


Tim Kulpé um arquiteto técnico sênior que vive em Baltimore, Md. Ele é desenvolvedor de Web, dispositivos móveis e de UWP, assim como escritor, pintor, pai e “aspirante a cientista louco”. Encontre ele no Twitter: @seccode ou no LinkedIn: linkedin.com/in/timkulp.

Agradecemos ao seguinte especialista técnico da Microsoft pela revisão deste artigo: John-David Dalton e Kiril Seksenov