Aborda alguns dos conceitos e técnicas envolvidos no desenvolvimento de uma aplicação mobile, mais especificamente para o sistema operacional iOS. Neste contexto, este artigo destaca a linguagem, os processos e ferramentas utilizadas para o desenvolvimento de aplicações para iPhone e iPad, o que pode vir a auxiliar nesse tipo de desenvolvimento.
Guia do artigo: Desenvolvimento para iOS com Objective-C
- Desenvolvimento aplicações para iPhone
- Sobre o iPhone e o iOS
- Arquitetura de desenvolvimento
- Ambiente de desenvolvimento
- Conclusão
- Referências
O tema se torna fundamental para desenvolvedores mobile que buscam aprimorar seus conhecimentos na linguagem Objective-C e nas técnicas envolvidas em um projeto mobile para as plataformas Apple.
Desenvolvimento aplicações para iPhone
Este artigo apresenta um referencial conceitual introdutório sobre os principais conceitos e ferramentas envolvidas no desenvolvimento de aplicações para iPhone. Neste sentido, são abordados os seguintes temas: definições iniciais, arquitetura de desenvolvimento e ambiente de desenvolvimento.
Um smartphone pode ser definido como um telefone móvel que pode ser utilizado como um pequeno computador. O iPhone e seu sistema operacional foram projetados para que, unindo seus recursos de hardware e software, conseguissem se enquadrar nessa definição (ler Nota DevMan 1).
Sobre o iPhone e o iOS
O iPhone é o smartphone desenvolvido pela Apple com funções de iPod, câmera digital, internet, mensagens de texto (SMS), visual voicemail, conexão wi-fi local e, atualmente, suporte a videochamadas (FaceTime). A interação com o usuário é feita através de uma tela sensível ao toque. A título de curiosidade, a Apple registrou mais de duzentas patentes relacionadas com a tecnologia que criou o iPhone.
A Apple lançou junto com o iPhone 3G a App Store - loja online de jogos e aplicativos desenvolvidos por terceiros. Os desenvolvedores utilizam as ferramentas do SDK disponibilizado pela empresa para desenvolver aplicativos tanto para o iPhone quanto para iPods Touch. Os aplicativos podem ser baixados através do próprio aparelho (aplicativos de até 10 MB) ou pelo iTunes. Os preços são definidos pelos próprios desenvolvedores, sendo que 70% do valor do aplicativo fica com ele e 30% vai para a Apple.
Veja também: Conheça a linguagem Swift
A App Store está disponível no Brasil desde o lançamento do iPhone 3G. Em pouco mais de seis meses desde a abertura da App Store, a Apple anunciou que foram baixados mais de 500 milhões de aplicativos para iPhones e iPods touch. Hoje, há mais de 50 mil títulos na loja, divididos em 20 categorias — de jogos a aplicativos destinados a negócios.
Todos os recursos disponibilizados por esse aparelho são gerenciados, assim como a interação desses com o usuário, pelo seu sistema operacional, o iOS, que derivado do núcleo do Mac OS X, foi criado para ser compacto e eficiente, podendo assim explorar toda a capacidade dos dispositivos no qual é instalado.
Há um fator preponderante para o sucesso e a popularização do iPhone, a App Store. Esse recurso consiste de uma loja de aplicativos incorporada ao iOS, e também ao iTunes (programa de gerenciamento e venda de músicas da Apple), onde um usuário previamente cadastrado pode ter acesso a aplicativos, comprá-los e baixá-los diretamente em seus dispositivos.
Saiba mais Confira Curso de iOSUma outra proposta dessa loja configura-se na tentativa de possibilitar a desenvolvedores criar e divulgar seus aplicativos. Pilone e Pilone (2010) afirmam que desde a sua criação, a App Store vem se mostrando uma grande oportunidade para desenvolvedores independentes, os quais encontram nela a possibilidade de competirem com grandes empresas de software com renome internacional.
Por meio do programa de desenvolvedores Apple, um interessado em criar aplicativos para o iOS tem acesso a três tipos de cadastro, o individual gratuito, individual pago e o empresarial. No programa individual gratuito o desenvolvedor tem acesso à IDE de desenvolvimento e pode criar seus aplicativos testando-os em um simulador, diferentemente do programa individual pago, onde esses testes podem ser feitos diretamente em um aparelho, o que segundo Lamarche et. al. (2011) é muito importante devido a limitações do simulador como, por exemplo, a falta de componentes de hardware como câmera e acelerômetro.
Com o aplicativo finalizado, antes que seja publicado na App Store, a Apple exige que o mesmo passe por uma avaliação dentro da empresa, onde serão testados diferentes requisitos como padrões de interface, gerenciamento de memória, entre outros pontos. Só após receber uma avaliação positiva nos testes, o mesmo poderá ser publicado na loja.
Pilone e Pilone (2010) descrevem que a maior incidência de erros durante o desenvolvimento de aplicações para o iPhone acontecem quando não é dada a devida atenção as limitações do aparelho. Apesar de possuir diversas características e funções de um computador, os dispositivos móveis gerenciados pelo iOS possuem alguns recursos como memória e tempo de resposta limitados.
Um dos primeiros problemas a ser considerado quando se está desenvolvendo um aplicativo para iPhone é a falta de um serviço de multi-tarefa. No iOS, implementar soluções que permitam que um aplicativo utilize o processador enquanto não está ativo é possível, porém requer um grande esforço por parte do desenvolvedor.
Portanto, na maior parte do tempo, somente uma aplicação pode ficar ativa para o usuário e, consequentemente, sendo mostrada na tela. A partir da versão de número 4 do sistema operacional, algumas melhorias em relação a esse problema foram implementadas, e agora algumas aplicações podem rodar em plano de fundo. Funcionando dessa forma, tais aplicativos terão diversas limitações de processamento e poderão utilizar poucos recursos do sistema. Ou seja, não recebem total atenção da CPU, o que impossibilita a utilização de alguns recursos como conexões com a rede.
Segundo Sadun (2008), a quantidade de memória e poder de processamento são escassos. Por consequência disso, o iOS implementa uma rotina na qual é disparada uma notificação para a aplicação assim que a memória estiver acabando. Portanto, devem ser escritos códigos para lidar com esse tipo de situação e liberar memória para o sistema antes que o aplicativo seja finalizado pelo iOS.
Arquitetura de desenvolvimento
Para utilizar os recursos disponibilizados pelo iPhone, um programador precisa ter acesso às ferramentas de desenvolvimento, e essas podem ser encontradas no site da Apple. Após se cadastrar como desenvolvedor oficial, é possível ter acesso a um kit contendo todos os programas necessários, inclusive o Xcode, um ambiente integrado de desenvolvimento utilizado para a construção de aplicações iOS, utilizando para sua codificação a linguagem de programação Objective-C.
Essa linguagem de programação foi criada no início dos anos 80 com o intuito de unir as linguagens C e Smalltalk, associando assim características simples que possibilitam uma programação orientada a objeto sofisticada. Em 1985, Steve Jobs fundou a NeXT, que por sua vez, escolheu como seu sistema operacional base o Unix e criou a NextSTEP, uma poderosa ferramenta de desenvolvimento em Objective-C. Quando a Apple comprou a NeXT em 1996, o NextSTEP recebeu o nome de Cocoa e trouxe uma grande quantidade de desenvolvedores para a plataforma Macintosh, pois estava sendo distribuído gratuitamente, portanto, qualquer desenvolvedor poderia utilizá-lo. Desde então a linguagem Objective-C vem sofrendo atualizações e melhorias, e com isso torna-se uma robusta ferramenta para o desenvolvimento de aplicações para as plataformas Apple.
A Objective-C, por possuir características advindas da junção de outras linguagens, oferece algumas abordagens de elementos básicos da programação similar às encontradas no mercado. Porém, há algumas questões que devem ser esclarecidas para melhor compreensão do funcionamento da linguagem. Na estrutura de arquivos da Objective-C uma classe possui uma arquitetura diferente de algumas linguagens como, por exemplo, o Java. Ao invés de um arquivo único contendo declarações e implementações, pode-se observar que tal informação é dividida em dois arquivos, os headers e os implementations.
O arquivo header, o qual possui a extensão .h, contém todas as declarações de classe, variáveis, métodos, entre outros. Já o arquivo de implementation, caracterizado pela extensão .m, possui a implementação da maioria dos elementos declarados no header. Portanto, quando se deseja declarar um método em uma classe, primeiro atualiza-se o arquivo .h e depois o .m.
A Objective-C é uma linguagem orientada a objeto, e uma das premissas básicas de um sistema construído utilizando os conceitos de orientação a objeto é a criação de classes. Trevitowski et. al. (2011) ressaltam que, por os arquivos de implementação serem separados em dois, na criação de uma classe deverão ser utilizadas duas diretivas de compilação, as quais são marcadas com o símbolo @. No arquivo header deverá ser utilizada a diretiva @interface, já no implementation será utilizada a @implementation e, dessa forma, o compilador interpreta que a junção desses dois arquivos está implementando uma classe.
Após a criação de uma classe, um desenvolvedor poderá declarar e implementar diversos métodos na mesma. Porém, eventualmente isso não será possível porque estará utilizando alguma classe que possua o código fechado, ou deseja inserir a implementação de um método sem alterar a estrutura da classe.
A Objective-C possui um recurso que pode solucionar esse problema, as categories. As categories consistem de uma maneira fácil de modularizar a definição de uma classe em uma categoria de métodos relacionados. Por meio dessas, é possível estender uma classe já existente, mesmo não tendo acesso ao código fonte original e sem precisar implementar uma subclasse da mesma, o que permite a um desenvolvedor explorar melhor uma classe existente sem a necessidade de utilizar outros nomes em seu código. Por exemplo, um desenvolvedor deseja implementar um método auxiliar à classe UIColor, no qual seja possível retornar uma cor a partir de um código RGB. Ao invés de ter de criar uma subclasse e utilizar o nome dessa para chamar esse método, ele pode criar uma category de UIColor e, por meio da chamada dessa classe, acessar o seu método, deixando assim o código mais limpo e claro.
Outro conceito amplamente utilizado na programação para dispositivos iOS é a implementação de protocolos. Um protocolo trata-se de uma interface programática que possui a declaração de uma certa quantidade de métodos, e que pode ou não ser implementada por uma classe. Um protocolo consiste de um arquivo header possuidor da declaração de alguns métodos, onde esses podem ser definidos como obrigatórios ou opcionais. Uma classe qualquer pode implementar um ou mais protocolos, e esses definem o seu comportamento em relação a uma determinada situação, por exemplo, uma classe que assina o protocolo UITableViewDataSource pode implementar no total onze métodos, sendo que dois desses são obrigatórios, um responsável por retornar o número de linhas na tabela e o outro responsável por retornar o conteúdo de cada linha, pois sem as informações advindas desses métodos uma tabela não consegue mostrar nenhuma informação.
Como dito anteriormente, a Objective-C descende diretamente da linguagem C e uma das características herdadas é a falta de um garbage collector, ou seja, o desenvolvedor fica responsável pelo gerenciamento da memória disponível para sua aplicação.
Para auxiliar nesta função, o Cocoa Touch utiliza um recurso conhecido tanto como reference counting quanto retain counting. Nessa técnica, cada objeto possui um inteiro associado a ele, conhecido como contador de referência. Quando, em alguma parte do código, o desenvolvedor necessita de utilizar algum objeto, deve-se incrementar o contador desse objeto, já quando não é mais necessário, tal número deve ser decrementado. Quando o contador de referências de um objeto chega a 0, esse é destruído e a memória ocupada retorna ao sistema. Pode-se ver a aplicação de alguns dos conceitos apresentados na representação do ciclo de vida de um objeto encontrado na Figura 1.
Na Objective-C também é utilizado o conceito de autorelease pool, termo que traduzido literalmente para o português significa “piscina de liberação automática”. Esse nome vem do fato que todos os objetos que foram marcados como autorelease são adicionados à pool e, quando a mesma é desalocada da memória, todos os objetos que estão dentro dela também são liberados da memória.
Segundo Dalrymple e Knaster (2009), existem três regras que devem ser seguidas, quando se está desenvolvendo uma aplicação com a Objective-C em relação ao gerenciamento de memória, são elas:
- Quando um objeto é criado utilizando alguns dos comandos new, alloc ou copy, o desenvolvedor que realizou essa ação torna-se responsável por liberar a memória alocada àquele objeto, utilizando um dos comandos release ou autorelease.
- Ao tomar posse de um objeto por meio do comando retain, o desenvolvedor torna-se responsável por liberar o objeto, que por sua vez terá o seu retain count diminuído.
- Quando um objeto que passou por um autorelease é utilizado, não se deve preocupar em liberá-lo na memória, pois a autorelease pool fará isso automaticamente.
Se tais regras forem seguidas, o desenvolvedor não terá problemas com o gerenciamento da memória de sua aplicação.
A partir da versão 4.2 do Xcode, a qual foi liberada junto com a versão 5 do iOS, a Apple introduziu o conceito de Automatic Reference Counting (ARC). O ARC é um recurso em tempo de compilação que promove um gerenciamento de memória automático, e foi projetado pensando na produtividade dos desenvolvedores, os quais perdiam muito tempo, tanto fazendo o gerenciamento manual, quanto corrigindo bugs em relação a esse trabalho.
O ARC funciona adicionando os retains, releases e autoreleases para o desenvolvedor, portanto, conceitualmente ele não se trata de um garbage collector, mas sim de um recurso executado no momento em que a aplicação vai ser compilada. Projetos que não utilizavam o ARC podem ser migrados para essa nova tecnologia e todas as aplicações que a utilizam necessitam de, no mínimo, a versão 4 do iOS para rodar.
Com o gerenciamento de memória implementado, surge outra preocupação no processo de desenvolvimento de um aplicativo, a persistência de dados. Ao desenvolver qualquer projeto de software, uma das maiores preocupações, e consequentemente, uma das primeiras decisões que devem ser tomadas por um desenvolvedor, é a maneira com a qual deverá ser feita a persistência dos dados da aplicação. Tal decisão pode ser um fator preponderante para o sucesso de um projeto. Como citado anteriormente, existem diferentes abordagens em relação à manutenção dos dados de um aplicativo para iPhone, duas dessas merecem destaque, o SQLite e o Core Data.
O SQLite consiste de uma versão compacta do amplamente utilizado banco de dados relacional MySQL, oferecendo os mesmos tipos de dados e mantendo-se um poderoso método de armazenamento. Uma de suas vantagens em relação ao MySQL consiste na sua portabilidade, ou seja, esse banco de dados não necessita de um servidor para funcionar, por isso, apenas colocando os arquivos do SQLite no diretório da sua aplicação ele já estará pronto para uso.
Porém essa técnica possui duas limitações, a primeira baseia-se na dificuldade relacionada à criação da base de dados, a qual deve ser feita inteiramente à mão. A segunda consiste na falta de uma interface orientada a objeto. Portanto, para utilizá-lo, é necessário usar uma biblioteca vinda da linguagem C, a qual é mais complicada que o usual para o Objective-C, portanto aconselha-se a utilização do Core Data.
Mark e Lamarche (2009) definem o Core Data como um framework produzido pela Apple, que utiliza conceitos de mapeamento objeto relacional, ou seja, os dados são traduzidos de forma que possam ser facilmente armazenados na base de dados, por isso o desenvolvedor, ao contrário de outros métodos de persistência, não precisa lidar com chamadas a arquivos ou querys ao utilizá-lo. O framework encapsula algumas rotinas extensas e complexas advindas da manipulação dos dados, otimizando assim a maneira com a qual suas bases de dados são criadas, economizando tempo e esforço.
O Core Data possui uma tecnologia de funcionamento própria e conceitos únicos, os quais devem ser abordados para o entendimento de seu funcionamento. Todos os tópicos destacados e explanados por Mark e Lamarche (2011), são:
- Persistence Store: consiste basicamente do local onde o Core Data armazena seus dados. No iPhone, por padrão, a tecnologia utilizada para armazenar os dados é um banco de dados SQLite, porém, isso pode ser alterado sem que nenhuma outra alteração seja feita no código da aplicação.
- Persistence Store Coordinator: é uma classe que controla o acesso às persistence stores, ou seja, quando mais de uma classe dispara uma requisição de leitura ou gravação de dados ao mesmo tempo, o coordinator as coloca em ordem, evitando assim, inconsistências no banco.
- Entidades: o Core Data trabalha com o conceito de entidade. Assim como em um banco relacional tradicional, consiste de abstrações de dados, os quais possuem propriedades.
- Propriedades: cada entidade possui um conjunto de propriedades que determinam suas características. Existem 4 tipos de propriedades, são elas, atributos, relacionamentos, fetched requests e fetch requests.
Quando um desenvolvedor opta por utilizar o Core Data como a maneira de persistência de dados do seu aplicativo, a primeira iniciativa a ser tomada é o desenvolvimento do modelo de dados. Por meio de uma ferramenta integrada ao Xcode, é possível construir modelos de dados contendo as entidades pertencentes à regra de negócio e seus relacionamentos.
Após a conclusão do modelo, é possível gerar as classes referentes a essas entidades e, dessa forma, quando for criado um objeto de NSManagedObjectModel referente a elas, o Core Data realizará o gerenciamento e a possível persistência desses dados. Para o funcionamento desse processo é necessária a utilização de um ManagedObjectContext.
Mark e Lamarche (2009) afirmam que, na grande maioria das vezes, será utilizado apenas um objeto da classe ManagedObjectContext, criado no AppDelegate. Também criado na mesma classe, tem-se uma instância de um store coordinator. Com todos os objetos necessário criados, para persistir um objeto no sistema, deve-se criar uma instância do mesmo recebendo o construtor de NSEntityDescription, alterar seus dados e, após todas essas configurações, salvar o contexto, realizando assim a persistência.
Para realizar uma busca utilizando o Core Data é necessário criar uma requisição, sendo essa um objeto da classe NSFetchRequest. Vários atributos podem ser alterados nesse objeto como a descrição do objeto que deve ser carregado e como os objetos obtidos vão estar dispostos. Quando executada por um contexto, a requisição retorna um NSArray contendo as informações que se encaixaram na sua descrição.
Ambiente de desenvolvimento
A IDE para o desenvolvimento em Objective-C é o Xcode. Criada e mantida pela Apple, essa plataforma traz diversos recursos para o desenvolvimento de aplicações desktop e mobile. Em sua interface, representada na Figura 2, pode-se perceber alguns desses recursos.
Na região destacada de número 1 está a área de navegação onde, por meio dessa, pode-se organizar e navegar nos arquivos pertencentes ao projeto por meio de uma estrutura em árvore, adicionar recursos multimídia apenas arrastando-os para a pasta onde se deseja que sejam inseridos, acessar as configurações do projeto, entre outras funções. Já na parte destacada de número 2 pode-se encontrar o editor de código onde o desenvolvedor pode implementar os códigos referentes à sua aplicação, receber dicas de implementação, as quais podem completar automaticamente os comandos inseridos e alterar a cor dos elementos presentes, facilitando assim a compreensão do código.
Na região destacada de número 3 está representada a área de debug. Por meio dessa facilidade o desenvolvedor pode acompanhar as mensagens enviadas pela aplicação ao console, após inserir um ponto de parada no código, acompanhar o valor atual das variáveis presentes, o que auxilia na descoberta de falhas. Já na parte destacada de número 4, pode-se encontrar a barra de ferramentas onde, por meio dessa, é possível escolher como sua aplicação será compilada, onde será compilada, selecionar se os pontos de parada do código estão ativos e, por fim, configurar quais elementos estarão visíveis ao desenvolvedor, o que permite a customização do layout da IDE.
Além dos recursos citados, o Xcode possui um editor de interfaces integrado, o qual possibilita a criação das telas de um aplicativo através de objetos prontos e algumas configurações. Os recursos do interface builder estão representados na Figura 3. Na parte destacada de número 1 pode-se perceber a área destinada à edição de uma tela, ou seja, nela serão inseridos os elementos que farão parte dessa view, facilitando assim o trabalho do desenvolvedor quanto à criação de layouts. Já na parte destacada de número 2 encontra-se a área de utilidades. Nela é possível realizar alterações em quaisquer características de um objeto inserido na tela, inclusive tamanho, cor e caraterísticas específicas. Também nessa área, está inserida a biblioteca de objetos do Xcode, os quais podem ser arrastados e posicionados na tela.
Por último, na parte destacada de número 3, encontra-se a representação gráfica de dois elementos lógicos. O segundo ícone representa o first responder de um evento que pode ocorrer na tela, ou seja, quem irá responder pelas ações no código que são disparadas por eventos na view. Já o primeiro ícone representa o file owner, ou seja, a representação da classe que possui o papel de “dona” da tela que está sendo editada, e por meio desse ícone é possível realizar a ligação de elementos no layout com seus representantes no código. Para implementar elementos em Objective-C que irão responder por controles inseridos via Interface Builder, é necessário utilizar dois comandos, o IBOutlet, inserido antes de um atributo para representar as caraterísticas de um objeto e o IBAction, antes dos métodos que serão disparados por eventos vindos da tela.
Conclusão
Uma das maiores motivações para o desenvolvimento de aplicações mobile para iPhone configura-se na oportunidade criada pela App Store. Essa loja de aplicativos permite que o desenvolvedor crie um aplicativo, o coloque a venda e assim atinja milhares de clientes podendo chegar a disputar um espaço no mercado crescente de desenvolvimento de aplicativos para smartphones.
O Xcode configura-se uma ferramenta robusta e detentora de diversos recursos de integração código-interface, o que facilita a implementação das respostas referentes à interação do usuário com as telas. Outra vantagem de se desenvolver para essa plataforma consiste na documentação existente. Em várias ocasiões, um desenvolvedor pode ter a necessidade de procurar por uma explicação em relação a conceitos de implementação, e nessas situações, os documentos disponibilizados pela Apple auxiliam na resolução de dúvidas.
Alguns fatores que podem surgir como dificuldades a um iniciante na linguagem e no tipo de programação podem ser conceitos exclusivos da linguagem e do framework. Primeiramente, a adaptação para a sintaxe da linguagem, a qual possui a característica de tentar ser o mais próximo da leitura natural possível, e assim acaba se diferenciando das demais. A segunda dificuldade surge em relação ao conceito de persistência de dados pois, ao criar um ambiente onde o sistema se encarrega de gravar automaticamente todas as informações em um banco de dados, a falta de um código responsável por essa ação pode deixar o desenvolvedor inseguro em relação a essa técnica.
Referências
- Apple Developer
- APPLE. Transitioning to ARC Release Notes
- DALRYMPLE, Mark; KNASTER, Scott. Learn Objective-C on the Mac [S. l.]: Apress, 2009.
- KOCHAN, Stephen. Programming in Objective-C 2.0 [S. l.]: Addison-Wesley, 2009.
- MARK, Dave; NUTTING, Jack; LAMARCHE, Jeff. Beginning iPhone 4 Development. [S. l.]: Apress, 2011.
- PILONE, Dan; PILONE, Tracey. Head First iPhone Development. [S. l.]: O’Reilly Media, 2010.
- TREBITOWSKI, Brandon; ALLEN, Christopher; APPELCLINE, Shannon. iPhone and iPad in Action. [S. l.]: Manning, 2011.