Estendendo uma aplicação criada no App Studio da Microsoft

Este artigo tem como objetivo explicar como estender uma aplicação que foi inicialmente gerada pelo App Studio da Microsoft.

Num outro artigo, Criando aplicações Windows Phone 8.1 e Windows 8.1 usando o App Studio da Microsoft, foi apresentado o serviço da App Studio, os vários tipos de templates para criar aplicações, as várias fases do desenvolvimento da aplicação no serviço e por fim a geração dos pacotes e a obtenção do código.

Microsoft App Studio

Atualmente o App Studio não tem suporte para feed do Twitter, no entanto é possível estender a aplicação para suportar esta funcionalidade, ora vejamos como o podemos fazer.

Na aplicação do Contoso Ltd, criada a partir de um template fornecido pelo App Studio temos várias secções:

  • About us é uma secção do tipo HTML
  • Catalog é uma secção do tipo coleção dinâmica
  • Team é uma secção do tipo coleção dinâmica
  • News é uma secção do tipo Bing
  • Contact us é uma secção do tipo Menu, que contém ações de menus.

App Studio: Secções da Aplicação

Para adicionar o feed do Twitter, iremos ter uma nova sessão chamada Twitter. Esta secção pode ser criada no App Studio usando uma das opções de secções avançadas, a Collection.App Studio: Secção para Twitter

Ao criar a secção do tipo Collection, temos que definir o nome, escolher a opção Dynamic resources data in the cloud e em seguida clicar em Add default columns (irá criar toda a estrutura de dados necessária para a coleção, caso o utilizador pretenda criar a sua própria estrutura deve usar a opção Create new). 

O resultado será o seguinte:

App Studio: Resultado da Secção para Twitter

Depois de confirmar, iremos ter mais uma seção na página de conteúdos:

App Studios: Secções

Como referi no meu artigo anterior, podemos alterar a ordem das seções, fazendo arrastar e largar (Drag & Drop), desta forma iremos ter:

App Studios: Secções

De seguida, devemos editar a seção Twitter, para definir uma entrada de dados para teste e para definir os Bindings do DataTemplates

Comecemos por definir os Bindings, primeiro da página principal:

App Studio: Bindings da Página Principal

Em seguida da página de detalhe:

App Studio: Bindings da Página de Detalhes

Por fim vamos criar uma entrada falsa, no separador de dados:

App Studio: Dados

App Studio: Dados

É possível importar dados de um ficheiro CSV ou inserir manualmente, neste caso, apenas foi criada uma entrada manualmente.

Neste momento, estamos prontos para gerar novos pacotes e com isto obter nova versão do código fonte, para assim continuar o desenvolvimento no Visual Studio 2013.

No Visual Studio, o projeto irá ter a seguinte estrutura:

  • AppStudio.Windows – projeto para a aplicação Windows 8.1
  • AppStudio.WindowsPhone – projeto para a aplicação Windows Phone 8.1
  • AppStudio.Shared – projeto partilhado pelas duas aplicações
  • AppStudio.BackgroundAgent – projeto que dá suporte a background agents
  • AppStudio.Data – projeto que consiste numa portable class library e contém toda a informação sobre a estrutura de dados usadas nas duas aplicações e contém ainda os providers de dados (facebook, feeds, …)

App Studio: Estrutura do Projeto

O resultado do deploy da aplicação no Windows Phone (secção do Twitter) é:

App Studio: Resultado

Para alterar esta página, para que use dados reais do Twitter é necessário fazer algumas alterações no projecto AppStudio.Data:

App Studio: Alterações Necessárias

Em TwitterDataSource, devemos alterar o método LoadData para:

public async Task<IEnumerable<TwitterSchema>> LoadData()
{
    if (_data == null)
    {
        try
        {
            var serviceDataProvider = new TwitterDataProvider();
            _data = await serviceDataProvider.Load();
        }
        catch (Exception ex)
        {
            AppLogs.WriteError("TwitterDataSource.LoadData", ex.ToString());
        }
    }
    return _data;
}

Em vez de usar o ServiceDataProvider devemos criar o TwitterDataProvider que será:

public class TwitterDataProvider
{
    TwitterContext twitterCtx;

    public TwitterDataProvider()
    {
        var auth = new SingleUserAuthorizer()
        {
            CredentialStore = new SingleUserInMemoryCredentialStore
            {
                ConsumerKey = ConsumerKey,
                ConsumerSecret = ConsumerSecret,
                AccessToken = AccessToken,
                AccessTokenSecret = AccessTokenSecret
            }
        };

        twitterCtx = new TwitterContext(auth);
    }

    public async Task<IEnumerable<TwitterSchema>> Load()
    {
        var searchresults = await (from tweet in twitterCtx.Search
            where tweet.Type == SearchType.Search &&
            tweet.Query == "#contoso" && tweet.Count == 100
            select tweet).SingleOrDefaultAsync();

        var data = new List<TwitterSchema>();
        foreach (var status in searchresults.Statuses)
        {
            data.Add(new TwitterSchema()
            {
                Title = status.User.Name,
                Description = status.Text,
                ImageUrl = status.User.ProfileImageUrl,
                Subtitle = status.CreatedAt.ToString("t")
            });
        }
        return data;
    }
}

Para obter as chaves

const string ConsumerKey = "...";
const string ConsumerSecret = "...";
const string AccessToken = "...";
const string AccessTokenSecret = "...";

deverá aceder ao dev.twitter.com e criar uma aplicação e em seguida obterá as chaves.

É necessário instalar o pacote do Nuget linqtoTwitter no projeto AppStudio.Data, mas como este projeto é uma Portable Class Library com targets para Windows Phone 8.1 e Windows 8.1, a instalação do pacote irá falhar. Para dar a volta a este problema, uma vez que ainda não existe uma atualização, deve-se instalar o pacote no projecto AppStudio.Windows e depois no projecto AppStudio.Data, deve-se fazer Add Reference Browser e em seguida procurar pela pasta que contém o pacote instalado, que será algo do género

App\packages\linqtotwitter.3.0.2\lib\portable-win8+net45+wp8

e deve-se selecionar a dll LinqToTwitterPcl.dll e assim o projeto AppStudio.Data irá ter a referência do LinToTwitterPcl.

Depois de correr a aplicação iremos ter o seguinte resultado, para Windows Phone 8.1:

App Studio: Resultado no Windows Phone 8.1 (Página Principal) App Studio: Resultado no Windows Phone 8.1 (Página dos Detalhes) 

A versão Windows 8.1 tem o seguinte aspeto:

App Studio: Resultado no Windows 8.1

Como se pode observar o aspeto da interface para a secção do Twitter, não é muito agradável e como tal podemos alterar o código XAML para assim obtermos um resultado melhor. Outro aspeto que podemos alterar é o facto de ao clicar no item navegamos para a página de detalhe, o que neste caso não faz muito sentido porque irá apresentar a mesma informação que na página inicial, por tanto iremos remover. 

No projeto de cada aplicação, podemos encontrar uma pasta chamada Views que contém uma pasta chamada DataTemplates, que por sua vez contém o dicionário de recursos para cada secção. Se abrirmos o ficheiro TwitterViews, encontramos o DataTemplate TwitterItem que representa cada item do feed do Twitter.

App Studio: Código para Alterar

Para a versão do Windows Phone 8.1, podemos alterar para:

<DataTemplate x:Key="TwitterList">
  <Grid>
    <ListView ItemsSource="{Binding Items}" SelectedItem="{Binding NavigationItem, Mode=TwoWay}"
 SelectionMode="None" IsSwipeEnabled="False" ScrollViewer.VerticalScrollBarVisibility="Hidden"
 ItemTemplate="{StaticResource TwitterItem}">
    </ListView>
    <ProgressBar Width="380" Height="40" Foreground="White" VerticalAlignment="Top" IsIndeterminate="True" Visibility="{Binding ProgressBarVisibility}" />
  </Grid>
</DataTemplate>

<!-- ListPhotoLeftDescription Item -->
<DataTemplate x:Key="TwitterItem">
  <Grid Width="380">
    <Grid.RowDefinitions>
      <RowDefinition Height="80"/>
      <RowDefinition Height="60"/>
    </Grid.RowDefinitions>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="50"/>
    <ColumnDefinition Width="*"/>
  </Grid.ColumnDefinitions>

  <Image Grid.Row="0" Grid.Column="0" Margin="0, 8" Source="{Binding ImageUrl}" MaxHeight="50" MaxWidth="50"
 Stretch="UniformToFill" VerticalAlignment="Center" />
 
    <StackPanel Grid.Row="0" Grid.Column="1">
      <TextBlock Margin="16, 8, 5, 10" Style="{StaticResource ItemHeaderWrapText}" MaxHeight="50" VerticalAlignment="Center"
 Text="{Binding Title, Converter={StaticResource TextPlainConverter}, ConverterParameter=140}" />
      <TextBlock Margin="16, 8, 5, 10" Style="{StaticResource ItemSubheaderText}" MaxHeight="110" VerticalAlignment="Top"
 Text="{Binding Subtitle}" />
    </StackPanel>

    <TextBlock Grid.Row="1" Grid.ColumnSpan="2" Margin="0, 0, 5, 0" Style="{StaticResource ItemSmallText}" MaxHeight="200" VerticalAlignment="Top"
 Text="{Binding Description}" />
  </Grid>
</DataTemplate>

Para a versão de Windows 8.1, podemos alterar para:

<DataTemplate x:Key="TwitterListSnapped">
  <Grid Width="230">
    <GridView ItemsSource="{Binding PreviewItems}" SelectedItem="{Binding NavigationItem, Mode=TwoWay}"
 SelectionMode="None" IsSwipeEnabled="False" ScrollViewer.VerticalScrollBarVisibility="Hidden"
 ItemTemplate="{StaticResource TwitterItemSnapped}">
    </GridView>
    <ProgressBar Height="40" Foreground="White" VerticalAlignment="Top" IsIndeterminate="True" Visibility="{Binding ProgressBarVisibility}" />
  </Grid>
</DataTemplate>

<!-- ListPhotoLeftDescription Item -->
<DataTemplate x:Key="TwitterItem">
  <Grid Width="480" Height="240">
    <Grid.RowDefinitions>
      <RowDefinition Height="0"/>
      <RowDefinition Height="130"/>
      <RowDefinition Height="160"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="140"/>
      <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <Image Grid.Row="1" Grid.Column="0" Margin="0, 8" Source="{Binding ImageUrl, Converter={StaticResource ThumbnailConverter}, ConverterParameter=220}" MaxHeight="110"
 Stretch="UniformToFill" VerticalAlignment="Top" />
    <StackPanel Grid.Row="1" Grid.Column="1" Orientation="Vertical">
      <TextBlock Margin="16, 0, 10, 0" Style="{StaticResource ItemHeaderWrapText}"
 MaxHeight="50" VerticalAlignment="Center" Text="{Binding Title, Converter={StaticResource TextPlainConverter}, ConverterParameter=140}" />
      <TextBlock Margin="16, 8, 10, 10" Style="{StaticResource ItemSubheaderText}"
 MaxHeight="110" VerticalAlignment="Top" Text="{Binding Subtitle, Converter={StaticResource TextPlainConverter}, ConverterParameter=280}" />
    </StackPanel>
    <TextBlock Grid.Row="2" Grid.ColumnSpan="2" Margin="0, 0, 10, 0" Style="{StaticResource ItemSmallText}"
 MaxHeight="60" VerticalAlignment="Top" Text="{Binding Description}" />
  </Grid>
</DataTemplate>

E assim obtemos um novo aspeto da aplicação, para Windows Phone 8.1 iremos ter:

App Studio: Resultado Final em Windows Phone 8.1

E para Windows 8.1 iremos ter:

App Studio: Resultado Final em Windows 8.1

Em conclusão, conclui-se que é muito simples estender a aplicação gerada pelo App Studio, no entanto não é possível fazer o upload desta versão para o App Studio, todas as alterações feitas na aplicação no App Studio implicam um “merge” entre versões.