C.E.S.A.R – CENTRO DE ESTUDOS E SISTEMAS AVANÇADOS DO RECIFE NELSON GLAUBER DE VASCONCELOS LEAL IOS2DROID – UMA FERRAMENTA DE TRADUÇÃO DE APLICAÇÕES IPHONE PARA ANDROID RECIFE 2010 NELSON GLAUBER DE VASCONCELOS LEAL IOS2DROID – UMA FERRAMENTA DE TRADUÇÃO DE APLICAÇÕES IPHONE PARA ANDROID Dissertação apresentada ao programa de Mestrado em Engenharia de Software do Centro de Estudos e Sistemas Avançados do Recife – C.E.S.A.R, como requisito para a obtenção do título de Mestre em Engenharia de Software. Orientação: Prof. Dr. Silvio Romero Lemos Meira RECIFE 2010 ii C.E.S.A.R – CENTRO DE ESTUDOS E SISTEMAS AVANÇADOS DO RECIFE iOS2Droid – Uma ferramenta de tradução de aplicações iPhone para Android NELSON GLAUBER DE VASCONCELOS LEAL Dissertação apresentada ao programa de Mestrado em Engenharia de Software do Centro de Estudos e Sistemas Avançados do Recife – C.E.S.A.R, como requisito para a obtenção do título de Mestre em Engenharia de Software. Data de aprovação: _____ / _____ / 2010. Banca examinadora: _________________________________ Prof. Dr. Silvio Romero Lemos Meira CESAR.EDU _________________________________ Prof. Dr. Carlos André Guimarães Ferraz U.F.P.E. _________________________________ Prof. M.Sc. Felipe Santana F. Soares CESAR.EDU _________________________________ Prof. M.Sc. Luis Eugênio F. Tenório CESAR.EDU iii Dedicatória Dedico esta dissertação primeiramente a Deus, por olhar para um filho e enche-lo de bênçãos as quais nunca me esquecerei de agradecer. Aos meus pais Neves e Eronilda por me darem educação e uma base sólida para construir um caráter de uma pessoa correta e digna. A minha esposa e melhor amiga Marcia, com quem sempre pude contar com o amor, carinho, dedicação e principalmente paciência. Agradecimentos A Lenildo, Eduardo e Gitirana que me proporcionaram começar a caminhada. Ao meu orientador, Prof. Dr. Silvio Meira por seu trabalho tornar o sonho de outras pessoas uma realidade. Ao meu Co-Orientador left, que acreditou nesse trabalho e me deu total incentivo e motivação. Obrigado por todo apoio prestado. A Tarciana Melo, uma conselheira e líder nata, que compreendeu minha divisão entre trabalho e estudos. A todos os educadores e profissionais CESAR.EDU pelo aprendizado, amizade e incentivo. do Resumo Com a popularização dos telefones celulares inteligentes (smartphones), a disputa entre os fabricantes desse tipo de aparelho vem ficando cada vez mais acirrada. O aumento do poder de processamento e da velocidade das redes de comunicação são fatores que estão influenciando nesse cenário. E essa disputa está ultrapassando a barreira de fabricantes e recursos e está chegando ao patamar dos sistemas operacionais e aplicativos. Com o lançamento do iPhone, o mercado sofreu uma revolução, visto que o telefone da Apple dispunha de recursos até então inexistentes em seus concorrentes. Aliado a isso, o modelo de distribuição de aplicações para os usuários através de uma loja virtual atraiu desenvolvedores, que poderiam lucrar com seus softwares disponibilizando-os para que os usuários pudessem adquirir através do próprio telefone. Tendo em vista esse sucesso, os concorrentes buscaram alternativas para se adaptar ao novo cenário do mercado de smartphones. A OHA (Open Handset Alliance), consórcio formado pela Google juntamente com outros grandes nomes do mercado de tecnologia, resolveu entrar nessa disputa e criaram a plataforma Android. Uma plataforma aberta, com modelo de distribuição de aplicações similar a do iPhone e que pode ser utilizada livremente por qualquer fabricante. Atualmente essas duas plataformas são as que atraem mais usuários e desenvolvedores, entretanto são completamente diferentes, de modo que, criar aplicativos que tenham versões para as duas plataformas requer a escrita do mesmo software duas vezes. Sendo assim, esse trabalho apresenta o iOS2Droid, uma ferramenta que realiza a conversão do código fonte de aplicações iPhone para Android, de modo a minimizar o esforço de codificação em projetos de conversão (porting) de aplicativos que devam ser disponibilizados para as duas plataformas. Palavras-chave iPhone. Android. Smartphone. Telefones Celulares. Mobilidade. Conversão de Código. Abstract With the popularity of smartphones, the competition between the manufacturers of these devices is becoming increasingly fierce. The strength of the power of processing and speed of communication networks are factors that are influencing this scenario. And this race is overcoming the barrier of manufacturers and resources and reaching the level of operating systems and applications. With the iPhone launch, the market has undergone a revolution once the iPhone had resources that had not been developed by their competitors so far. Furthermore, the model of distributing applications to users through a virtual store, attracted developers, who could profit from their software and making them available so that users could purchase them through the phone itself. Having in mind this success, competitors sought alternatives to suit the new scenario of the smartphone market. OHA (Open Handset Alliance), a consortium formed by Google, along with other big names in the technology market, decided to enter the dispute and created the Android platform. An open platform, with a distribution model similar to the iPhone applications and can be used freely by any manufacturer. Nowadays, these two platforms are attracting more users and developers, however they are completely different, therefore, create applications that have versions for both platforms requires writing the same software twice. Thus, this work presents the iOS2Droid, a tool that performs the conversion of the source code for iPhone applications for Android, to minimize the coding effort in conversion projects of applications that should be available for both platforms. Key-words iPhone. Android. Smartphone. Mobile Phones. Mobile. Code Conversion. SUMÁRIO 1 INTRODUÇÃO ............................................................................................. 1 1.1 VISÃO GERAL ............................................................................................. 1 1.2 1.2.1 1.2.2 MOTIVAÇÃO ................................................................................................ 2 Motivação de Mercado ................................................................................. 2 Motivação Técnica ....................................................................................... 6 1.3 1.3.1 1.3.2 PROBLEMA ................................................................................................. 7 Objetivo geral ............................................................................................... 8 Objetivos específicos ................................................................................... 8 1.4 JUSTIFICATIVA ........................................................................................... 9 1.5 CONTRIBUIÇÕES ....................................................................................... 9 1.6 ESTRUTURA DA DISSERTAÇÃO ............................................................... 9 2 COMPUTAÇÃO MÓVEL E A ARQUITETURA DAS PLATAFORMAS IOS E ANDROID ........................................................... 11 2.1 COMPUTAÇÃO MÓVEL ............................................................................ 11 2.2 2.2.1 2.2.2 2.2.3 2.2.4 APPLE IPHONE/IOS ..................................................................................... 12 Arquitetura.................................................................................................. 12 Ferramentas ............................................................................................... 13 Modelo de Aplicação .................................................................................. 14 Ciclo de Desenvolvimento .......................................................................... 15 2.3 2.3.1 2.3.2 2.3.3 2.3.4 GOOGLE ANDROID ...................................................................................... 16 Arquitetura.................................................................................................. 17 Ferramentas ............................................................................................... 18 Modelo de Aplicação .................................................................................. 18 Ciclo de Desenvolvimento .......................................................................... 19 2.4 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 TRABALHOS RELACIONADOS ................................................................ 20 XMLVM ...................................................................................................... 20 Titanium Mobile .......................................................................................... 21 PhoneGap .................................................................................................. 21 Adobe AIR .................................................................................................. 21 ELIPS Studio .............................................................................................. 21 Comparativo ............................................................................................... 22 2.5 CONCLUSÕES .......................................................................................... 22 3 SOLUÇÃO PROPOSTA – IOS2DROID..................................................... 24 3.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 CONVERSÃO DO CÓDIGO FONTE ......................................................... 24 Objective-C e Java ..................................................................................... 25 Estrutura de Classes .................................................................................. 26 Alocação de memória................................................................................. 27 Propriedades .............................................................................................. 28 Classes e tipos de dados ........................................................................... 30 3.1.6 3.1.7 Assinaturas e chamadas de métodos ........................................................ 31 Diretiva de compilação #define .................................................................. 32 3.2 3.2.1 CONVERSÃO DO ARQUIVO DE DEFINIÇÃO DA UI................................ 32 Conversão dos Arquivos de UI................................................................... 35 3.3 MODELO DE APLICAÇÃO ........................................................................ 38 3.4 EXECUÇÃO DA APLICAÇÃO CONVERTIDA ........................................... 39 3.5 3.5.1 3.5.2 RESTRIÇÕES E LIMITAÇÕES .................................................................. 44 Restrições de hardware ............................................................................. 44 Restrições da linguagem ............................................................................ 45 3.5.2.1 Palavras reservadas ................................................................................... 45 3.5.2.2 Estruturas genéricas e checagem de tipo................................................... 46 3.6 CONCLUSÕES .......................................................................................... 47 4 VALIDAÇÃO DA FERRAMENTA .............................................................. 49 4.1 BUTTON FUN ............................................................................................ 49 4.2 4.2.1 4.2.2 4.2.3 4.2.4 CONTROL FUN ......................................................................................... 50 Aspecto Visual ........................................................................................... 51 Novos eventos ........................................................................................... 53 Suporte a imagens 9-patch ........................................................................ 54 Cores e Textos ........................................................................................... 54 4.3 VIEW SWITCHER ...................................................................................... 54 4.4 SOCCER BALL .......................................................................................... 55 4.5 CONCLUSÕES .......................................................................................... 57 5 CONSIDERAÇÕES FINAIS ....................................................................... 59 5.1 EVOLUÇÃO DO TRABALHO ..................................................................... 59 REFERÊNCIAS ......................................................................................................... 61 Lista de ilustrações Figura 1. Acessos a internet por Sistema Operacional Móveis no Mundo .................. 3 Figura 2. Vendas de smartphones por sistema operacional nos EUA ........................ 4 Figura 3. Pesquisa de satisfação dos sistemas operacionais móveis ......................... 5 Figura 4. Interesse dos desenvolvedores em criar aplicações para as plataformas............................................................................................. 6 Figura 5. Camadas do sistema operacional iOS ....................................................... 12 Figura 6. Modelo de aplicação de aplicações iPhone ............................................... 14 Figura 7. Ciclo de desenvolvimento de aplicativos iOS ............................................. 16 Figura 8. Arquitetura da plataforma Android .............................................................. 17 Figura 9. Modelo de Aplicação do Android ................................................................ 19 Figura 10. Ciclo de desenvolvimento de aplicativos Android..................................... 20 Figura 11. Processo de conversão do código fonte Objective-C para Java .............. 25 Figura 12. Implementação do UIKit no iOS2Droid..................................................... 33 Figura 13. Modelo de aplicação do iOS2Droid .......................................................... 39 Figura 14. Projeto de um Jogo da Velha ................................................................... 40 Figura 15. Emulador do iPhone com o projeto em execução .................................... 41 Figura 16. Projeto convertido pelo iOS2Droid no Eclipse .......................................... 42 Figura 17. Emulador do Android executando o projeto convertido ............................ 44 Figura 18. Aplicação Button Fun convertida pelo iOS2Droid..................................... 50 Figura 19. Aplicação Control Fun convertida pelo iOS2Droid ................................... 51 Figura 20. Aplicação View Switcher convertida pelo iOS2Droid................................ 55 Figura 21. Aplicação SoccerBall convertida pelo iOS2Droid ..................................... 57 ABREVIATURAS Sigla Significado ADT Android Development Tools ANTLR ANother Tool for Language Recognition API Application Programming Interface APK Android Package CSS Cascading Style Sheets OHA Open Handset Alliance GUI Graphical User Interface HTML HyperText Markup Language IDE Integrated Development Environment IOS iPhone Operating System MXML Macromedia Extensible Markup Language NIB NextSTEP Interface Builder SDK Software Development Kit UI User Interface WYSIWYG What You See Is What You Get XML Extensible Markup Language 1 1 INTRODUÇÃO Este capítulo apresenta uma visão geral sobre este trabalho, descrevendo as motivações, o problema a ser analisado e os objetivos a serem alcançados. Em seguida, será apresentada a justificativa e a relevância desta pesquisa, bem como as contribuições esperadas. Por fim, será detalhado como estão organizados os próximos capítulos desta dissertação. 1.1 VISÃO GERAL O aumento do poder computacional nos aparelhos celulares e a evolução das tecnologias de comunicação estão atraindo cada vez mais a atenção de diversos segmentos de mercado. Instituições bancárias, empresas de jogos, institutos de pesquisa, assim como profissionais e usuários comuns vêm se beneficiando dos recursos dos celulares inteligentes, também conhecidos como smartphones. Estes dispositivos nos permitem ir além da funcionalidade básica de um telefone celular, oferecendo dentre outras coisas, acessar a internet e e-mails, ouvir música, visualizar e editar arquivos, obter posição geográfica e utilizar sensores de movimento (MEIER, 2009). Em junho de 2007, a Apple revolucionou o mercado de smartphones ao anunciar o iPhone, aparelho com tela sensível ao toque e com apenas um botão físico (CHAURAIS e MICHELS, 2009). Esse aparelho provê diversos recursos multimídia, acesso a internet via Wi-Fi e foco direcionado na usabilidade. Ele também permite ao usuário, personalizar o telefone instalando aplicativos através de uma central de aplicações chamada de App Store que conta com mais de 200 mil aplicações (JAMES, 2010). Tentando usufruir desse nicho de mercado alavancado pelo iPhone, a Open Handset Alliance (OHA), consórcio formado por gigantes da área de telecomunicações e liderado pela Google, lançou em Novembro de 2007 uma plataforma baseada em software livre denominada Android (DIMARZIO, 2008). Diferentemente do iOS – sistema operacional do iPhone – que está presente apenas em dispositivos da Apple, o Android é distribuído sob a licença Apache 2.0, o que dá 2 o direito a qualquer fabricante de aparelhos utilizá-lo sem obrigá-lo a compartilhar com os demais fabricantes as modificações realizadas por eles para seus produtos. Isso traz o benefício da competitividade entre os fabricantes ao mesmo tempo em que estabelece uma plataforma de desenvolvimento padrão para produção de aplicativos. Apesar de serem plataformas para o mesmo propósito, iPhone e Android são completamente heterogêneas. Elas diferem tanto em termos de sistema operacional quanto de linguagem de programação para desenvolvimento de aplicações, o que impede a execução de uma aplicação iPhone em outra plataforma (PILONE e PILONE, 2009, p. 9). Desta forma, desenvolver um mesmo aplicativo para as duas plataformas requer a escrita do código fonte para cada uma, sem nenhuma possibilidade de reuso. Nesse contexto, observando a enorme quantidade de aplicações desenvolvidas para a plataforma da Apple e a crescente demanda por aplicações para a plataforma Android (GARDNER, 2010), essa dissertação apresenta uma ferramenta para realizar a conversão automática de código fonte e dos arquivos de definição de interface gráfica, reduzindo o esforço de tradução de aplicativos escritos para iPhone que necessitem ser disponibilizados para a plataforma Android. Visando com isso, diminuir o tempo e o custo do desenvolvimento deste tipo de software. 1.2 MOTIVAÇÃO Essa seção apresenta as motivações de mercado e técnicas que impulsionaram esse trabalho. 1.2.1 Motivação de Mercado De acordo com Lechetta (2009, p. 19), “estudos mostram que hoje em dia mais de 3 bilhões de pessoas possuem um aparelho celular”, e segundo Carton e Crumrine (2010) esse número tende a crescer. Isso representa um número considerável de usuários, viabilizando grandes oportunidades de negócios em vários segmentos. 3 No mercado de smartphones, diversos fabricantes disputam a preferência dos clientes, e as plataformas iPhone e Android se destacam, sendo responsáveis por quase dois terços do acesso a internet móvel no mundo. Os telefones da Apple detêm 40%, enquanto o Android ocupa o segundo lugar com 26% (AdMob, 2010a, p.10) conforme a Figura 1. Figura 1. Acessos a internet por Sistema Operacional Móveis no Mundo O crescimento nas vendas de aparelhos Android desencadeou um aumento na demanda por aplicações. Empresas que desenvolvem aplicações para iPhone, planejam desenvolver versões destes aplicativos para Android (AdMob, 2010b) de modo a acompanhar essa tendência de mercado. A Figura 2 ilustra que nos seis primeiros meses de 2010, mais da metade dos smartphones vendidos nos Estados Unidos, eram Android ou iPhone (The Nielsen Company, 2010b). Isso reforça a importância que ambas as plataformas têm no mercado de telefones móveis, demonstrando também o crescimento da plataforma do Google no último ano, enquanto que os seus concorrentes perdem espaço. 4 Figura 2. Vendas de smartphones por sistema operacional nos EUA Além dos bons resultados nas vendas, as plataformas estão atendendo as necessidades dos seus usuários. Na Figura 3 (The Nielsen Company 2010a) é apresentada uma pesquisa realizada em agosto de 2010 sobre a satisfação dos usuários em relação às plataformas de smartphones. Constatou-se que 89% dos usuários de iPhone, e 71% dos usuários de smartphones Android, desejam permanecer na mesma plataforma. 5 Figura 3. Pesquisa de satisfação dos sistemas operacionais móveis O modelo de distribuição de aplicações através de lojas virtuais atraiu a atenção de desenvolvedores em todo mundo. Segundo pesquisa feita pela Appcelerator em setembro de 2010 com mais de dois mil desenvolvedores, 91% dos desenvolvedores estão bastante interessados em desenvolver para iPhone, e 82% têm o mesmo sentimento para o Android. Esse resultado pode ser observado na Figura 4 (Appcelerator, 2010a). 6 Figura 4. Interesse dos desenvolvedores em criar aplicações para as plataformas Tendo em vista o crescimento do Android, e dado o maior número de aplicações disponíveis para a plataforma da Apple, uma ferramenta que converta uma aplicação iPhone diretamente para Android auxiliará empresas e desenvolvedores que desejam disponibilizar aplicações para a plataforma da Google. 1.2.2 Motivação Técnica Desenvolver software para dispositivos móveis é um grande desafio para os desenvolvedores, tendo em vista a variedade de modelos de aparelhos disponíveis no mercado (SAMPAIO et al. 2004). Algumas abordagens como diretivas de compilação e pré-processamento podem ser aplicadas quando se trabalha para a mesma plataforma (LEAL, FONSECA e FERRAZ, 2010). 7 Entretanto, quando os desenvolvedores têm que produzir aplicações para plataformas incompatíveis, inclusive com linguagens de programação distintas, eles podem recorrer a ferramentas de transformação como ANTLR (ANother Tool for Language Recognition. PARR, 2007). Elas podem ser utilizadas para auxiliar na conversão do código fonte de uma linguagem para outra, realizando a tradução sintática e permitindo ser programada para realizar adaptações de conceitos divergentes entre as linguagens. No caso das plataformas estudadas, os arquivos de UI também devem ser convertidos. No iPhone, esses arquivos são conhecidos por NIBs (NextSTEP Interface Builder) e são gerados a partir de uma ferramenta WYSIWYG (What You See Is What You Get). A documentação sobre a estrutura desse tipo de arquivo não está disponível para consulta, por isso os estudos sobre esse tipo de arquivo foram realizados baseados nas aplicações analisadas. Uma vez que código fonte e arquivos de UI estão convertidos, estes estarão utilizando frameworks não existentes em Android. A ferramenta proposta disponibilizará esses frameworks através de uma biblioteca escrita em Java de modo a compatibilizar a aplicação convertida. As três etapas do processo são contempladas pela ferramenta proposta, fazendo com que, uma mesma aplicação possa atender as duas plataformas móveis que estão em maior evidência no mercado atual de smartphones, desde que tenha sido produzida utilizando as ferramentas padrão de desenvolvimento para iPhone. Desta forma, o trabalho de conversão é feito de forma automatizada, visando com isso, economizar tempo, reduzir custos e minimizar a possibilidade de possíveis erros que poderiam ocorrer caso o processo fosse feito manualmente. 1.3 PROBLEMA As plataformas da Google e da Apple destacam-se no mercado de smartphones. Entretanto, desenvolver uma aplicação que execute em ambas, ou ainda converter para Android um aplicativo existente para iPhone, torna-se uma tarefa que demanda esforço devido a incompatibilidade entre elas em vários 8 aspectos. Neste contexto, pode-se identificar os seguintes problemas que dificultam a execução de uma aplicação iPhone em um dispositivo Android: Aplicativos escritos para iPhone utilizam a linguagem Objective-C, enquanto que para Android, é utilizado Java; Os arquivos de definição de UI, no Android, descrevem apenas os componentes e suas propriedades (como posicionamento e tamanho). Enquanto que, no iPhone, além da descrição dos componentes, eles também realizam a associação entre os mesmos e o código fonte, determinando qual variável está associada a que componente e qual método será chamado quando esses componentes disparam eventos; Os frameworks utilizados nos aplicativos iPhone são diferentes dos que são utilizados em aplicações Android; Os artefatos envolvidos no ciclo de vida e arquitetura das aplicações necessitam ser adaptados. 1.3.1 Objetivo geral Dado o maior número de aplicações disponíveis para iPhone em relação à plataforma Android (JAMES, 2010), esta dissertação tem como objetivo propor uma ferramenta que realize a conversão do código fonte e dos arquivos de definição de UI de uma aplicação iPhone para Android. Permitindo desta forma, que ela seja compilada e executada em dispositivos Android com menos esforço. 1.3.2 Objetivos específicos Tendo em vista que as linguagens de programação são distintas, deve-se viabilizar a conversão do código fonte escrito em Objective-C para Java. Os arquivos de definição de UI devem ser convertidos e as associações com o código fonte devem ser realizadas. O mapeamento da API (Application Programming Interface) deve ser atingido através do desenvolvimento em Java dos frameworks utilizados na aplicação para iPhone. 9 1.4 JUSTIFICATIVA Este trabalho justifica-se por sua relevância do ponto de vista prático, tendo o intuito de automatizar o processo de conversão de aplicações móveis em plataformas distintas. A ferramenta proposta age como um facilitador em um trabalho que comumente demanda bastante esforço (BARROS, 2007) e visa minimizar a quantidade de erros decorrentes de falhas na execução dos projetos de conversão (SAMPAIO et al. 2004). 1.5 CONTRIBUIÇÕES As seguintes contribuições são esperadas: Projeto e implementação de uma ferramenta que realize a conversão do código fonte de projetos iPhone para projetos Android de modo que o esforço de ajustes no código convertido não represente parte significativa no processo de desenvolvimento; Desenvolver em Java os frameworks utilizados na plataforma iPhone; Aplicação de uma ferramenta de transformação de linguagem em um contexto de aplicações para plataformas móveis. 1.6 ESTRUTURA DA DISSERTAÇÃO No capítulo 2 é apresentado o estado da arte, onde os conceitos principais deste trabalho são descritos baseados na fundamentação teórica. Nele, serão detalhados conceitos sobre computação móvel e a arquitetura e modelo de aplicação das plataformas envolvidas nesse trabalho: iOS e Android. Por fim, são apresentados os trabalhos relacionados. No capítulo 3 é explicado em detalhes o mecanismo proposto, suas características, tecnologias utilizadas e a arquitetura. Nesse capítulo é apresentado como é realizada a conversão dos arquivos de UI de um projeto iOS para Android; e do código fonte entre as linguagens Objective-C e Java. Ao final, são apresentadas restrições para utilização da ferramenta. 10 No capítulo 4 são apresentadas aplicações que foram convertidas pela ferramenta e as características que foram convertidas por ela. E finalmente no capítulo 5 são apresentadas as considerações finais e a evolução do trabalho. 11 2 COMPUTAÇÃO MÓVEL E A ARQUITETURA DAS PLATAFORMAS IOS E ANDROID Este capítulo descreve inicialmente a computação móvel, segmento no qual se encontram iOS e Android. Em seguida, são detalhadas as arquiteturas das plataformas de modo a esclarecer sua organização. Por fim, são apresentados trabalhos relacionados à ferramenta proposta. 2.1 COMPUTAÇÃO MÓVEL Este trabalho trata sobre computação móvel, em especial, em telefones celulares. De acordo com Johnson (2007, p. 20), “computação móvel é aquela que permite que os usuários tenham acesso a serviços independente de sua localização”. Esses serviços estão disponíveis em dispositivos que devem apresentar algumas características: “deve ser portátil e o usuário ser capaz de transportá-lo com relativa facilidade. [...] tem de ser altamente utilizável, funcional e permitir fácil conectividade e comunicação com outros dispositivos” (LEE; SCHNEIDER; SCHELL, 2005, p. 1). Essas características são atendidas pelos smartphones atuais. Segundo Tynan (2005), o primeiro aparelho que utilizou essa denominação foi o Simon da IBM, lançado em 1993 ele reunia funções de telefone, calculadora, agenda de endereços, calendário, fax e e-mail. O poder de processamento desse tipo de aparelho cresceu (CARTON e CRUMRINE, 2010), o custo vem diminuindo e a expansão das redes de dados está atraindo cada vez mais os usuários domésticos (ARIMA, 2010), que comumente buscam recursos como: câmeras de boa qualidade, execução de música e vídeo, ou ainda acesso a redes sociais, jogos que utilizam acelerômetro e gráficos 3D. Mas não é apenas esse tipo de usuário que está usufruindo do poder dos smartphones, os profissionais e executivos também estão cada vez mais descobrindo o poder desses dispositivos, que os permitem se manter conectados aos seus negócios, possibilitando verificar e-mail, agendar/lembrar de reuniões, ler/redigir documentos, acessar a conta bancária, ler notícias e registrar fechamento de negócios. 12 2.2 APPLE IPHONE/IOS Em 2007, visando atingir o mercado de smartphones que se encontrava em ascensão, a Apple revolucionou ao apresentar o iPhone (CHAURAIS e MICHELS, 2009), um smartphone que além das funcionalidades de telefonia, é uma plataforma para jogos, um organizador, um navegador de internet, um tocador de música e vídeo. Tudo isso aliado a uma interface simples com tela sensível ao toque. 2.2.1 Arquitetura O iOS, sistema operacional do iPhone, foi concebido a partir do Mac OS X, que por sua vez foi baseado no Unix. A plataforma é organizada em camadas como pode ser observado na Figura 5 (Chaurais e Michels, 2009, p. 28). Figura 5. Camadas do sistema operacional iOS A camada superior é um subconjunto do Cocoa, framework utilizado para criar aplicações para o OS X. É nessa camada que ficam as principais bibliotecas para a criação de aplicações como o Foundation framework e UIKit. O primeiro reúne as classes para os tipos básicos (string, inteiro, ponto flutuante, booleano, etc.), coleções, threads, etc. O UIKit dispõe os componentes para criação da interface gráfica. 13 Na camada Media ficam as bibliotecas para tratamento áudio e vídeo. Uma importante parte dessa camada são as bibliotecas Quartz e OpenGL ES que permitem desenhar na tela através de gráficos e imagens 2D e 3D. A camada Core Services disponibiliza diversos serviços importantes, normalmente escritos em C, como: persistência de dados, localização, acesso à rede, segurança, etc. A camada inferior, Core OS, contém os drivers do aparelho, o kernel do sistema operacional e serviços de mais baixo nível. Brannan (2010), entretanto, resume essa separação da plataforma em duas camadas: Cocoa Touch e C. Essa abordagem pode ser utilizada, uma vez que as aplicações desenvolvidas utilizam apenas a camada superior, e ela por sua vez provê acesso para as camadas inferiores. 2.2.2 Ferramentas As aplicações desenvolvidas para iPhone são escritas em Objective-C, uma linguagem orientada a objetos que faz uma junção da linguagem C ao estilo do Smalltalk. A Apple disponibiliza um SDK (Software Development Kit) para Mac OS X que é composto de uma biblioteca de classes, um IDE denominado Xcode, um compilador para a linguagem Objective-C e um simulador onde o desenvolvedor pode testar a execução dos aplicativos. O Xcode permite escrever o código fonte da aplicação, que normalmente estão em arquivos com a extensão *.h para os arquivos de cabeçalho, e *.m para os arquivos de implementação. A criação da interface gráfica é feita através do Interface Builder, que também vem com o SDK. Essa ferramenta conta com um editor WYSIWYG, que permite ao desenvolvedor compor as telas da aplicação arrastando e posicionando componentes. Os arquivos gerados pelo Interface Builder são chamados de NIB, porém contém a extensão *.xib. Esses arquivos são escritos no formato XML (Extensible Markup Language), e além de descrever os componentes, também descrevem os eventos que são disparados por eles e os interliga aos métodos que responderão a esses eventos. Esses arquivos normalmente não são alterados manualmente pelo desenvolvedor, apenas através dos editores do Interface Builder. 14 2.2.3 Modelo de Aplicação O fluxo de uma aplicação iPhone representado pela Figura 6, envolve diversos elementos. O programa inicia a partir de um arquivo que tenha a função main. Esse arquivo tem basicamente o objetivo de instanciar um objeto da classe UIApplication, que representa a aplicação em si. Essa classe, por sua vez, carrega um arquivo XML que tem a terminação Info.plist e que contém um elemento que descreve o NIB principal do projeto. Figura 6. Modelo de aplicação de aplicações iPhone O desenvolvedor normalmente não utiliza o objeto UIApplication, ao invés disso, ele utiliza uma classe que implementa o protocolo UIApplicationDelegate. O framework Cocoa Touch, captura os eventos do sistema e os repassa para o objeto UIApplication que por sua vez delega essas ações para o delegate implementado pelo desenvolvedor. Diversos eventos do ciclo de vida de uma aplicação podem opcionalmente ser tratados, tais como: pausa da aplicação quando do recebimento de uma chamada de voz ou um alarme; aviso de pouca memória disponível; mudança de orientação da tela (do modo retrato para paisagem e vice-versa). O método que detecta o fim do carregamento da aplicação deve ser obrigatoriamente implementado (BRANNAN, 2010, p.119). 15 O objeto UIApplication carrega o NIB principal da aplicação, que contém três objetos principais: UIApplication, UIWindow e um objeto que representa o UIApplicationDelegate implementado pelo desenvolvedor. O primeiro representa o objeto UIApplication, enquanto que o segundo representa o display do dispositivo onde serão exibidas as telas da aplicação. O delegate é associado ao objeto UIApplication pelo atributo de mesmo nome, e o objeto UIWindow é interligado ao delegate pelo atributo window, sendo este definido pelo desenvolvedor. As telas da aplicação são representadas por subclasses de UIView, que podem ser criadas via código, mas são comumente elaboradas através de arquivos NIB criados no Interface Builder. Para realizar o tratamento de eventos, bem como referenciar os Outlets – referência em código dos componentes visuais descritos no NIB – utiliza-se uma subclasse de UIViewController. A partir desse ponto, a aplicação pode definir diversas UIViews com UIViewControllers associados. 2.2.4 Ciclo de Desenvolvimento Após o término do desenvolvimento, uma aplicação pode ser disponibilizada para os usuários de todo o mundo através da App Store1, loja virtual da Apple. Ela disponibiliza aos usuários mais de 200.000 aplicações (JAMES, 2010) e os preços dos aplicativos são estabelecidos pelo desenvolvedor. Antes de incluir sua aplicação na loja, ele deverá registrar-se e pagar por uma licença. Feito isso, ele deve obter um certificado digital para assinar a aplicação, para enfim submetê-la. O Ciclo de desenvolvimento de um aplicativo iPhone é ilustrado pela Figura 7. 1 http://www.apple.com/iphone/apps-for-iphone/ 16 Figura 7. Ciclo de desenvolvimento de aplicativos iOS 2.3 GOOGLE ANDROID Com o sucesso do smartphone da Apple (BRANNAN, 2010), surgiu a oportunidade de desenvolver uma plataforma aberta para concorrer com o iPhone. Nasceu então a OHA, que tinha por objetivo “criar uma plataforma aberta, única, moderna e flexível para celulares que permita o desenvolvimento de aplicações corporativas e para uso pessoal” (LECHETTA , 2009, p. 21). Como resultado dessa iniciativa, surgiu o Android, uma plataforma completa de software que pode executar em qualquer aparelho que atenda seus requisitos mínimos (Android Compatibility Definition, 2010). O primeiro telefone a utilizá-lo foi o G1/Dream fabricado pela HTC Corporation e liberado em outubro de 2008. Desde então, outros fabricantes adotaram o Android como sistema operacional nos seus produtos. 17 2.3.1 Arquitetura Segundo Meier (2009, p. 12), a plataforma apresentada na Figura 8 é representada por uma pilha de software. No topo, estão localizadas todas as aplicações instaladas no dispositivo, o Android não faz distinção entre aplicações nativas e de terceiros. Um nível abaixo se encontra o Application Framework, que disponibiliza bibliotecas necessárias para a criação de aplicações como a de interface gráfica, localização, comunicação e acesso a recursos. As Libraries são bibliotecas desenvolvidas em C e C++ que rodam sobre o sistema operacional e provêm serviços de mais baixo nível à camada superior. No mesmo nível, fica o Android Runtime, que é composto da máquina virtual Dalvik e das bibliotecas Java padrão. Na parte inferior, fica o kernel do Linux, onde ficam os drivers do dispositivo e também onde é feito o gerenciamento de processos e controle de energia. Figura 8. Arquitetura da plataforma Android 18 Para criar as aplicações, os desenvolvedores utilizam apenas o Application Framework e as Android Libraries. 2.3.2 Ferramentas O Google disponibiliza um SDK que viabiliza o desenvolvimento de aplicativos. Ele contém as bibliotecas, simulador, plugin ADT (Android Development Tools) para integração do SDK com o Eclipse, e diversas outras ferramentas para auxiliar o desenvolvimento. Todas essas ferramentas estão disponíveis para Microsoft Windows, Mac OS X ou Linux. O código fonte é escrito em Java e a interface gráfica é elaborada através de um arquivo XML. O IDE de desenvolvimento padrão é o Eclipse, disponível para qualquer um dos sistemas operacionais citados acima. O XML que define a interface gráfica pode ser criado através de um editor WYSIWYG disponível no ADT. Freqüentemente esse arquivo é alterado manualmente pelo desenvolvedor, e contem apenas as informações dos componentes da interface gráfica – como posicionamento e tamanho – enquanto que o código a ser executado em resposta a eventos são associados no código Java. 2.3.3 Modelo de Aplicação O modelo de aplicação do Android apresentado na Figura 9 envolve a utilização de menos artefatos que o do iPhone. Ao iniciar a execução da aplicação, o sistema operacional consulta em um arquivo de configuração, chamado AndroidManifest.xml, qual Activity deve ser inicializada. Cada atividade representa uma tela da aplicação, e todas devem estar registradas nesse arquivo. A Activity, faz papel semelhante ao UIViewController do iPhone, tratando os eventos da interface e referenciando os elementos visuais da tela. Esses elementos podem ser criados no próprio programa ou definidos em arquivos XML. Diferentemente do iPhone, os métodos para tratamento dos eventos, assim como as associações entre os componentes definidos no XML e o código fonte, não podem ser feitas diretamente no XML. Isso deve ser implementado pelo desenvolvedor através de uma ligação estabelecida no programa. 19 O modelo de atividades adotado pelo Android permite que qualquer tela de uma aplicação possa ser chamada por outra aplicação, proporcionando a integração dos aplicativos e ajudando a promover o reuso. Figura 9. Modelo de Aplicação do Android 2.3.4 Ciclo de Desenvolvimento Semelhante à loja da Apple, a Google criou o Android Market, local onde os desenvolvedores podem publicar suas aplicações e os usuários podem fazer download desses aplicativos para o seu aparelho. Para submeter aplicações para o Android Market, os desenvolvedores devem registrar-se e pagar uma taxa. Em seguida, devem obter o certificado para assinar digitalmente seus aplicativos. O Ciclo de desenvolvimento de uma aplicação Android é mostrado na Figura 10. 20 Figura 10. Ciclo de desenvolvimento de aplicativos Android 2.4 TRABALHOS RELACIONADOS Segundo Pilone (2009, p. 9) não é possível executar uma aplicação iPhone em outra plataforma, pois “quando desenvolvemos para iPhone, utilizamos frameworks como Cocoa Touch e também Objective-C. E ambos não estão disponíveis em outros dispositivos”. Entretanto, já observamos no mercado algumas ferramentas que tentam compatibilizar aplicativos dentre diferentes plataformas de smartphones, dentre elas, iPhone e Android. Um breve resumo sobre algumas delas está descrita nas subseções a seguir. 2.4.1 XMLVM Em trabalho realizado por Puder (2005), foi criada uma ferramenta chamada XMLVM que converte bytecodes gerados pelo compilador Java ou códigos intermediários (CIL) da tecnologia .net da Microsoft em um documento XML. A partir desse documento é possível fazer a tradução para vários formatos, entre eles o 21 Objective-C do iPhone. Essa ferramenta já se encontra em estado avançado, permitindo inclusive converter para iPhone, jogos publicados no Android Market. Para atingir esse objetivo, o desenvolvedor tem que escrever a aplicação utilizando as ferramentas de desenvolvimento do Android e a API do iPhone, que foi portada pelo autor para Java. 2.4.2 Titanium Mobile O Titanium Mobile permite a geração de uma mesma aplicação para Android e iPhone com a escrita de apenas um código fonte. Essa ferramenta está disponível nas versões Community e Professional, onde a primeira é gratuita com funcionalidade reduzida e a segunda é paga. As aplicações desenvolvidas são escritas utilizando HTML (HyperText Markup Language), CSS (Cascading Style Sheets) e JavaScript e uma API proprietária que tenta atingir as duas plataformas (ALLEN, GRAUPERA e LUNDRIGAN, 2010). 2.4.3 PhoneGap O PhoneGap é uma ferramenta de código aberto, que age como uma ponte entre aplicações web e dispositivos móveis. O desenvolvedor utiliza HTML, CSS e JavaScript para criar as aplicações, e a partir desse código ele pode ter acesso a recursos do aparelho como câmera, acelerômetro e localização (STARK, 2010). Isso é feito através das APIs e de um projeto modelo disponibilizado pela ferramenta. 2.4.4 Adobe AIR O Adobe Air traz os recursos do Adobe Flash para os dispositivos móveis. Com essa ferramenta é possível criar aplicações utilizando a linguagem Action Script e executá-las fora de um navegador de internet tanto em dispositivos Android (a partir da versão 2.2) quanto no iPhone (ALLEN, GRAUPERA e LUNDRIGAN, 2010). 2.4.5 ELIPS Studio ELIPS Studio é um SDK para criação de aplicações móveis multi-plataforma baseado no Adobe Flex Builder. As aplicações são criadas utilizando a linguagem 22 ActionScript e MXML (Macromedia Extensible Markup Language), esse código fonte passa pelo compilador da ferramenta que compila a aplicação para a plataforma de destino. 2.4.6 Comparativo As ferramentas existentes apresentam diversas vantagens: elas aproveitam o know-how dos desenvolvedores de aplicações web, uma vez que utiliza recursos amplamente utilizados por eles como: HTML, JavaScript, CSS e ActionScript; elas convertem as aplicações para até mais de duas plataformas; e uma vez que encontram-se no mercado a um certo tempo – algumas inclusive com versões comerciais – elas já se encontram bastante estáveis. Diferentemente dos trabalhos citados anteriormente, a ferramenta proposta utiliza o código fonte e a API nativa da plataforma iPhone para converter o aplicativo para Android. Dessa forma, o desenvolvedor vai escrever a aplicação normalmente para iPhone e a ferramenta converterá o código fonte para Android. Sendo assim, desenvolvedores que criam aplicativos para iOS, podem continuar utilizando o ambiente ao qual já estão adaptados sem a necessidade de aprender uma outra linguagem ou framework. Outro ponto importante da ferramenta proposta é a utilização do código fonte existente para iPhone, permitindo que tanto novas aplicações quanto aplicativos legados sejam portados para Android com esforço reduzido. 2.5 CONCLUSÕES Como podemos observar a computação móvel evoluiu bastante nos últimos anos, e parte desse crescimento deve-se ao smartphones e aos softwares que executam nesses aparelhos. As plataformas iOS e Android, apresentam uma arquitetura bem semelhante, uma vez que ambas surgiram da plataforma Unix. Sobre o kernel do sistema operacional rodam bibliotecas de mais baixo nível que provêm serviços para as camadas superiores. 23 Outra similaridade entre as plataformas é o modelo de distribuição de aplicativos através de uma loja virtual. Esse modelo auxilia tanto os desenvolvedores – que desejam publicar e até faturar com seus aplicativos – quanto usuários, que podem baixar aplicativos confiáveis em um local padrão. Entretanto, ambiente de desenvolvimento, a linguagem de programação, modelo de aplicação e as APIs são completamente diferentes. Isso inviabiliza com que uma aplicação execute em ambas as plataformas. Sendo assim, a demanda por ferramentas que auxiliem no processo de conversão de uma plataforma para outras é cada vez maior. No mercado já existem algumas ferramentas que auxiliam nesse processo. Porém, elas se aplicam apenas para novas aplicações. A ferramenta proposta que será detalhada no próximo capítulo auxilia também na conversão de aplicativos existentes de iPhone para Android. 24 3 SOLUÇÃO PROPOSTA – IOS2DROID O iOS2Droid é a ferramenta proposta para realizar a conversão para Android de aplicações desenvolvidas para iPhone. Este trabalho é realizado em três etapas: primeiramente os arquivos de código fonte, com extensão *.h e *.m são convertidos para arquivos com extensão *.java; em seguida, os NIB‟s que têm extensão *.xib são convertidos para arquivos XML que definem a interface gráfica no Android; e por fim é feito o mapeamento das APIs de desenvolvimento. Nesse capítulo, as três etapas são detalhadas. Em seguida é apresentado um exemplo de um projeto convertido pela ferramenta, e ao final são apresentadas as restrições atuais da ferramenta. 3.1 CONVERSÃO DO CÓDIGO FONTE A conversão do código fonte utiliza o ANTLR (Another Tool for Language Recognition), uma ferramenta que “é um gerador de parser que automatiza a construção de reconhecedores de linguagens” (PARR, 2007, p.15). O processo de tradução interpreta cada sentença de uma linguagem para geração do código fonte da linguagem destino. Isso é feito em duas etapas: a análise léxica e a conversão. A primeira faz uma análise sintática no código fonte para avaliar se está dentro dos padrões da linguagem estabelecidos por um arquivo de gramática. A segunda etapa, chamada de parsing, recebe os símbolos gerados pelo lexer e gera uma saída. O ANTLR gera o lexer e o parser automaticamente a partir do arquivo de gramática, o trabalho do iOS2Droid é converter os símbolos gerados pelo parser e traduzir em código fonte Java. O ANTLR permite que sejam adicionados alguns trechos de código à gramática, tornando o parser gerado pela ferramenta, um tradutor. O código adicionado à gramática chama classes do iOS2Droid que realizam a interpretação de cada elemento do código e o converte para o padrão da linguagem Java. O esquema é apresentado na Figura 11. Os arquivos de cabeçalho de código fonte, com extensão *.h, são traduzidos primeiro. Esse tipo de arquivo “descreve a interface para as classes do seu projeto” (PILONE e PILONE, 2009, p.11), contendo informações como o nome da classe, da 25 super classe, os protocolos implementados, propriedades e assinaturas de métodos. Em seguida são convertidos os arquivos de implementação, com extensão *.m. São eles que implementam os métodos declarados nos arquivos de cabeçalho. Para ambos os tipos, o processo de conversão adotado é o mesmo. Figura 11. Processo de conversão do código fonte Objective-C para Java 3.1.1 Objective-C e Java Objective-C é a linguagem de programação padrão utilizada para escrever aplicativos para Mac OS e iOS. Ela adiciona o conceito de objetos à linguagem C padrão e utiliza a sintaxe de métodos do SmallTalk (DALRYMPLE e KNASTER, 2009). Diferentemente de outras linguagens, ela não cria toda uma nova linguagem, ela é um super conjunto do C padrão (BUCANEK, 2009). 26 Lançada em 1996 pela Sun, “Java é uma plataforma inteira, com uma enorme biblioteca, com um monte de código reutilizável, e um ambiente de execução que provê serviços como segurança, portabilidade entre sistemas operacionais, e coleta de lixo automática” (HORSTMANN e CORNELL, 2008, p.2). A plataforma Android, além da linguagem, utiliza a biblioteca padrão e conceitos da máquina virtual da tecnologia Java. A abordagem utilizada pelo iOS2Droid para solucionar divergências entre as linguagens e compatibilizar o código convertido foi: mapear as APIs do Cocoa Touch através de uma biblioteca de classes escritas em Java; e realizar adaptações no código fonte durante o processo de conversão. Nas próximas subseções será explicado como esse mapeamento foi realizado. 3.1.2 Estrutura de Classes As classes em Objective-C são definidas em dois arquivos, sendo um de cabeçalho e outro de implementação. Em Java, as classes têm de ser definidas em um mesmo arquivo de código fonte. // Em Objective-C // Pessoa.h #import <Foundation/Foundation.h> @interface Pessoa : NSObject { NSString* nome; } @property (retain, nonatomic) NSString *nome; - (void) falar:(NSString *fala); @end // Pessoa.m #import "Pessoa.h" @implementation Pessoa @synthesize nome; 27 - (void) falar:(NSString *fala){ NSLog(fala); } @end // Em Java // Pessoa.Java public class Pessoa extends NSObject { private NSString nome; public NSString getNome(){ return nome; } public NSString setNome(NSString nome){ return this.nome = nome; } public void falar(NSString fala){ NSLog(fala); } } No arquivo com extensão *.h é definida a estrutura da classe, especificando atributos, propriedades e assinaturas de métodos, enquanto que no arquivo *.m ficam as implementações dos métodos da classe. 3.1.3 Alocação de memória Assim como no Java, o Objective-C 2.0 conta com o conceito de garbage collector para gerenciamento de memória. Porém, esse recurso não está disponível para o iOS. Dessa forma, o desenvolvedor tem que realizar a alocação e liberação de memória manualmente (MARK e LAMARCHE, 2009, p.8). // Em Objective-C Carro *carro = [[Carro alloc] init]; [carro release]; // Em Java Carro carro = new Carro().init(); carro.release(); 28 No código acima é feita a alocação de memória através do método alloc, em seguida é chamado o método init. Como o nome sugere, o primeiro alocará memória para o objeto, enquanto que o segundo fará as inicializações necessárias. O método init é utilizado em Objective-C, pois ele não conta com o conceito de construtores. Isso foi traduzido pelo iOS2Droid através de uma chamada para o construtor padrão da classe, utilizando a palavra reservada new seguido por uma chamada ao método init. Objective-C utiliza contadores de referência para determinar se a memória deve ser liberada ou retida. Quando o método alloc é chamado, esse contador é incrementado em um. O método release por sua vez, decrementa o contador em um. Quando o contador de referências alcança o valor zero, o próprio sistema operacional chama o método dealloc que liberará a memória alocada para aquele objeto (BRANNAN, 2010, p.54). Em Java, e conseqüentemente em Android, os desenvolvedores não precisam se preocupar com esse tipo de trabalho, uma vez que a liberação de memória é feita automaticamente pelo garbage collector (HORSTMANN e CORNELL, 2008, p.55). 3.1.4 Propriedades Uma diferença impactante na conversão do código fonte foi o conceito de propriedades existente em Objective-C. Antes desse tipo de estrutura ser adicionada à linguagem, programadores comumente adicionavam um par de métodos chamados de assessores e modificadores, bem conhecidos pelos programadores Java como gets e sets (MARK e LAMARCHE, 2009, p.37). - (id) nome { return nome; } - (void) setNome: (id) aNome { if (aNome != nome) { [aNome retain]; [nome release]; nome = aNome; 29 } } Essa abordagem ainda é perfeitamente válida, no entanto se esses métodos só fazem recuperar e definir o valor de um atributo, o desenvolvedor pode definir uma propriedade. Para tal, é definido no arquivo de cabeçalho através da diretiva @property e no arquivo de implementação chama-se a diretiva @synthesize para que o framework gere os métodos assessores automaticamente. // Carro.h #import <Foundation/Foundation.h> @interface Carro : NSObject { NSString* marca; NSString* modelo; NSInteger ano; } @property (retain, nonatomic) NSString *marca; @property (retain, nonatomic) NSString *modelo; @property NSInteger ano; @end // Carro.m #import "Carro.h" @implementation Carro @synthesize marca, modelo; @synthesize ano; @end Dessa forma, o desenvolvedor pode atribuir e recuperar os valores da propriedade pelo seu nome, e internamente essa chamada será direcionada para o método assessor correspondente. O conceito de propriedades não existe na linguagem Java. Para acessar atributos de um objeto de uma classe, utilizamos diretamente os métodos de acesso públicos (SIERRA e BATES, 2008, p.31). 30 // Em Objective-C carro.ano = 2010; // Em Java carro.setAno(2010); Dessa forma, o iOS2Droid teve que tratar essa diferença chamando métodos get e set quando propriedades forem utilizadas. Porém, isso gerou efeitos colaterais que também tiveram de ser tratados. Um exemplo foi o pré-incremento e pósincremento de propriedades. // Em Objective-C int x = ++carro.ano; // Em Java int x = carro.setAno(carro.getAno()+1); O caso do pré-incremento é convertido da forma acima, onde se a propriedade ano do objeto carro for igual a 2010, a variável x receberá o valor 2011. Isso porque, o método setAno(int) retorna o valor atual do atributo da classe. No entanto, no caso do pós-incremento, o mesmo código foi convertido como: // Em Objective-C int x = carro.ano++; // Em Java int x = posinc(carro.setAno(carro.getAno()+1)); Nesse caso o incremento será realizado, mas o método posinc retornará o valor antes do incremento. 3.1.5 Classes e tipos de dados O Foundation Framework e o Core Graphics provêm algumas classes semelhantes às existentes em Java. A classe java.lang.String, que representa uma seqüência de caracteres, é um exemplo típico. No framework Cocoa Touch essa função é realizada pela classe NSString. Essa classe foi implementada no iOS2Droid de modo a compatibilizar os métodos de criação e manipulação de strings definidos nessa classe. Entretanto, como a classe java.lang.String não pode ter subclasses, foi 31 criado um método chamado str que converte um objeto da classe java.lang.String para NSString. // Em Objective-C NSString *nome = @”Nelson”; NSInteger idade = 26; BOOL casado = YES; CGFloat altura = 1.75; // Em Java NSString nome = str(“Nelson”); int idade = 26; boolean casado = true; float altura = 1.75; NSInteger e CGFloat representam um inteiro e um ponto flutuante respectivamente, e foram simplesmente convertidas para int e float, uma vez que são apenas atalhos para esses tipos de dados primitivos (typedef). Para o tipo BOOL, que representa valores booleanos, ele foi convertido para o tipo boolean de Java e os valores que podem assumir os valores YES ou NO foram convertidos para true e false respectivamente. 3.1.6 Assinaturas e chamadas de métodos Objective-C utiliza uma notação chamada infix (DALRYMPLE e KNASTER, 2009, p.46), onde o nome do método e seus argumentos são todos interligados. // Em Objective-C - (void) sayHello: (NSString*)name andLastName:(NSString *)lastName { } // Em Java void sayHelloAndLastName(NSString name, NSString lastName) { } O sinal de subtração indica que é um método de instância. Métodos de classe, ou estáticos como são chamados em Java, utilizam o sinal de adição. O tipo de retorno está logo em seguida entre parêntesis. O símbolo de dois pontos separa o nome do método da lista de parâmetros e também separa cada parâmetro. É 32 possível observar que logo após o parâmetro name existe o termo andLastName. Essas palavras que ficam entre os parâmetros fazem parte da assinatura do método e servem para facilitar o entendimento ao se chamar o método. // Em Objective-C [meuObj sayHello:@”Nelson” andLastName:@”Glauber”]; // Em Java meuObj.sayHelloAndLastName(“Nelson”, “Glauber”); Pode-se observar que no código escrito em Java não é possível saber o significado do valor “Glauber”, enquanto que em Objective-C presume-se que se trata do último nome da pessoa. Dessa forma, por fazerem parte da assinatura do método, o iOS2Droid ao converter assinatura dos métodos, bem como chamadas a eles, adicionou os termos existentes entre os parâmetros ao nome do método. 3.1.7 Diretiva de compilação #define Desenvolvedores podem utilizar a diretiva #define para declarar constantes. Essas diretivas, quando declaradas em um arquivo de cabeçalho de uma classe, são traduzidas para constantes estáticas em Java. // Em Objective-C #define kShowSegmentIndex 0 #define PI 3.14 // Em Java public static final int kShowSegmentIndex = 0; public static final double PI = 3.14; 3.2 CONVERSÃO DO ARQUIVO DE DEFINIÇÃO DA UI Para a realização dos testes deste trabalho, as bibliotecas utilizadas pelo código de origem tiveram de ser implementadas em Java no iOS2Droid. Isso é essencial para permitir que o código convertido possa executar e apresentar o 33 mesmo comportamento da aplicação original. Nessa seção é apresentado o mapeamento das classes dos componentes visuais do UIKit (Apple, 2010) convertidas para atender esse experimento. Os componentes implementados utilizam composição (MCLAUGHLIN, POLLICE e WEST, 2007, p.408) para adaptar a hierarquia de classes do iPhone ao framework de UI do Android. Para alcançar esse objetivo, a classe UIView, que é a classe mais genérica dos componentes visuais do iPhone, tem um atributo que referencia um objeto da classe android.view.View que tem o mesmo propósito no Android. Essa implementação está apresentada na Figura 12. Figura 12. Implementação do UIKit no iOS2Droid Internamente, cada classe filha de UIView contém uma inner class que herda de android.view.View e que realmente implementa o comportamento do componente. São elas também que são referenciadas no arquivo de definição de UI que é convertido a partir do NIB da aplicação iPhone. O mapeamento das classes do UIKit com as respectivas inner classes são apresentadas nas Tabela 1. 34 Componente iOS Componente Android Modificação do iOS2Droid UILabel UITextView Nenhuma UITextField EditText Nenhuma UIButton Button Ajustes para permitir definir a área dimensionável sem utilizar o formato 9.png. UISwitch ToggleButton Mudança visual UISlider SeekBar Mudança visual UIView AbsoluteLayout Nenhuma UIToolbar Nenhum Foi utilizado um LinearLayout que adiciona UIBarButtomItem‟s. UIBarButtonItem Button Mudança Visual UIImage ImageView O componente teve que prover suporte ao redimensionamento de imagens sem usar o formato 9-patch utilizado no Android. 35 UISegmentedControl Nenhum Foi utilizado um LinearLayout que cria um TextView para cada segmento. Tabela 1. Mapeamento dos componentes visuais 3.2.1 Conversão dos Arquivos de UI Os arquivos de definição de interface gráfica do iPhone, chamados de NIB, têm extensão *.xib, no entanto têm o formato XML. Eles são gerados automaticamente pelo Interface Builder, à medida que o desenvolvedor cria a interface gráfica em tempo de desenvolvimento. Por ser uma plataforma fechada e por ser raramente modificada manualmente pelo desenvolvedor, a documentação sobre a formatação desse arquivo é escassa. Aliada a incompatibilidade com o arquivo de definição de UI do Android, o processo de conversão desse arquivo foi realizado tomando por base algumas amostras de arquivos de aplicações utilizadas no referencial teórico desse trabalho. O processo consta inicialmente da geração de uma árvore de objetos que reflete os componentes descritos no NIB. Cada objeto armazena uma série de informações necessárias para gerar o arquivo de UI do Android, como o nome do outlet, que é a referência no código fonte, de um componente visual descrito no NIB, e os eventos associados a esses componentes. Essas associações, no Android, são feitas no código fonte e não no arquivo de descrição da UI como é feito no iPhone. Sendo assim, a ferramenta de tradução tem que gerar essa ligação no código fonte. Uma vez que a árvore de objetos foi gerada, é feita uma checagem com cada nó, de modo a gerar o arquivo XML de UI do Android. Após essa etapa, o iOS2Droid abre o arquivo Java, contendo a classe já convertida. Nele serão feitas as associações de atributos da classe para referências a elemento de UI definidos no XML. Depois são associados os eventos desses componentes que chamam métodos definidos na classe. 36 No código abaixo é apresentada a definição de uma classe que representa uma tela que contém uma caixa de texto chamada editNome e uma área de texto chamada statusText. Nessa classe, é definido um método que será disparado quando o usuário pressionar o botão, esse método associará o conteúdo da caixa de texto para a área de texto. // Em Objective-C // Tela1ViewController.h #import <UIKit/UIKit.h> @interface Tela1ViewController : UIViewController { IBOutlet UITextField *editNome; IBOutlet UILabel *statusText; } @property (retain, nonatomic) UITextField *editNome; @property (retain, nonatomic) UILabel *statusText; - (IBAction) buttonPressed; @end // Tela1ViewController.m #import "Tela1ViewController.h" @implementation Tela1ViewController @synthesize statusText, editNome; - (IBAction) buttonPressed { statusText.text = editNome.text; } - (void)dealloc { [statusText release]; [editNome release]; [super dealloc]; } @end É possível observar que não há nenhuma associação no código entre o componente visual e o código fonte. Isso porque essa ligação é feita no Interface Builder e armazenada no NIB. Para que o Interface Builder possa realizar essas ligações, os componentes que devem ser interligados devem ter a declaração 37 IBOutlet antes do nome da classe. Os métodos por sua vez, para serem identificados pelo Interface Builder têm que ter IBAction como tipo de retorno. O código abaixo mostra o código convertido para Android pelo iOS2Droid. É possível notar que os atributos que representam os componentes são associados no construtor da tela. Outro detalhe é que precisamos associar o evento ao botão, e para tanto, precisamos obter a referência ao componente definido no XML pelo identificador. O iOS2Droid gera um identificador para cada componente descrito no NIB caso ele não tenha. No código abaixo, o identificador „outlet4689’ representa o botão definido no XML. Esse identificador foi gerado pela ferramenta para que seja possível obter a referência ao componente. Feito isso, é possível associar os eventos ao botão. //Em Java public class Tela1ViewController extends UIViewController { private UITextField editNome; private UILabel statusText; public UILabel setStatusText(UILabel _statusText) { this.statusText = _statusText; return this.statusText; } public UILabel getStatusText() { return this.statusText; } public Cap03_ButtonFunViewController() { Context _ctx = MainActivity.getContext(); LayoutInflater inflater = (LayoutInflater) _ctx. getSystemService( Context.LAYOUT_INFLATER_SERVICE); android.view.View _view = inflater.inflate( R.layout.cap03_buttonfunviewcontroller, null); this.setView(new UIView((UIView.View) _view.findViewById(R.id.view))); this.statusText = new UILabel((UILabel.View) _view.findViewById(R.id.statusText)); this.editNome = new UILabel((UILabel.View) _view.findViewById(R.id.editNome)); 38 final UIButton outlet4689 = new UIButton( (UIButton.View)_view. findViewById(R.id.outlet4689)); outlet4689.getView().setOnClickListener( new android.view.View.OnClickListener() { public void onClick(android.view.View v) { buttonPressed(outlet4689); } }); } public void buttonPressed(id sender) { statusText(editNome.getText()); } public void dealloc() { editNome.release(); statusText.release(); super.dealloc(); } } A classe LayoutInflater do Android é responsável por carregar arquivos de definição de UI. Ao inflar o arquivo, é retornada uma árvore de componentes através de um objeto da classe android.view.View. E por meio do método findViewById é obtido cada nó dessa árvore que é utilizado para criar os objetos das classes de UI do iOS2Droid. 3.3 MODELO DE APLICAÇÃO A Figura 13 apresenta como o iOS2Droid adapta o ciclo de vida de uma aplicação iPhone para Android. Isso é feito através de uma Activty disponibilizada pela biblioteca da ferramenta. E como exigido pelo Android, esta atividade é declarada no arquivo AndroidManifest.xml que também é gerado pela ferramenta. 39 Figura 13. Modelo de aplicação do iOS2Droid No processo de conversão, o iOS2Droid alimenta uma lista em memória com as classes que foram convertidas, e após esse processo, é gerado um arquivo de configuração que contém o nome do pacote da aplicação e o nome da classe que implementa a interface UIApplicatonDelegate. Ao iniciar a atividade, esse arquivo de configuração será lido e uma instância da classe que implementa UIApplicationDelegate será criada. Daí em diante, o processo seguirá como uma aplicação iPhone comum. A diferença é que os eventos do sistema serão delegados pela Activity da ferramenta para as classes do iPhone. 3.4 EXECUÇÃO DA APLICAÇÃO CONVERTIDA Nesta seção é exibida a estrutura de um projeto Xcode e como essa estrutura fica disposta no Eclipse após ser convertida pelo iOS2Droid. A Figura 14 apresenta um projeto de um “Jogo da Velha” escrito para iPhone. 40 Figura 14. Projeto de um Jogo da Velha No diretório Classes ficarão os arquivos de código fonte Objective-C. Eles utilizam um padrão similar à linguagem C, onde para cada classe existe um arquivo de cabeçalho (header) e outro de implementação. Os arquivos de cabeçalho têm extensão *.h e servem pra definir a própria classe (sua herança e implementações), bem como suas respectivas propriedades e métodos. A implementação desses métodos ficam no arquivo de implementação que tem a extensão *.m. No diretório Other Sources ficam os arquivos main.m, que inicializa a aplicação, e o arquivo *.pch (Pre-Compiled Header). Esse último é uma lista compilada de arquivos de cabeçalhos dos frameworks utilizados no nosso projeto. O XCode faz esse trabalho para otimizar o processo de compilação da aplicação. O diretório Resources armazena os arquivos de definição de interface e o arquivo TicTacToe-Info.plist, que contém informações sobre a aplicação como o ícone da aplicação e o NIB principal da aplicação, similar ao AndroidManifest.xml. 41 No diretório Frameworks ficam as bibliotecas externas utilizadas pela aplicação e no diretório Products ficará o executável da aplicação com a extensão *.app, sendo este gerado quando o projeto é compilado. É importante frisar que a estrutura de diretórios, assim como a disposição dos arquivos dentro do projeto não é obrigatória. Inclusive, é possível observar no diretório onde o projeto foi salvo, que alguns diretórios (como Resources) não existem fisicamente, ou seja, essa organização é apenas interna no Xcode. O SDK do iPhone disponibiliza um emulador que permite a execução do projeto diminuindo a necessidade de um dispositivo real. A Figura 15 mostra o emulador do iPhone executando o projeto do jogo descrito acima. Figura 15. Emulador do iPhone com o projeto em execução Após realizar a conversão da aplicação, o projeto Android terá uma estrutura semelhante à Figura 16. O diretório src armazenará os arquivos *.java da aplicação. 42 Observe que nesse diretório existe um pacote Java criado pelo tradutor, mesmo quando este conceito não existe no Objective-C. Esse nome de pacote identificará unicamente a aplicação dentro do dispositivo, e por exigência do Android, deve ter no mínimo dois identificadores (por exemplo, ngvl.android). Adicionalmente, as classes da biblioteca do iOS2Droid também encontram-se nesse diretório. Figura 16. Projeto convertido pelo iOS2Droid no Eclipse Na pasta res ficam armazenados os recursos da aplicação. Visando uma melhor organização desses arquivos, a ferramenta de tradução distribui os arquivos em subdiretórios: em drawable ficam as imagens utilizadas na aplicação; no subdiretório layout ficam os arquivos XML que definem as telas da aplicação; e em values são armazenados arquivos XML contendo textos utilizados na aplicação (facilitando a internacionalização), bem como definições de cores, temas e estilos personalizados. 43 A pasta gen contém arquivos Java que são gerados pelo plugin do Android. O mais importante deles é o arquivo R.java. Ele é atualizado automaticamente pelo plugin do Android cada vez que algum recurso é adicionado, removido ou atualizado dentro do projeto. Para facilitar o acesso aos recursos pelos demais arquivos do projeto é feito um mapeamento desses recursos em constantes do tipo inteiro que estão em classes internas à classe R. Ao abrir o arquivo R.java é possível observar dentro da classe R, a classe interna drawable, que tem uma constante chamada icon. Essa constante foi definida ao criar o projeto. Nesse momento, o plugin adicionou um ícone padrão para aplicação dentro do diretório res/drawable chamado icon.png. Desta forma, para referenciar essa imagem em outras classes da aplicação deve-se utilizar a constante R.drawable.icon. Além do mapeamento dos recursos, a classe R armazena na classe interna id os nomes que são dados aos componentes adicionados aos arquivos de layout. Por exemplo, se nomearmos uma caixa de texto como editNome, será criada uma constante denominada R.id.editNome. O arquivo AndroidManifest.xml armazena as informações sobre a aplicação como título, ícone, nome do pacote que identifica a aplicação, e telas da aplicação. O arquivo default.properties armazena algumas informações para compilação da aplicação, como: a versão mínima do Android exigida pela aplicação; e configurações para geração do APK (Android Package), que é o arquivo executável da aplicação a ser instalado no aparelho. Com o projeto traduzido, é possível executá-lo no emulador ou em um dispositivo Android. A Figura 17 exibe a aplicação convertida em execução. 44 Figura 17. Emulador do Android executando o projeto convertido 3.5 RESTRIÇÕES E LIMITAÇÕES O iOS é uma plataforma padrão para três modelos de dispositivos: iPhone, iPod Touch e iPad. O Android por sua vez pode ser executado em qualquer aparelho que possa adotá-lo. Dessa forma, além das diferenças entre APIs e as linguagens de programação, existem incompatibilidades pertinentes ao hardware desses dispositivos. Neste capítulo será descrito essas restrições e limitações que não foram resolvidas pelo iOS2Droid, e impedem uma total compatibilidade entre a aplicação original e a convertida. 3.5.1 Restrições de hardware O iPhone é um telefone com especificações de hardware padronizadas e com variações mínimas. O Android por sua vez, pode ter configurações variadas, mas o 45 documento Compatibility Definition especifica os requisitos essenciais para que um aparelho seja compatível com a plataforma. Para o propósito deste trabalho, a restrição de hardware que mais impacta no iOS2Droid é a diferença entre os tamanhos de tela dos aparelhos. Enquanto que o iPhone, até a versão 3GS tem uma resolução de 320x480, o Android, além dessa, suporta outras resoluções. Atualmente a conversão da aplicação pressupõe que as telas dos dispositivos origem e destino sejam as mesmas. Outra restrição importante é que nem todos os aparelhos Android suportam multi-touch, recurso muito utilizado em aplicativos iPhone. 3.5.2 Restrições da linguagem As principais restrições/limitações quanto à conversão do código estão ligadas a práticas de programação utilizadas na linguagem C que serão detalhadas nas próximas subseções, e que não estão disponível na linguagem Java. 3.5.2.1 Palavras reservadas Diversas palavras reservadas existentes na linguagem C não têm similares em Java, e por isso não são suportadas também pelo iOS2Droid. Abaixo são citadas algumas: goto apesar de ser uma palavra reservada da linguagem, não pode ser utilizada; typedef para criação de atalhos de tipos; extern para declaração de variáveis globais; static tem um conceito semelhante ao de Java, mas permite que sejam declaradas variáveis locais como estáticas que mantêm seu valor mesmo após várias chamadas de métodos; register indica que a variável estará alocada em um registrador da CPU; 46 signed e unsigned não são suportados uma vez que os tipos primitivos de Java são sinalizados, ou seja, aceitam números negativos e positivos. 3.5.2.2 Estruturas genéricas e checagem de tipo Um novidade do Java 5 foi o conceito de tipos genéricos, ou simplesmente Generics. E uma utilização bastante comum é especificar o tipo do objeto que é armazenado em uma estrutura de dados. // Em Java – Sem Generics List listaJava1 = new ArrayList(); // Em Java – Com Generics List<Carro> listaJava2 = new ArrayList<Carro>(); // Em Objective-C NSMutableArray * listaObjC = [[NSMutableArray alloc] init]; Nas instruções acima, são apresentadas declarações de listas de objetos em Java e Objective-C. Na primeira, é criada uma lista sem especificar qual tipo de objeto será armazenado nela, sendo assim, ela poderá armazenar qualquer tipo de objeto. A segunda instrução cria a lista especificando o tipo de objeto que será armazenado, restringindo assim o armazenamento a objetos apenas do tipo Carro (ou de alguma subclasse). Por fim, a última instrução, em Objective-C, cria uma lista sem especificar o tipo de objeto que será armazenado. // Em Java // (Instrução 1) Carro c1 = listaJava1.get(0); // (Instrução 2) Carro c2 = (Carro)listaJava1.get(0) // (Instrução 3) Carro c3 = listaJava2.get(0) // Em Objective-C // (Instrução 4) Carro * carro = [listaObjC objectAtIndex: 0]; 47 É possível observar que nas duas primeiras instruções acima, o intuito é tentar obter o primeiro objeto da lista (posição 0). No primeiro caso ocorrerá um erro em tempo de compilação, pois como lista foi declarada sem especificar o tipo de objeto que será armazenado, ela pode conter qualquer objeto. Sendo assim, deve ser feita uma conversão para o tipo que se deseja obter, o que é feito na instrução 2. Feita a conversão, é possível compilar o código, entretanto se o objeto armazenado na posição zero não for do tipo carro, uma exceção será lançada em tempo de execução. A terceira instrução utiliza a lista que foi criada especificando a classe dos objetos a serem armazenados. Dessa forma, o objeto pode ser obtido diretamente. Por fim, em Objective-C, o compilador não realiza a checagem dos tipos de dados durante a compilação como é feita na primeira instrução. Sendo assim, a instrução 4 seria válida em tempo de compilação, podendo lançar uma exceção em tempo de execução caso o objeto armazenado não seja um objeto da classe Carro. Dessa forma, o iOS2Droid converte a instrução 4 similar a instrução 1, tendo o desenvolvedor que fazer a conversão nessas situações, pois o iOS2Droid não está tratando esse tipo de instrução. // Em Java Carro carro = listaObjC.objectAtIndex(0); 3.6 CONCLUSÕES Como pode ser observado, o iOS2Droid realiza a conversão do código fonte utilizando um parser gerado pelo ANTLR. Esse parser utiliza bibliotecas do iOS2Droid para realizar o mapeamento das incompatibilidades entre as linguagens Objective-C e Java. Em seguida é feita a conversão dos NIBs para arquivos de layout do Android. Nesta etapa, é realizado o mapeamento entre componentes e propriedades divergentes entre as plataformas. Além disso, essa etapa adiciona no código fonte convertido na etapa anterior, a ligação entre os componentes e atributos definidos no código fonte. 48 Apesar dos impedimentos listados, que inviabilizam uma conversão completa, onde boa parte destes se refere à utilização de recursos não mapeáveis da linguagem C, o iOS2Droid consegue realizar o processo de conversão adaptando o ciclo de uma aplicação iPhone para Android. Com isso, o código da aplicação pode ser aberto no Eclipse e executado no emulador ou em um dispositivo real, bastando apenas realizar pequenos ajustes no código convertido. 49 4 VALIDAÇÃO DA FERRAMENTA Para validar o funcionamento da ferramenta proposta, algumas aplicações disponíveis na literatura adotada como referencial teórico deste trabalho foram convertidas. Elas englobam funcionalidades comuns como transições de tela e componentes de interface gráfica com eventos associados. Neste capítulo serão detalhadas essas aplicações e como as features foram convertidas pelo iOS2Droid. 4.1 BUTTON FUN O aplicativo ButtonFun (MARK e LAMARCHE, 2009) foi utilizado como primeiro experimento para converter o arquivo de definição de UI e associar eventos de clique aos botões de uma tela. Como foi citado anteriormente, a associação de eventos a componentes no iPhone é feita no arquivo de definição de UI. Enquanto no Android isso deve ser feito via código. Sendo assim, esse experimento validou a associação do evento de clique ao botão feito no código pela ferramenta. final UIButton outlet9573 = new UIButton((UIButton.View) _view.findViewById(R.id.outlet9573)); outlet9573.getView().setOnClickListener( new android.view.View.OnClickListener() { public void onClick(android.view.View v) { buttonPressed(outlet9573); } }); O código acima associa um evento de clique ao botão e chama o método definido no arquivo NIB que será executado quando o botão for clicado. 50 Figura 18. Aplicação Button Fun convertida pelo iOS2Droid 4.2 CONTROL FUN A aplicação Control Fun (MARK e LAMARCHE, 2009) foi utilizada no experimento devido a sua variedade de componentes e de propriedades utilizadas para obter o aspecto visual apresentado na Figura 16. 51 Figura 19. Aplicação Control Fun convertida pelo iOS2Droid 4.2.1 Aspecto Visual Nota-se que o aspecto visual dos componentes do iPhone foi mantido. A biblioteca de classes do iOS2Droid realiza esse trabalho convertendo as propriedades dos componentes do UIKit para propriedades dos componentes do Android. Propriedade no arquivo NIB Propriedade no XML do Android NSFrame android:layout_x android:layout_y android:layout_width android:layout_height 52 IBUIFont android:textSize IBUIImage android:src IBUIText android:text IBUINormalTitle IBUITitle IBUIValue android:progress IBUIMaxValue android:max IBUIOn android:checked IBSegmentTitles Segments IBUITextAlignment android:gravity IBUIAutocapitalizationType android:inputType IBUIKeyboardType IBUIReturnKeyType android:imeOptions IBUIBackgroundColor android:background IBUIPlaceholder android:hint IBUINormalTitleColor android:textColor IBUITextColor IBUIHighlightedTitleColor android:textColorHighlight IBUITag android:tag Tabela 2. Mapeamento das propriedades do XIB para Android 53 Além de fazer o mapeamento das propriedades, a biblioteca do iOS2Droid, adaptou componentes similares entre as plataformas, como o Slider do iPhone para o SeekBar do Android, e criou outros, com foi o caso do UISegmentedControl (que apresenta as opções de “Exibir” e “Ocultar” na Figura 16). 4.2.2 Novos eventos A aplicação utiliza outros eventos além do evento de clique de botão. Para o UISlider, o evento Value Changed é disparado quando o valor do componente é alterado. Ele foi mapeado da seguinte forma: final UISlider outlet5032 = new UISlider((UISlider.View) _view.findViewById(R.id.outlet5032)); outlet5032.getView().setOnSeekBarChangeListener( new SeekBar.OnSeekBarChangeListener() { public void onProgressChanged( SeekBar seekBar, int progress, boolean fromUser) { sliderChanged(outlet5032); } public void onStartTrackingTouch(SeekBar seekBar) {} public void onStopTrackingTouch(SeekBar seekBar) {} }); As caixas de texto do iPhone invocam automaticamente o teclado virtual, no entanto para ocultá-lo o desenvolvedor deve codificar esse comportamento. Esse evento é capturado pelo evento Did End On Exit. Ele também foi convertido durante essa aplicação. numberField.getView().setOnEditorActionListener( new android.widget.TextView.OnEditorActionListener() { public boolean onEditorAction( TextView v, int actionId, KeyEvent event) { textFieldDoneEditing(numberField); return false; } }); 54 4.2.3 Suporte a imagens 9-patch O visual do botão “Do something” é obtido através de uma imagem. Entretanto, para não perder qualidade é especificada em código a área que pode ser redimensionada sem a perda de qualidade. No Android esse resultado é obtido automaticamente pelo uso do padrão 9.patch (Android Developers WebSite, 2010). A classe UIImage do iOS2Droid implementa esse recurso do iPhone no Android. 4.2.4 Cores e Textos Tanto o iPhone quanto o Android utilizam o esquema de cores RGB (Red Green Blue). Entretanto essas cores, assim como alguns textos que são descritos no arquivo NIB utilizam o método de codificação Base64. Dessa forma, ao converter esse arquivo para o XML utilizado no Android, a ferramenta teve que realizar a decodificação dessas informações. <bytes key="NSRGB"> MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA </bytes> ... <string type="base64-UTF8" key="IBUIText"> TsO6bWVybzo </string> 4.3 VIEW SWITCHER A aplicação View Switcher (MARK e LAMARCHE, 2009) foi utilizada no experimento para verificar a funcionalidade de troca de telas. Em especial, nesse exemplo a transição é feita com um efeito 3D. O iPhone, assim como o Android, tem alguns efeitos de transição de telas pré-configurados. O efeito de rotação é um desses efeitos pré-configurados do iPhone, porém esse efeito teve de ser implementado pelo iOS2Droid e adicionado a sua biblioteca. 55 Figura 20. Aplicação View Switcher convertida pelo iOS2Droid 4.4 SOCCER BALL A aplicação Soccer Ball (CHAURAIS e MICHELS, 2009) foi utilizada no experimento para testar eventos de toque na tela. O mapeamento do evento foi feito na classe UIViewController. Ao definir o objeto UIView dessa classe, automaticamente os eventos de touch são capturados, mas não fazem nada por padrão. Cabe às subclasses programarem o comportamento para cada evento de touch. // Método da classe UIViewController do iOS2Droid public void setView(UIView view) { this.view = view; this.view.getView().setOnTouchListener( new View.OnTouchListener() { 56 public boolean onTouch( View v, MotionEvent motionEvent) { UITouch touch = new UITouch( CGUtils.CGPointMake( motionEvent.getX(), motionEvent.getY())); NSSet touches = NSSet.initWithObject(touch); UIEvent event = UIEvent.createTouchEvent( touches); switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: touchesBegan(touches, event); return true; case MotionEvent.ACTION_MOVE: touchesMoved(touches, event); return true; case MotionEvent.ACTION_UP: touchesEnded(touches, event); return true; case MotionEvent.ACTION_CANCEL: touchesCancelled(touches, event); return true; } return false; } }); viewDidLoad(); } public public public public void void void void touchesBegan(NSSet touches, UIEvent event) {} touchesMoved(NSSet touches, UIEvent event) {} touchesEnded(NSSet touches, UIEvent event) {} touchesCancelled(NSSet touches, UIEvent event){} 57 Figura 21. Aplicação SoccerBall convertida pelo iOS2Droid 4.5 CONCLUSÕES Ao final das validações, as aplicações convertidas foram compiladas e executadas em dispositivos Android com a necessidade de apenas pequenos ajustes. Uma prática sugerida na criação de novas aplicações, que pode auxiliar no processo de conversão, é a utilização apenas das classes do Cocoa Touch, evitando assim recursos exclusivos da linguagem C. As aplicações apresentaram um aspecto visual semelhante a original, ficando resguardados detalhes pertinentes à plataforma Android. Mesmo sendo aplicativos de baixa complexidade, eles nos dão indícios que a conversão automática de código entre as plataformas estudadas é possível através da utilização da ferramenta proposta. Entretanto, para que se possa abranger uma gama maior de aplicativos se 58 faz necessário realizar as evoluções do trabalho que serão descritas no próximo capítulo. 59 5 CONSIDERAÇÕES FINAIS Com o sucesso das plataformas móveis Android e iOS, a busca por aplicativos que rodem nesses dois ambientes se torna cada vez mais comum. Tendo em vista a velocidade dos projetos de software, desenvolver uma aplicação para cada uma das plataformas, pode aumentar o tempo e o custo do projeto, o que pode chegar a inviabilizá-lo. Nesse cenário, ferramentas que auxiliem na portabilidade de aplicações entre essas plataformas se tornam fundamentais. O iOS2Droid realiza esse trabalho prezando pela similaridade do código fonte original e procurando exigir o menor esforço possível do desenvolvedor nos ajustes que a ferramenta não pode realizar. Isso é obtido através da conversão direta do código fonte de uma plataforma para outra, o que traz alguns benefícios como: não forçar o desenvolvedor a aprender uma nova linguagem e uma nova API; não ter um ambiente de execução intermediário para executar a aplicação convertida; usufruir da grande disponibilidade de softwares desenvolvidos para iPhone de convertê-los para uma plataforma em constante crescimento como o Android. 5.1 EVOLUÇÃO DO TRABALHO Após a aplicação da ferramenta nos exemplos estudados, constatou-se diversos pontos de melhoria e novas funcionalidades que estão previstas em trabalhos futuros, conforme descritos abaixo: Mapeamento e implementação completa dos componentes do framework UIKitt e de suas propriedades; Implementar o Core Graphics Framework utilizado na criação de jogos; Converter arquivos que contenham apenas funções. Java trabalha com classes, logo, ao invés de criar arquivos apenas com funções, pode-se utilizar uma classe com métodos estáticos. O arquivo main.m não é tratado por esse motivo; Utilização da diretiva #define para criação de macros; 60 Tratar estruturas (struct) e diretivas (#ifdef, #ifundef, #undef, #if, #endif) instruções sizeof; A inicialização de arrays ainda não suportada pela ferramenta. Como apresentado abaixo: // Em Objective-C int maze[9]; // Em Java int[] maze = new int[9]; O iPhone conta apenas com um botão físico que serve para sair da aplicação. Dessa forma todo o fluxo de navegação de telas deve ser implementado pelo desenvolvedor. Os dispositivos Android por sua vez, contam com uma tecla física para voltar de uma tela para a anterior. Eles também contam com outra tecla que permite voltar diretamente para a tela principal do aparelho. Atualmente, a tecla de voltar não está realizando o comportamento de voltar para a tela anterior, ao invés disso, ela fecha a aplicação convertida independente da tela que estiver sendo exibida; Elaborar uma arquitetura que suporte outras plataformas de destino como bada, desenvolvida pela Samsung. 61 REFERÊNCIAS ADMOB Mobile Metrics. Metrics Highlights. Maio, 2010. Disponível <http://metrics.admob.com/2010/06/may-2010-mobile-metrics-report/>. em: Acessado em: 10 set. 2010. ADMOB Mobile Metrics, Publisher Survey. Março, 2010. Disponível em: <http://metrics.admob.com/2010/03/admob-publisher-survey/>. Acessado em: 10 set. 2010. Android Compatibility Definition. 2010. Disponível em: <http://static.googleusercontent.com/external_content/untrusted_dlcp/source.android. com/pt-BR//compatibility/android-2.2-cdd.pdf>. Acessado em: 26 out. 2010. Android Developer Website, 2010. Disponível em: <http://developer.android.com>. Acessado em: 25 out. 2010. ALLEN, Sarah. GRAUPERA, Vidal. LUNDRIGAN, Lee. Pro Smartphone CrossPlatform Development: iPhone, BlackBerry, Windows Mobile and Android Development and Distribution. Apress, 2010. Appcelerator. Q4 Mobile Developer Report, 2010. Disponível em: <http://assets.appcelerator.com.s3.amazonaws.com/docs/Appcelerator-IDC-Q4Mobile-Developer-Report.pdf>. Acessado em: 25 nov. 2010. Apple Developer Website. iOS Reference Library, 2010. Disponível <http://developer.apple.com/library/ios>. Acessado em: 14 set. 2010. em: 62 ARIMA, Katia, Smartphone para todos: Do iPhone ao Xing Ling vendido na esquina, os smartphones entram para escalação oficial de cada vez mais brasileiros. Info Exame 293ª edição, jul. 2010, p.23-28. BARROS, Tiago Guedes Ferreira. CMF: um framework multi-plataforma para desenvolvimento de aplicações para dispositivos móveis. 2007, 104 folhas. Dissertação de Mestrado – Universidade Federal de Pernambuco. Recife, Pernambuco. BRANNAN, James A., iPhone SDK Programming: A Begginner’s Guide. MacGraw-Hill, 2010. BUCANEK, Jamew. Learn Objective-C for Java Developers. Apress, 2009. CARTON, Paul. CRUMRINE, Jean. New survey shows Android OS roiling the smart phone market. jan. 2010. Disponível em: <http://www.changewaveresearch.com/articles/2010/01/smart_phone_20100104.htm l>. Acessado em: 26 jan. 2010. CHAURAIS, Gustavo. MICHELS, Paulo. Desenvolvendo para iPhone. Web Mobile Magazine, 27ª edição, p18-34, 2009. DALRYMPLE, Mark. KNASTER, Scott. Learn Objective-C on the Mac. Apress, 2009. 63 DIMARZIO, Jerome. Android: A programmer’s Guide. McGraw-Hill, 2008. GARDNER, David. Cresce demanda por aplicativos móveis. set. 2010. Disponível em: <http://www.itweb.com.br/noticias/index.asp?cod=71665>. Acessado em: 10 set. 2010. HORSTMANN, Cay. CORNELL, Gary. Core Java Fundamentals. 8º ed., Sun Microsystems, 2008. JAMES, Chris. Where to Play the Mobile Game: A Closer Look at the Leading Platforms. Casual Connect, Summer 2010, p.42-44. JOHNSON, Thienne M. Java para dispositivos Móveis: Desenvolvendo aplicações com J2ME. São Paulo: Novatec Editora, 2007. LEAL, Nelson Glauber de Vasconcelos. Android e iPhone: Um comparativo entre as plataformas da Google e da Apple. Web Mobile Magazine, 30ª edição, p5-21, 2010. LEAL, Nelson Glauber de Vasconcelos. FONSÊCA, Jorge Cavalcanti Barbosa. FERRAZ, Felipe Silva. Ant + Antenna com Java ME: Reuso de código entre aparelhos e otimização do processo de deploy. Web Mobile Magazine, 29ª edição, p5-15, 2010. LECHETTA, Ricardo R. Google Android: Aprenda a criar aplicações para dispositivos móveis com Android SDK. São Paulo: Novatec, 2009. 64 LEE, Valentino; SCHNEIDER, Heather; SCHELL, Robie. Aplicações Móveis: Arquitetura, Projeto e Desenvolvimento. São Paulo: Pearson Education do Brasil, 2005. MARK, Dave; LAMARCHE, Jeff. Beginning iPhone Development: Exploring the iPhone SDK. Apress, 2009. MCLAUGHLIN, Brett D.; POLLICE Gary; WEST, David. Head First Object-Oriented Analysis & Design. O‟Reilly, 2007. MEIER, Reto. Professional Android: Application Development. Indianapolis: Wiley Publishing, 2009. PARR, Terence. The definitive ANTLR Reference Manual: Building DomainSpecific Languages. Dallas, Texas: The Pragmatic Bookshelf, 2007. PILONE, Dan; PILONE, Tracey. Head First iPhone Development. O‟Reilly, 2009. PUDER, Arno. An XML-based Cross-Language Framework. DOA 2005, Agia Napa, Cyprus, LNCS, Springer. TYNAN, Dan. The 50 Greatest Gadgets of the Past 50 Years. dez. 2005. Disponível em: <http://www.pcworld.com/article/123950- 6/the_50_greatest_gadgets_of_the_past_50_years.html>. Acesso em: 26 jan. 2010. 65 The Nielsen Company. Android Soars, but iPhone Still Most Desired as Smartphones Grab 25% of U.S. Mobile Market. Ago. 2010. Disponível em: <http://blog.nielsen.com/nielsenwire/online_mobile/android-soars-but-iphone-stillmost-desired-as-smartphones-grab-25-of-u-s-mobile-market/> Acesso em: 01 set. 2010. The Nielsen Company. Recent Smartphone Android Most Popular Operating System in U.S. Among Buyers. Out. 2010. Disponível em: <http://blog.nielsen.com/nielsenwire/online_mobile/android-most-popular-operatingsystem-in-u-s-among-recent-smartphone-buyers/> SAMPAIO, Pedro; DAMASCENO, Alexandre; SAMPAIO, Igor; ALVES, Vander; RAMALHO, Geber; BORBA, Paulo. Portando Jogos em J2ME: Desafios, Estudo de Caso, e Diretrizes. jun. 2004. Disponível em: <http://toritama.cin.ufpe.br/twiki/pub/SPG/AspectProductLine/scientia05.pdf> Acesso em: 11 set. 2010. SIERRA, Kathy; BATES, Bert. Sun Certified Programmer for Java 6: Study Guide. McGraw-Hill, 2008. STARK, Jonathan. Building Android Apps with HTML, CSS, and JavaScript. Sebastopol, CA: O‟Reilly, 2010.