Compressão GZip no Windows Phone

Os servidores modernos de internet permitem comprimir os dados por eles devolvidos utilizando GZip, um algoritmo standard para compressão de dados.

A compressão de dados nas comunicações é especialmente importante para os dispositivos móveis, em que normalmente o acesso à internet feito através da rede móvel é limitado (e caro!)

Se os dados foram comprimidos antes de serem devolvidos ao cliente, vamos gastar menos bytes no envio, e como tal estamos a ganhar tanto em tráfego como em velocidade: os ganhos da compressão com GZip podem ir de 50% a 80%, de acordo com algumas estatísticas online.

Apesar de grande parte dos dispositivos de acesso à internet estar preparado para receber dados comprimidos neste formato, o Windows Phone aparentemente não está, pelo menos no que toca ao HttpWebRequest, o objecto utilizado por base para comunicação em HTTP na .NET Framework!

Opção 1: a minha aplicação usa HttpWebRequest ou WebClient

Uma solução para esta situação é utilizar o GZipWebClient do Morten Nielsen, disponível por NuGet e em código aberto no GitHub.

Depois de juntarem o componente ao vosso projecto, juntem estas duas linhas no início da aplicação:

WebRequest.RegisterPrefix("http://", SharpGIS.WebRequestCreator.GZip);
WebRequest.RegisterPrefix("https://", SharpGIS.WebRequestCreator.GZip);

Feito isto, sempre que criarem uma nova instância do HttpWebRequest ou do WebClient, este estará pronto para funcionar com GZip!

Opção 2: A minha aplicação usa RestSharp

Bem, no caso do RestSharp, desde a versão 102.6 que tudo o que tem a fazer é, antes de executarem o vosso pedido, juntar o Http Header que indica que aceitam dados comprimidos com GZip na resposta!

var client = new RestClient("http://some.url/service");

client.AddDefaultHeader("Accept-Encoding", "gzip");

Como podem aqui ver, o truque está na ultima linha, em que damos indicação ao servidor que o cliente vai aceitar dados comprimidos com GZip.

O RestSharp ao receber a resposta vai validar o formato dos dados, e se estes foram comprimidos encarregar-se-á de os descomprimir!

Simples e eficáz! :)

Nota: Dado que a alteração para suporte de GZip no RestSharp foi incluída por mim, agradeço que se detectarem algum problema me façam chegar essa informação! ;)

Performance das Aplicações de Windows Phone

Desenvolver para Windows Phone ou para qualquer outro dispositivo móvel não é o mesmo que desenvolver para o desktop ou mesmo para a web!

São várias as preocupações que devemos ter, como a baixa capacidade de processamento, a memória e o espaço de storage limitados, o consumo de energia, etc.

No caso do Windows Phone, existe uma série de considerações que se deve ter em conta, e que se seguidas à risca, permitem melhorar (e muito) a performance das aplicações!

Imagens

Sempre que possível, utilizar imagens em formato JPEG em vez de PNG. É certo que os ficheiros JPEG tem perda de qualidade e que não suportam transparência, mas sempre que estes dois pontos não forem impeditivos (por exemplo, em fotos ou fundos da aplicação), este é o formato preferencial dado que a sua descodificação e leitura é em geral mais rápida.

Outra questão nas imagens é relativamente ao seu carregamento fora do thread da interface, algo que já anteriormente referi neste artigo.

Com o Expression Design é possível criar imagens vectoriais que são elementos em formato XAML; mais uma vez, sempre que possível, prefiram guardar e usar essas imagens em formato estático em vez de usarem o XAML!

Recursos

Os recursos que adicionados à aplicação devem ter a propriedade Build Action com o valor Content e não Resource. Isto porque o Windows Phone está optimizado para acesso a ficheiros e streams de rede, mas não de memória. Se assim fizerem os recursos serão incluídos no ficheiro .XAP em vez de serem compilados directamente na assembly binária da aplicação.

Bitmap Caching

Os elementos visuais em que for manipulada a propriedade UIElement.Opacity podem sofrer de um melhoramento de performance se colocarem na propriedade UIElement.CacheMode o valor BitmapCache; o que isto vai garantir é que o sistema operativo vai guardar uma imagem do estado da composição tal como ela está com cada valor alterado da opacidade, e assim poderá recorrer a ela sem necessidade de fazer nova renderização.

ProgressBar

Sempre que tenham operações que vão demorar algum tempo (por exemplo, aceder à internet), recorram a uma barra de progresso na vossa aplicação. Apesar do Windows Phone incluir um controlo ProgressBar, este não é adequado dado que a sua animação é feita no thread da interface, bloqueando a mesma; a alternativa é utilizarem o PerformanceProgressBar que podem encontrar no Silverlight for Windows Phone Toolkit.

Outra alternativa é recorrer ao ProgressIndicator no SystemTray do sistema.

Web

Tomem em atenção que ao utilizar o WebClient, este devolve o resultado no thread de composição da interface, pelo que qualquer tratamento da informação poderá bloquear a mesma!

Sempre que possível, utilizem o HttpWebRequest em vez do WebClient, dado que o retorno é feito num thread separado e que não irá bloquear a interface.

Bottom line…

Estas são as considerações que considerei mais importantes, mas existem outras que estão registadas neste artigo no MSDN.

Basicamente, a mensagem a passar é de que pensem sempre duas vezes antes de começarem a escrever código para a vossa aplicação! :)

Alinhamento de items dentro de uma ListBox

Ao desenvolver diariamente para Windows Phone por vezes deparo-me com situações em que nem tudo o que parece, realmente o é… esta é uma dessas situações!

Cenário inicial: numa PhoneApplicationPage vazia, adicionamos o seguinte bloco de XAML ao conteúdo da Grid ContentPanel:

<ListBox ItemsSource="{Binding Items}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <TextBlock Text="{Binding}" Style="{StaticResource PhoneTextTitle2Style}" />
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Como podem aqui ver, estamos a criar uma ListBox com um template muito simples (para cada item, apresentar um TextBlock usando o próprio item como texto).

Do lado do código temos uma propriedade Items que tem apenas e só 3 items e que vão servir para alimentar a propriedades ItemsSource da nossa ListBox.

Até aqui tudo bem, ao executar a aplicação o resultado deverá ser este:

Digamos que agora pretendemos alinhar o texto de cada item à direita; normalmente, a seguinte alteração seria suficiente:

<TextBlock Text="{Binding}" HorizontalAlignment="Right" Style="{StaticResource PhoneTextTitle2Style}" />

Ao executar novamente a aplicação, poderemos ver que o resultado se mantém inalterado!

Nesta altura, começamos a testar as propriedades da própria ListBox, ao ponto de fazer algo deste tipo:

<ListBox HorizontalContentAlignment="Right">

E mais uma vez, ao executar poderemos reparar que nada mudou!!!

O que se passa é que cada item da ListBox é instanciado dentro de um ListBoxItem, e este controlo ignora por completo a propriedade HorizontalContentAlignment colocada na própria ListBox.

Para resolver este problema, temos que definir a propriedade ListBox.ItemContainerStyle e ai sim colocar o ListBoxItem.HorizontalAlignment pretendido.

O código corrigido ficará estão da seguinte forma:

<ListBox ItemsSource="{Binding Items}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="HorizontalAlignment" Value="Right"/>
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <TextBlock Text="{Binding}" Style="{StaticResource PhoneTextTitle2Style}" />
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

E aqui temos o resultado final:

Pessoalmente, coloco sempre o ListBoxItem.HorizontalAlignment com o valor HorizontalAlignment.Stretch, e depois controlo o alinhamento do item propriamente dito dentro do template; com esta segunda abordagem tenho a garantia de que o item dispõe realmente da largura total da ListBox para apresentar resultados!

Amazon Web Services SDK for Windows Phone

A Microsoft apresentou ontem a primeira versão Beta do Amazon Web Services SDK for Windows Phone!

O SDK contém uma série de componentes que vem facilitar o desenvolvimento de aplicações para Windows Phone que comuniquem com alguns dos serviços prestados pela Amazon Web Services, como por exemplo o S3, o SimpleDB, e o SQS Cloud Services.

Para facilitar a sua utilização, a Microsoft disponibilizou ainda um artigo “Getting Started” com uma série de tutorais.

Este SDK está disponível em código aberto no GitHub sob licença Apache 2.0.

App Me Up

 

Depois do estrondoso sucesso do Windows Phone App Code Camp em Dezembro passado, a Microsoft apresenta mais uma iniciativa de promoção ao desenvolvimento para Windows Phone: App Me Up!

Numa página muito completa, reuniu toda a informação necessária para ajudar aqueles que querem desenvolver aplicações para Windows Phone, independentemente de serem iniciados ou profissionais: o software necessário, a documentação e vários tutoriais e vídeos de aprendizagem, a informação relativa à publicação no Marketplace (até mesmo informação para quem pretender publicar as suas aplicações, mas que ainda não tem conta no AppHub), e a projecção das aplicações feitas em Portugal! :)

Mas há mais: podem ainda encontrar o programa App VIP, em que serão oferecidos equipamentos Nokia Lumia para as melhores aplicações, e para quem tiver pelo menos 5 aplicações publicadas!!!

Então? Estás à espera de quê? :D

Cimbalino Windows Phone Toolkit v1.2

Ultimamente não tenho tido a oportunidade de actualizar o blog com a mesma frequência que vinha a fazer, e a principal razão foi mesmo de me ter dedicado a melhorar o Cimbalino Windows Phone Toolkit, culminando hoje esses melhoramentos com o lançamento da versão 1.2!

As alterações são (mesmo) muitas, especialmente no número de serviços agora suportados e nos  extension methods, mas para além disso foram adicionados três novos projectos:

Os projectos DeviceInfo e o UserInfo expõe serviços que permitem aceder ao DeviceExtendedProperties e UserExtendedProperties respectivamente; já o Location expõe um serviço que permite utilizar a capacidades de geolocalização presentes no sistema operativo!

Os próximos artigos do blog serão certamente sobre as novidades desta versão, bem como exemplos e novas samples!

O código está disponível no sítio do costume, bem como os pacotes de NuGet! ;)

Rescaldo do Windows Phone App Code Camp

3 dias no Palmela Village Golf Resort, cerca de 60 pessoas de todas as idades (estudantes, programadores profissionais e amadores, designers, etc.), 30 projectos de aplicações Windows Phone, vários equipamentos Windows Phone para usarem (e abusarem!), algumas sessões técnicas à mistura e o acompanhamento meu e do Nuno Silva nos seus projectos…

Resumindo numa só palavra: Sucesso!!!

Pessoalmente, foi o evento mais desgastante e simultaneamente mais gratificante que tive o prazer de colaborar!!!

No final, o espírito de missão cumprida e saber que existem agora mais 60 pessoas impressionadas com a facilidade que é desenvolver para Windows Phone, e o enorme potencial disso! :)

Ficam ainda os parabéns à organização do Nuno Silva, do André Malico e do Miguel Vicente, e a esperança de serem realizados novos Windows Phone App Code Camp num futuro próximo! ;)

Nokia Lumia 800 skin

O emulador do Windows Phone apresenta uma skin muito básica de um dispositivo genérico, mas pela internet podemos encontrar várias skins alternativas, nomeadamente a do Nokia Lumia 710 disponibilizada pela Telerik, e a do Samsung Focus pelo Jeff Wilcox.

Nesse sentido, procurei por uma do Nokia Lumia 800, mas as (várias!) que encontrei tinham todas baixa qualidade, sendo resultado de imagens de fraca definição…

Nesse sentido, tratei de criar a minha própria skin do Nokia Lumia 800 para o emulador do Windows Phone, e o resultado pode ser visto ao lado! :)

Esta é uma skin com imagens de alta resolução, com os seguintes botões totalmente funcionais:

  • Back/App switcher
  • Start/Speech
  • Search
  • Volume Up
  • Volume Down
  • Camera

Nota: apesar de o botão “Power” estar também presente e fazer a devida animação(!), este parece não funcionar com o Windows Phone!

Podem fazer download da skin aqui! ;)

Candidaturas ao WP App Code Camp terminam dentro de 2 dias…

… por isso não percam tempo e tratem de enviar já a vossa! :D

Relembro: 3 dias (de 16 a 18 de Dezembro), no Palmela Village Golf Resort com tudo pago(!), para terem todo o tempo e apoio para concretizarem aquela ideia que tiveram para uma aplicação no Windows Phone!

Para quem não viu anteriormente o anúncio do evento, aqui tem a informação sobre o registo:

O registo no WP7 App Code Camp é gratuito (yup!), e porque as vagas são muito, muito limitadas, para assegurar o teu lugar deverás enviar um e-mail até 9 de Dezembro para t-andma@microsoft.com e provar que tu, ou a tua equipa, merecem uma vaga. Como? Basta que no e-mail incluas as seguintes informações:

  • dados pessoais individuais ou da tua equipa (até 2 elementos) – nome, telefone, e-mail;
  • numa frase, explicar qual a ideia de app que vais/vão desenvolver no Camp;
  • numa frase, porque deves/devem ser o(s) escolhido(s)? 

Iremos, então, notificar quais os seleccionados até ao dia 12 de Dezembro!

Posso desde já confirmar que em resposta a um convite que me foi feito pela Microsoft, estarei presente no evento para juntamente com o Nuno Silva dar apoio a todos os presentes na criação das suas aplicações! :)

Cimbalino Windows Phone Toolkit: ApplicationBarBehavior

ApplicationBar disponível para utilização no desenvolvimento de aplicações para Windows Phone foi desde o primeiro dia uma grande dor de cabeça para os programadores, pelo simples facto de este controlo não ser um FrameworkElement.

Quer isto dizer que não é possível aplicar Styles ou Templates à ApplicationBar, e mais importante ainda, não é possível fazer Binding das suas propriedades, algo que complica e muito quem quer utilizar uma arquitectura baseada em MVVM!

É certo que a arquitectura MVVM não é completamente fechada e limitada, e como tal existem alternativas para ultrapassar este problema (por exemplo, esta e esta)!

No meu caso, de forma a poder utilizar a Application Bar nas minhas aplicações de uma forma mais “MVVM’ed”, criei o ApplicationBarBehavior que podem encontrar no Cimbalino Windows Phone Toolkit!

Este Behavior, quando aplicado no elemento LayoutRoot de uma PhoneApplicationPage, permite criar e manter uma Application Bar com propriedades Bindable de forma a manter uma arquitectura MVVM mais consistente.

Para melhor explicar, nada como um exemplo:

<!-- Restante código -->

<Grid x:Name="LayoutRoot" Background="Transparent">
    <i:Interaction.Behaviors>
        <cimbalino:ApplicationBarBehavior>
            <cimbalino:ApplicationBarIconButton Command="{Binding AddItemCommand, Mode=OneTime}" IconUri="/Images/appbar.add.rest.png" Text="add" IsVisible="{Binding IsSelectionDisabled}" />
            <cimbalino:ApplicationBarIconButton Command="{Binding EnableSelectionCommand, Mode=OneTime}" IconUri="/Images/appbar.manage.rest.png" Text="select" IsVisible="{Binding IsSelectionDisabled}" />
            <cimbalino:ApplicationBarIconButton Command="{Binding DeleteItemsCommand, Mode=OneTime}" CommandParameter="{Binding SelectedItems, ElementName=ItemsMultiselectList}" IconUri="/Images/appbar.delete.rest.png" Text="delete" IsVisible="{Binding IsSelectionEnabled}" />
        </cimbalino:ApplicationBarBehavior>
    </i:Interaction.Behaviors>

    <!-- Restante código -->

</Grid>

<!-- Restante código -->

No excerto de código acima podemos ver o ApplicationBarBehavior com uma série de controlos ApplicationBarIconButton (tal como seria feito normalmente), e rapidamente nos apercebemos de algumas novas propriedades como o Command, CommandParameter, e IsVisible (algo que não encontramos de base na ApplicationBar do Windows Phone); apesar de neste exemplo isso não ser visível, também as propriedades Text e IconUri são Bindable!

Para melhor explorarem o ApplicationBarBehavior, proponho que façam download do código completo do Cimbalino Windows Phone Toolkit do GitHub, e depois executem a solução BindableApplicationBar que encontram na pasta “samples”.