Resultados para ''

Fragmentação no iPhone?

Escrito por Afonso Junior em 29/06/10 17:00

Já é lugar-comum dizer que o perfil dos usuários de celular mudou muito. Agora, além de um bom aparelho, os aplicativos são determinantes para se escolher um novo celular: quanto mais aplicativos existirem, mais atrativo fica o aparelho. Por conta disso, tudo que for feito no sentido de melhorar a vida do desenvolvedor acaba sendo bom também pro fabricante do dispositivo, pois mais desenvolvedores implica mais aplicativos, enfim, tudo o que o usuário final deseja.

Porém, há um fator que sempre atrapalhou os desenvolvedores na hora de criar o seu aplicativo: a fragmentação. Pra quem não sabe o que isso quer dizer, vou explicar através de um exemplo. Quando desenvolvemos para Java ME, nunca temos certeza se o aplicativo irá funcionar em todos os aparelhos. Isso se deve a diversos fatores, seja porque a fabricante decide instalar uma versão mais antiga (ou mais nova) do CLDC, ou por questões de compatibilidade do hardware que se usa no dispositivo, enfim, sobra para o desenvolvedor testar em diversos aparelhos, e esperar que funcione na maioria deles.

Esse problema não ocorre só com Java ME, também acontecia com Windows Mobile: muitas vezes soluções corporativas eram desenvolvidas e homologadas para um aparelho, e as empresas ficavam presas àquele modelo, pois não havia garantias de que iria funcionar com outro, mesmo sendo da mesma fabricante.

Daí veio o desenvolvimento para iPhone, e esse problema quase não existia: praticamente sempre o mesmo hardware, poucas alterações entre as atualizações do sistema operacional do aparelho, mesmo tamanho de tela, enfim, a vida para nós desenvolvedores foi facilitada. Hoje em dia, um dos principais concorrentes do iPhoneOS, o Android, embora tenha um bom SDK, sofre muito com esse problema. Basta colocar no Google "fragmentação android" e ver que há diversos textos tratando disso como não só como um problema, mas como uma ameaça à plataforma.

Porém, nos últimos meses surgiram diversas novidades vindas da empresa de Cupertino: surgiu o iPad, com tamanho diferente de tela e sem câmera, veio o novo sistema operacional - o iOS4 -, e com ele a notícia de que os aparelhos mais antigos (2G para baixo) não poderiam ser atualizados, e o novo iPhone, também com nova resolução de tela. Por conta disso, começou a rolar na internet alguns textos que afirmavam que estaria começando o processo de fragmentação do iPhone.

Não se pode negar que alguns percalços realmente existam por causa dessa avalanche de atualizações: aqui na Mobits, por exemplo, só temos um computador habilitado para fazer build abaixo da versão 3.2. Isso sem contar que, para fazer um aplicativo universal, a própria Apple afirma que você deverá ter mais trabalho. Porém ainda não é nada perto ao que encontramos nas outras plataformas. Não se trata de uma defesa cega da Apple (como se ela precisasse), mas desenvolver para iPhone ainda é mais fácil do que para as outras plataformas. E isso acaba explicando o porquê ela tem tantos aplicativos disponíveis, enquanto outras, como Symbian, vão minguando no mercado de smartphones.

Leia também:

iPad: primeiro projeto com UISplitView

Escrito por Afonso Junior em 17/05/10 18:30

O iPad roda o mesmo sistema operacional utilizado pelo iPhone e iPod Touch. Isso significa que os desenvolvedores que já estão familiarizados com programação em iPhone são capazes de escrever rapidamente aplicativos para o iPad. Na verdade, a maioria (se não todas) as aplicações do iPhone deve ser executada sem nenhum problema no iPad, embora em um tamanho menor de quadro, com uma opção de aumentar o tamanho dos pixels. No entanto, para realmente fazer pleno uso da tela maior do iPad, você precisa redesenhar sua interface de usuário para ter em conta o espaço extra de tela. O iPhone SDK 3.2, que é necessário para o desenvolvimento para iPad, vem com um novo modelo de aplicação, Split View-based Application, que permite construir aplicações em wide-screen.

O modelo Split View-based permite que você crie uma interface de visualização dividida em sua aplicação. O lado esquerdo da tela exibe uma lista de itens selecionáveis, e o lado direito exibe os detalhes do item selecionado. Este artigo mostrará como desenvolver um aplicativo baseado nesse modelo para o iPad.

Começando o projeto

Na janela de diálogo de novo projeto, escolha o "Split View-based Application". Dê um nome para o seu projeto (o meu será um projeto de Portfolio).

Split View-based Application

Observe na imagem abaixo que além do AppDelegate ele cria mais duas classes: o RootViewController e o DetailViewController. Mais tarde eu explicarei como eles se encaixarão nessa dinâmica toda.

Classes geradas

Mande rodar o projeto (Command + R) e veja como ficam as telas nas figuras abaixo. Quando o iPad está deitado, a lista fica visível à esquerda. Quando em pé, ele aparece como um menu suspenso.

Split View no iPad: paisagem

Split View no iPad: retrato

Olhando o AppDelegate

Se olharmos o código de PortfolioAppDelegate.h,

Código no AppDelegate

podemos ver que ele tem um UISplitViewController. Esse elemento vai "abrigar" dois viewControllers: o RootViewController e o DetailViewController - que, respectivamente, serão a lista com os itens a serem selecionados e a tela que exibe algo de acordo com a seleção da lista.

Na implementação do PortfolioAppDelegate, nenhuma novidade:

Código no AppDelegate (implementação)

Somente adiciona a view do splitViewController na window.

Olhando o XIB

MainWindow no Interface Builder

Abrindo o arquivo MainWindow.xib, podemos ver que ele tem um Split View Controller. Dentro dele, dois elementos: o NavigationController e um view controller (cuja classe é referenciada pela classe DetailViewController no projeto). Dentro do NavigationController,

RootViewController no Interface Builder

temos um Navigation Bar e outro viewController, referenciado pelo RootViewController do projeto.

RootViewController no Interface Builder

No AppDelegate, algo que já era de se esperar:

RootViewController no Interface Builder

todos os elementos com propriedade IBOutlet no PortfolioAppDelegate.h ligados com seus correspondentes no XIB.

Olhando os ViewControllers

Depois de olharmos o XIB, vamos ver como a mágica acontece dentro dos dois viewControllers do projeto. Numa rápida olhada no RootViewController.h

Código do RootViewController

percebemos que ele é filho de um UITableViewController, que servirá para tabelar os valores a serem exibidos na tela. Eu criei o array portfolio que guardará os valores que serão exibidos na tela.

Agora, olhando o código de DetailViewController.h,

Código do DetailViewController

podemos perceber que ele implementa dois protocolos:

  • UIPopoverControllerDelegate: para controlar o popover que irá exibir o conteúdo da tableView do RootViewController quando o iPad estiver em pé (posição retrato);
  • UISplitViewControllerDelegate: para dizer o que fazer (esconder ou exibir) o PopoverView quando o iPad mudar a orientação.

Na implementação, o Xcode gera para o DetailViewController quatro métodos que nos interessam para o nosso exemplo. O primeiro,

Código do DetailViewController

serve para utilização do detailItem dentro da classe. Na declaração da classe ele foi declarado como um id, e a ideia é que ele seja utilizado para popular os valores a serem exibidos na tela. No RootViewController, eu atribuí a ele um NSDictionary com duas chaves: o texto a ser exibido e o nome da imagem a ser mostrada. Mas a ideia é não mexer muito nesse método, e sim no próximo:

Código do DetailViewController

Olhando o código você pode perceber que as propriedades da label e da imagem são alteradas, ou seja, é aqui que parte da "mágica" acontece. Os outros dois métodos são implementações dos protocolos assinados:

Código do DetailViewController

Confesso que mexi quase nada neles. O primeiro é acionado quando a tela é rotacionada para o modo retrato (em pé). E o outro, o contrário: ele é o que faz o RootViewController ser exibido novamente quando o aparelho é posto em modo paisagem.

Enfim, com um código simples já consigo fazer uma aplicação de portfólio. Para facilitar, eu coloquei em dois arquivos .plist a relação entre os nomes das posições na tableView com os arquivos de imagem e com suas descrições. E criei uma classe utilitária para fazer o acesso aos arquivos. Tudo isso você pode consultar baixando o projeto. Abaixo segue algumas telas do projeto.

Exemplos do projeto

Exemplos do projeto

Exemplos do projeto

Exemplos do projeto

Leia também:

Testes no iPhone - Usando o framework padrão do Xcode

Escrito por Afonso Junior em 02/03/10 11:30

O post do Felipe sobre testes em iPhone, escrito em janeiro do ano passado, serviu como parâmetro para vários projetos nossos aqui na Mobits. Só depois de um bom tempo utilizando o framework do Google, descobrimos lendo posts do Matt Gallagher no Cocoa with love que o framework nativo do Xcode estava disponível para projetos em iPhone.

Pesquisando na internet, decidimos implementar um projeto utilizando o framework padrão. Este post visa mostrar como configurar seu projeto para iPhone usando o framework nativo e compará-lo com o GTM. Por enquanto, estamos lidando apenas com teste unitários. Em um post futuro comentamos sobre Mock e como adicioná-lo ao seu projeto.

Configuração

Uma vez criado o projeto, você deve criar um novo target para o projeto. Clique com o botão direito em Target > Add > New Target....

Adicionando novo target

Como template, escolha Unit Test Bundle. Escolha um nome para o target (sugestão: Testes Unitarios) e clique em Finish.

Agora, arraste o target original para dentro do target de teste, para criar dependência (forçar o aplicativo a dar build no projeto antes de executar os testes). Após fazer isso, o target deve ficar assim:

Targets aninhados

Pronto! Com isso você já tem o suficiente para rodar seus testes. Mas pode ser que você queira algo a mais, então vamos ao próximo passo que pode ser muito útil nos seus testes.

Debug

Esta foi a parte mais complicada de fazer funcionar. Depois de muitas indas e vindas em diversos sites, conseguimos configurar o debug (funcionando com breakpoint). Assim você pode correr passo-a-passo as linhas de código dos seus testes caso precise. Vale ressaltar que o debug não funciona caso tenha ocorrido erro de compilação, mas funciona perfeitamente em caso de falhas ocorridas nos testes.

Mas vamos ao que interessa: primeiro, crie um executável para o projeto (Project > New Custom Executable...).

Criando executável

Na janela que se abre, escolha o nome do executável. Ele deverá executar o otest, um programa de termnal que serve para depurar o código das classes em Objective-C. Ele deve ser específico para o SDK do iPhone que você utiliza no projeto. Para saber onde ele está e qual versão você deve utilizar, vá no terminal e digite:

find /Developer -name otest

Eu obtive os seguintes resultados:

/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/Developer/usr/bin/otest
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.1.2.sdk/Developer/usr/bin/otest
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.1.sdk/Developer/usr/bin/otest
/Developer/Tools/otest

Que fique bem claro que o último não serve para projetos em iPhone. No nosso caso, usamos o segundo (3.1.2). Clique em Finish. Agora precisamos configurar os argumentos do executável na janela que aparece. A imagem abaixo mostra como eles devem ser configurados:

Parâmetros do executável

Na seção dos argumentos, você deve obedecer a ordem em que eles estão escritos. O segundo argumento deve ser o nome do produto gerado pelo target de testes que você utiliza (veja no grupo Products). Na seção de variáveis, utilize os seguintes valores:

Variável Valor
DYLD_LIBRARY_PATH ${BUILD_PRODUCTS_DIR}:${DYLD_LIBRARY_PATH}
DYLD_FRAMEWORK_PATH "${BUILD_PRODUCTS_DIR}:${DEVELOPER_LIBRARY_DIR}/Frameworks:
${DYLD_FRAMEWORK_PATH}"
DYLD_NEW_LOCAL_SHARED_REGIONS YES
CFFIXED_USER_HOME "${HOME}/Library/Application Support/iPhone Simulator/User"
IPHONE_SIMULATOR_ROOT $SDKROOT
DYLD_NO_FIX_PREBINDING YES
DYLD_ROOT_PATH /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/
iPhoneSimulator3.1.2.sdk

Cuidado com a última variável: ela deve ser a mesma versão do SDK utilizado com o otest. Feito isso, você já possui a configuração necessária para "debugar" seus testes. Tudo que você precisa fazer é configurar o executável como o padrão (Project > Set Active Executable). Marque os breakpoints que achar necessário e execute com "Build and Debug".

Comparações

Com o framework configurado e com vários casos de teste já implementados, fica inevitável a comparação entre o framework padrão e o GTM. Algumas diferenças são notadas logo de cara.

  • Menos métodos de teste: foi um susto ao ver que o framework padrão não tinha o STAssertEqualStrings. Mas nada que assustasse muito: o STAssertEqualObjects servia para o mesmo propósito. No final das contas, não houve nenhum teste que não conseguimos fazer por não existir método para tal.

  • Bundle: Isso é ponto positivo para o GTM. Para acessar arquivos no ambiente padrão você não utiliza o [NSBundle mainBundle]. Para fazer funcionar, tivemos que configurar no target (na aba Properties, no campo Identifier) um identificador que pudesse ser referenciado no código. Se, por exemplo, você colocar lá um identificador "com.mobits.caricas.tests", basta chamar o bundle identificado por essa string: [NSBundle bundleWithIdentifier:@"com.mobits.caricas.tests"]. É óbvio que isso nos causou alguns problemas nos testes, principalmente nos casos em que no target do aplicativo eu tinha que rodar em um bundle e no target de testes eu tinha que rodar em outro. A solução foi utilizar diretivas de pré-compilação.

  • Build Results: nisso o framework padrão ganha de lavada do GTM. Enquanto neste os erros aparecem todos duplicados, e listados diretamente na lista dos resultados do build, naquele aparece bem organizado, cada erro apontado hierarquicamente dentro do seu específico caso de teste.

Exibição de erros no GTM
Exibição dos erros no GTM: duplicado

Exibição dos erros no framework padrão: visão hierárquica dos testes
Exibição dos erros no framework padrão: visão hierárquica dos testes

Conclusão

Por ser mais simples de configurar, por exibir melhor os erros dos testes e por não ter certas mandingas que o GTM tem (não poder rodar os testes com o iPhone Simulator aberto, por exemplo), a escolha é o framework padrão do Xcode. Os métodos a mais de teste do GTM não foram um diferencial tão grande que pesasse em favor dele, mas talvez aqueles que o utilizam e desejam migrar vão ter alguns problemas de adaptação, mas nada que seja o fim do mundo.

Em um post futuro eu comento outra parte importante nos testes, a técnica de Mock Objects, como configurá-lo e como utilizá-lo em seus testes. Ah, e se você encontrou algum erro ao tentar configurar o ambiente, adiciona um comentário aqui, pode ser que já tenhamos passado por isso e saibamos como solucionar.

Grande abraço!

Leia também

Formatador Automático para Objective C

Escrito por Felipe Barreto em 04/05/09 19:55

UPDATE: funcionando agora no Snow Leopard. Verifique a lista de passos da instalação.

Uma das coisas que me incomodam na hora de programar pra iPhone é que o XCode não possui um mecanismo para formatar automaticamente o código como há no Eclipse ou no NetBeans. O máximo que a IDE da Apple permite é tabular automaticamente um trecho de código selecionado. Muito fraco.

Durante a pesquisa, foi difícil escolher o termo certo para encontrar o que eu queria, pois existem diversas variações: code beautifier, formatter, code styler, entre outras.

Finalmente, encontrei o tal do Uncrustify que é um programa de terminal para UNIX - logo, para MAC - e que permite configurar uma série de parâmetros de formatação e aplicar sobre um arquivo de código de diversas linguagens baseadas em C - inclusive Objective C.

"Estou no caminho certo", pensei eu. "Agora só falta aprender a instalar, configurar e fazer o XCode usar o programinha". Depois de penar um pouco, cheguei ao artigo que me colocou na direção que eu esperava. Nem tudo o que foi dito nele funcionou 100% ou está completo, mas foi de grande ajuda para conseguir alcançar o que vou apresentar abaixo.

Baixando e instalando o Uncrustify

  • Faça o download do uncrustify e extraia em qualquer lugar;
  • Abra o arquivo uncrustify.xcodeproj no XCode e dê um Build (Command-B);
  • Update: Para o Snow Leopard, o build acima não funcionou. Ao invés dele, use o Terminal, na pasta do uncrustify:

    $> ./configure
    $> make

  • Volte à pasta onde extraiu o Uncrustify e procure o executável no caminho build/ppc. Update: no Snow Lepard, o executável estará na pasta src.

Agora, como meu conhecimento de UNIX é meio tosco, não garanto que o passo seguinte seja o mais correto, mas funcionou. :D

  • Copie o executável para a pasta /usr/bin (pode ser necessário se autenticar como admin).

Pronto! O Uncrustify está disponível para ser usado por qualquer usuário da máquina.

Criando o arquivo de configuração

Na pasta do Uncrustify, você vai encontrar o arquivo etc/defaults.cfg que possui praticamente todos os parâmetros disponíveis acompanhado de comentários bem explicativos. Mas eles são muitos e configurá-los um por um sem ver o efeito que causam sobre o código é impensável para alguém preguiçoso como eu.

Felizmente, alguém teve a bondade de criar um configurador para diversas ferramentas como o Uncrustify, inclusive o próprio: UniversalIndentGUI.

Esta ferramenta, apesar de ter a interface um pouco tosca e com usabilidade mediana, facilita muito o trabalho, pois permite editar os parâmetros e ver imediatamente o resultado sobre um trecho de código que você pode fornecer e manipular durante a fase de configuração.

Não vou me aprofundar sobre os detalhes desta fase, mas se você não estiver interessado em passar por ela, compartilho aqui o arquivo - ainda em desenvolvimento - com o padrão de código da Mobits.

Usando o arquivo acima, ou gerando o seu próprio, recomendo salvá-lo em /etc/uncrustify/qualquer_coisa.cfg para que esteja disponível para todos os usuários.

Colocando no XCode

Embora o XCode não possua diversas ferramentas comuns em outras IDEs, ele tem um mecanismo simples para adicionar funcionalidades sem muito esforço: os User Scripts.

Uncrustify oara ObjectiveC no XCode

  • Abra a tela de edição dos User Scripts e adicione um Shell Script com nome tipo "Auto Format";
  • Sugiro definir um atalho de teclado, como command-shift-A;
  • Copie o código abaixo para o seu script (renomeie o arquivo de configuração se necessário):
#!/bin/sh
echo -n "%%%{PBXSelection}%%%"
uncrustify -q -l OC -c /etc/uncrustify/mobits-uncrustify.cfg
echo -n "%%%{PBXSelection}%%%"
  • Configure os parâmetros de entrada e saída
    • Input: Entire Document
    • Directory: Selection
    • Output: Replace Document Contents
    • Errors: Display in Alert

Pronto. Agora basta executar o script sobre o código que estiver aberto no momento e apreciar sua beleza. :D

Até a próxima.

Leia também:

  1. Saiba como customizar sua UITableView
  2. Comparação entre as soluções ORM para iPhone
  3. Teste automático de interface para suas Apps de iPhone