um pluguinho
Éverton Antônio
This user hasn't shared any biographical information
Homepage: http://www.nuxlli.com.br
Jabber/GTalk: nuxlli@gmail.com
Posts by Éverton Antônio
Compartilhando código entre projetos iOS: A solução
Jul 12th
No post anterior apresentei o problema sobre o compartilhamento de código entre projetos iOS, falei das soluções mais utilizadas e seus problemas, também falei da solução usando framework, e acabei falando sobre a pegadinha de que o framework só esta disponível para Mac OS X. Na verdade eu menti (era para o seu bem), essa opção só está disponível (oficialmente) para Mac OS X, podemos fazer para iOS, mas como tudo no iOS: com um certo trabalho.
Vamos a solução, primeiro vamos criar um novo projeto no Xcode, este projeto deve ser do tipo “iOS > Framework & Library > Cocoa Touch Static”:

Defina um nome para seu framework:

Obs: atenção a esse nome, no final vamos ter é alguma coisa como: [nome-do-projeto].framework.
Vamos adicionar aqui um código de exemplo:

Uma vez com um código de exemplo ou o código que você queira compartilha adicionado, já podemos compilar e verificar se tudo esta indo bem. Se tudo estiver certo vamos passar ao passo seguinte que é montar o framework. Para isso vamos adicionar um novo target do tipo: “iOS > Other > Aggregate”:

Vou dar o nome de “iOS-Framework”, mas você pode escolher o nome que lhe convier:

Agora precisamos adicionar 3 entradas na aba “Build Settings” desse target:

As entradas são as seguintes:
PRODUCT_NAME = ${PROJECT_NAME}
STATIC_TARGET_NAME = ${PRODUCT_NAME}
FRAMEWORK_DIR = ${PROJECT_DIR}/${PRODUCT_NAME}.framework
Lembra que falei que o resultado final do projeto é algo como [nome-do-projeto].framework? Pois bem, será assim se você seguir os valores que sugeri para essas entradas, evidente que você pode variar de acordo com o que lhe convier.
Na sequência vamos para aba “Build Phases”, e adicionamos duas fases do tipo “Run Scripts” e uma do tipo “Copy Files”, a baixo dou exemplo de nomes que você pode dar a essas fases:

Para primeira fase, no exemplo a fase “Build architecture-specific static libs”, que será responsável por compilar o código nas duas arquiteturas: x386 e ARM, Simulador e Device respectivamente vamos definir o seguinte script:
xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphoneos -target ${STATIC_TARGET_NAME} -configuration ${CONFIGURATION} clean build SYMROOT=${SYMROOT}
Já para segunda fase, a “Build framework package”, que vai montar a pasta do framework usando os arquivos compilados com o script anterior, vamos definir o script:
LIBRARY_NAME_PATH="lib${STATIC_TARGET_NAME}.a" &&
DEVICE_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphoneos/${LIBRARY_NAME_PATH}" &&
SIMULATOR_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${LIBRARY_NAME_PATH}" &&
UNIVERSAL_LIBRARY_PATH="${FRAMEWORK_DIR}/Versions/A/${PRODUCT_NAME}"
# Create framework directory structure.
rm -rf "${FRAMEWORK_DIR}" &&
mkdir -p "${FRAMEWORK_DIR}/Versions/A/Headers" &&
mkdir -p "${FRAMEWORK_DIR}/Versions/A/Resources" &&
# Generate universal binary from desktop, device, and simulator builds.
lipo "${SIMULATOR_LIBRARY_PATH}" "${DEVICE_LIBRARY_PATH}" -create -output "${UNIVERSAL_LIBRARY_PATH}" &&
# Move files to appropriate locations in framework paths.
cd "${FRAMEWORK_DIR}/Versions" &&
ln -s "A" "Current" &&
cd "${FRAMEWORK_DIR}" &&
ln -s "Versions/Current/Headers" "Headers" &&
ln -s "Versions/Current/Resources" "Resources" &&
ln -s "Versions/Current/${PRODUCT_NAME}" "${PRODUCT_NAME}"
Escolhendo o target “iOS-Framework” e compilando já devemos obter uma pasta [nome-do-projeto].framework nas pasta do projeto, isso é o suficiente para termos uma framework que pode ser usando em outro projeto, mas apenas bibliotecas estáticas não compõe um framework, um dos pontos principais de um framework são os arquivos de cabeçalho, os famosos .h. Precisamos copiar os arquivos .h para pasta “Headers”, para isso vamos usar a ultima fase que adicionamos ao target:

Neste ponto devemos arrastar os arquivos de cabeçalhos que precisarmos para esta fase. Assim podemos compilar e obter uma pasta .framework que podemos utilizar em qualquer projeto iOS. Mas como usar este framework?
O processo é bem parecido com adicionar um framework oficial, a diferença é que devemos procurar pela pasta .framework no lugar de escolher uma da lista:

Observe que no exemplo eu arrastei o MyFramework.framework para o grupo Frameworks, para uma melhor organização do código. Se você tiver interesse em ver como ficou esse projeto de exemplo pode baixa-lo aqui.
Update: Ficou faltando alguma referência ne?
Referência 1: Eu cheguei a escrever um artigo antes desse falando de um metodo que usava target do tipo “Mac Framework”, mas como não funcionou com o Device, e era bem complexo quando comparado a essa solução, resolvi mudar a abordagem, mas se tiver interesse nessa solução de uma olhada neste post.
Referência 2: A solução que descrevi aqui não veio do nada, na verdade ela é uma simplificação e um roteiro para solução que o pessoal do Pivotal Labs utilizou na criação do Framework Cedar, um framework de testes que vale dar uma olhada, e quem sabe um post
Compartilhando código entre projetos iOS: O problema
Jul 6th
Uma das coisas que mais incomoda no desenvolvimento para iOS é a falta de um suporte (decente) ao compartilhamento de código entre projetos.
Na maior parte dos casos tem se optato por três soluções: “copiar o código”, “biblioteca estática” e “projeto dependente”, no primeiro caso você faz uma copia do código que vai reutilizar e adiciona este código no projeto onde quer reutilizar, este é um método ruim, primeiro porque você vai ter que acertar as dependências desse código, adicionando frameworks indiretos (que o código compartilhado utiliza, mas seu projeto não), depois você tem que definir informações sobre compilação, flags e variáveis.
Outro efeito colateral é na hora de compilar, dependendo do tamanho do código adicionado você pode perder tempo de compilação considerável, principalmente se você precisar limpar constantemente a compilação. Por ultimo mas não menos importante, aumenta-se em muito o gral de complexidade na manutenção do código compartilhado, você vai ter que ficar copiando código de um lado para outro quando houver atualizações, além de que se tivermos testes (eu recomendo) a coisa pode ficar ainda mais complicada.
A segunda alternativa é a “biblioteca estática”, talvez a melhor dentre as atuais opções. Nesta opção você cria um projeto que tem como target gerar uma lib static, um .a, que deve ser adicionado como dependência de linkagem ao projeto final. O bom dessa opção é que além de ser suportada oficialmente pelo SDK, você pode criar um projeto separada para conte-la, o que facilita sua manutenção. Mas ela sofre de dois problemas chatos, primeiro você tem que administrar os “headers” manualmente, copiando de um projeto para o outro, e definindo os “path load” dos arquivos “headers”, o que recai sobre os problemas na opção anterior.
Depois temos um outro um outro problema, a compilação tem como resultado .a’s para diferentes arquiteturas, acabamos com um .a para o simulador (i386) e um .a para o device (arm), o que nos obriga a juntar esses arquivos com uma ferramenta como “lipo”, um utilitário de linha de comando que junta binários de diferente arquiteturas, claro, isso se quisermos algo mais útil.
O esquema de “projeto dependente” é uma complemento da solução anterior, você cria um projeto de biblioteca estática depois arrasta este projeto para dentro do outro projeto, configura o target dependente, seta o produto desse target como dependência de linkagem do target do seu projeto, e acaba com um projeto mega confuso e difícil de manter
. Eu nunca consegui usar isso de forma prática, primeiro que o Xcode se perde com os arquivos de cabeçalho, com os targets e outras coisas malucas que só o Xcode faz por você, depois essa solução gera um projeto final complicado de entender, se forem muitas as dependências você acaba com um monte de projeto dentro do outro, e se estes projetos não estiverem no mesmo diretório (o que pode ser inviável se você mantém os projetos em diferentes controls de versão) você acaba com projeto todo quebrado, que vai demandar mais atenção de terceiros e sua na hora de dar manutenção.
Mas então o que fazer? Surge então os framework. Mas o que vem a ser frameworks? Pela definição da Apple: “A framework is a dynamic (loaded only when used) shared library along with its associated resource information. This information is packaged as a bundle. This is analogous to the shared libraries, which are placed in the Extensions folder in Mac OS 9.”. Em termos gerais é a forma pela qual você pode re-utilizar partes dos seus projetos em outros projetos em ambientes de desenvolvimento da Apple, tanto o SDK para Mac OS X como para iOS contam com alguns frameworks fornecidos pela Apple, que estão longe de cobrir todas as necessidades, principalmente de projetos mais complexos. O que leva aos desenvolvedores a criar seus próprios frameworks.
Mas, eis que surge a pegadinha, atualmente (minha esperança é que isso mude), você só pode escrever seu próprio framework para Mac OS X, e não para iOS. O que é uma verdadeira chatice, por falta de um termo melhor. Isso além de dificultar a organização de projetos dependentes, dificulta em muito disseminação de código Open Source pelo ecossistema iOS.
Bom essa foi uma introdução ao problema, nó próximo post vamos ver como resolver esse problema, e começar a compartilha códigos de uma forma mais prática.
Server rack à la zeroconf com Pow
Apr 17th
Já faz algum tempo que não mantenho um apache instalado no ambiente de desenvolvimento, isso se deve principalmente ao fato de que já não desenvolvo nada em php a alguns anos, logo um apache rodando o tempo todo na máquina acaba sendo um desperdicio de recursos.
Uma coisa que tem aumentando muito por aqui são aplicações rack, sejam projetos em andamento, sejam apps de teste para as mais diversas gemas que aparecem por esse mundão do ruby, sempre preciso levantar uma app para testá-la e quase sempre isso quer dizer levantar uma app rack.
Não que digitar um comando como rackup, padrino start, rake start ou similares sejam a morte, mas eu acabo perdendo um tempinho gerenciando o que esta ou não em pé. Sem contar que na hora de acessar, o historico do browser acaba virando uma zona: http://localhost:3000, http://localhost:4567, http://localhost:9000 e por ai vai, acabo perdendo um pouco de comodidade que o Chrome oferece na busca de urls já acessadas. Evidente que existe a opção de adicionar uma host no /etc/host, mas mesmo isso acaba não sendo prático de manter.
Então surge o Pow, o Pow é uma aplicação escrita pelo Ryan McGeary, que tem como objetivo ser um zeroconf rack server para Mac OS X, voltado exclusivamente ao ambiente de desenvolvimento. Como ele suporta rack apps, consequentemente suporta Rails apps.
Como toda ferramenta zero-conf, a instalação e configuração do Pow é muito simples:
$ curl get.pow.cx | sh
Em algum momento ele vai pedir a senha do root para fazer configurações de firewall (ele redireciona fluxo da porta 80 da sua máquina para porta 20559 do Pow), e vai criar uma symlink no seu home: ~/.pow.
Agora basta criar um symlink para sua aplicação dentro dessa pasta, e configuração já esta pronta:
$ ln -s ~/Projects/myapp ~/.pow/myapp
Acessando http://myapp.dev o Pow vai reconhecer o virtual host e automaticamente levantar a aplicação, se depois de 15 minutos a aplicação não tiver mais acessos o Pow dece a aplicação e continua aguardando conexões. Aqui uma dica: no Chrome digitar apenas myapp.dev não funciona, ele não identifica isso como um host e acaba indo parar na busca, o http:// se faz necessário (pelo menos no chrome dev foi assim).
Alguns features interessantes:
- Auto refresh: Pelo menos aqui no testes com uma aplicação padrino (preciso falar um pouco mais sobre padrino), ele fez refresh dos meus controllers e models automaticamente, acredito que isso funcione também no Rails, vai depender mais de como o framework é desenvolvido;
- Suporte a rvm: Por padrão ele procura pelo seguintes arquivos na pasta da aplicação: .powrc, .powenv ou .rvmrc, o que acaba sendo uma mão na roda se você utiliza .rvm;
- Suporte a variáveis de ambiente: no arquivo .powenv você pode exportar variáveis de ambiente que sua aplicação utilize. Isso tem sido de grande utilidade por aqui, pois permite emular os comportamento de configuração que o Heroku utiliza;
- Subdomínio: Este é um dos pontos fortes na hora de executar testes, facilita bastante poder digitar subdomínios, principalmente quando você esta desenvolvendo aplicações que utilizam subdomínios dinâmicos.
- É mais: Mais detalhes sobre como utilizar e configuras as esta e vários outras opções na página do projeto: Pow
Como sempre o Pow não é a bala de prata, mas é sempre bom poder automatizar tarefas repetitivas, e quando isso envolve pouca configuração ou zero acaba ficando ainda melhor.
Melhorando o editor do codebase
Feb 21st
Já faz algum tempo que estamos em processo de adoção do codebase como serviço de repositório e controle de versão aqui na Abril, em substituição principalmente a serviços de git e wiki internos.
Uma das coisas que incomodam no codebase é o editor do wiki, que é bem limitador, para dizer a verdade um textarea sem nenhuma customização e com uma fonte safadinha. Pensando nisso resolvi melhorar um pouquinho o trabalho de editar a wiki e fiz um pequeno script que para facilitar minha vida, e quem sabe a sua.
Usando o elegante editor web: markitUp, criei um projeto no github. No README do projeto existe informações de como utilizar o script no chrome.
Basicamente você vai precisar instalar uma extensão para seu navegador que permita injetar javascript em uma determinada página, como meu navegador principal é chrome, normalmente eu utilizo a extensão “Personalized Web“, ela facilita bastante o trabalho de injetar código javascript ou mesmo css, além de permitir a criação de um match para saber quando o script deve ser executado.
Existem outras extensões, inclusive suporte a isso em outros browsers, no caso do Firefox você pode usar o Greasemonkey, se você souber de outras me mande para que possa listar aqui para ajudar mais gente a utilizar o recurso.
Global Game Jam 2011
Feb 1st
No ultimo final de semana participei do Global Game Jam. Fui convidado pelo Rafael da Panela Games para participar do Site que ele montou em casa, no fim o único da cidade de São Paulo, fiquei me perguntando: cade a galera de games de sampa? Provavelmente ganhando dinheiro por ai
Já faz um tempo que estou aprendendo a desenvolver para iOS. Mas esta foi uma boa oportunidade de colocar em pratica alguns conceitos, principalmente no que tange a desenvolvimento de games, área que estou começando a dar os primeiros passos.
O evento como um todo foi legal, vários jogos criados (cerca de 1500 games criados pelo mundo em 48 horas o.O), muita comida de nerd e uma boa quantidade de refrigerante e cerveja consumida. O calor atrapalhou um pouco mas deu para concentrar e acabamos por conseguir colocar 3 games no ar. Dois para PC e uma para iOS, ainda falta um bom trabalho para que eles se tornem jogáveis, mas esperem um pouco e teremos novidades sobre isso.
E por falar em novidade, em breve devo liberar alguns novos post que estou escrevendo sobre desenvolvimento para iOS. Foram 6 meses de desenvolvimento de uma app para iOS, muita coisa aprendida, muita dica e ideias a serem transmitidas.
RVM, onde estou!?!?!
Nov 24th
Comecei a utilizar o RVM em sua versão 0.0.22, na época ele não passava de um script shell que permitia a instalação e troca entre as vms, mas ele vem avançado muito, e funcionalidades como set de gemas é só a ponta do iceberg.
Motivado pelo post anterior acabei lendo um pouco mais a documentação e encontrei uns scriptizinho bem interessante. Como saber rapidamente qual a versão atual da minha VM? Para isso podemos contar com o script ~/.rvm/bin/rvm-prompt, ele pode ser usando adicionando a seguinte linha ao seu .bash_profile:
Com isso ele mostra qual maquina virtual do Ruby você esta usando, mas apenas quando essa for diferente da default. Só isso já seria o suficiente, mas o que me incomoda nesta solução, é que eu já tenho uma linha de comando grande, e nem sempre eu preciso saber qual versão eu estou usando, isso é particularmente interessante quando estou em um projeto Ruby. Como normalmente um projeto Ruby temos um arquivo Rakefile podemos procurar por este arquivo e exibir a versão da máquina apenas quando estivermos no diretório de um projeto Ruby. Vamos adicionar as seguintes linhas ao nosso .bash_profile:
RVM_VERSION=`~/.rvm/bin/rvm-prompt`
if [[ -f "$(pwd)/Rakefile" ]] && [[ ! -z "$RVM_VERSION" ]]; then
echo "${RVM_VERSION} "
fi
}
Agora podemos mudar a linha anterior para:
Espero que ajude alguém e qualquer dica que possa melhor é só comentar a baixo.
Para tudo! Instale o RVM antes.
Nov 24th
Essa era uma dica que gostaria de ter recebido antes de ter encostado no meu mac, mas infelizmente na época o RVM ainda não existia, então para quem esta começando a usar Mac OS X e principalmente Ruby, use o RVM. Digo isso porque uma vez que tenha feito a bagunça de instalar varias máquinas Ruby, a coisa vai começar a complicar.
Mas o que raios é esse RVM? Ruby Version Manager, é basicamente um instalador e gerenciador de máquinas virtuais Ruby, e adicionalmente um gerenciador de sets de gemas. Por baixos dos panos ele é um script bash que troca algumas variáveis de ambiente e permite ter varias versões das máquinas virtuais Ruby (MRI, Jruby, etc) instaladas diretamente na pasta do usuário, dessa forma ele ainda permite um isolamento entre as instalações de VMS dos usuário de uma máquina.
A grande vantagens dele esta em não misturas as coisas de uma VM com a outra, e permite uma rápida troca entra uma VM e outra. A vantagem adicional de gerência sets de gemas é na verdade um grande achado, pois juntas as duas coisas permite criar ambientes isolados por aplicação, e quem trabalha com Ruby sabe como é difícil lidar com o o esquema de gemas, famoso “DLL Hell”.
Mas vamos deixar de conversa e vamos mostrar como usar. A instalação é simples, e feita usando o gem, que no caso de você esta usando Leopard já vai estar instalado:
$ rvm-install
O segundo comando vai criar a pasta ~/.rvm, é nela que toda a magia acontece, dentre outras coisas dentro dessa pasta esta os scripts que permite o funcionamento do rvm, observe que este comando mostra uma instrução sobre como adicionar o carregamento do RVM no seu bash, isso pode variar dependendo de máquina e SO.
Uma vez que bash esteja configurado, o comando rvm deve estar disponível, sua utilização é simples:
$ rvm install ree # para instalar ruby enterprise por exemplo
$ rvm ree # passa a utilizar o ruby enterprise com máquina virtual rvm
Bom até aqui temos o bem básico, você pode ver mais sobre a instalação e configuração do RVM aqui. Agora vamos a um exemplo de para o esquema de sets de gemas. Vamos criar um set para um blog, típico não
$ rvm 1.8.7 # vamos para máquina MRI v=1.8.7 só para listar as gemas
$ gem list # veja que não há nenhuma gema instalada
$ rvm 1.8.7%blog # aqui estamos criando um novo set com base na máquina 1.8.7
$ gem install rails # vamos instalar rails nesse set
$ gem list # observe que vc tem rails instalado
$ rvm use 1.8.7 # agora não tem mais ;)
Agora é só criar sets diferentes para suas aplicações e evitar a colisão das malditas gemas. Mas antes disso duas observações importantes: Evite o uso do sudo quando for instalar a gemas dentro de uma das máquinas virtuais, elas podem ate funcionar, mas isso vai fazer com que as gemas sejam instaladas como root e os arquivos dentro de pasta ~/.rvm/** não vão pode ser removidos pelo usuário normalmente.
Outra dica que eu acho importante, mesmo ele permitindo que volte a VM default do sistema, prefira fazer uma instalação limpa dela dentro do rvm, isso permite manter as coisas separadas e facilita na hora de criar um set ou mesmo atualizar sua VM.
Tarifas do Correios: Sedex e PAC (Atualizado)
Dec 14th

Hoje postei minha primeira contribuição ao mundo Rails. Fiz isso no forum do RubyOnbr.org por dois motivos: ainda não descobrir como postar código com syntax colorida aqui no WordPress
, e segundo que la tem bem mais acessos que aqui.. heheh
Update: Na semana passada os correios fizeram algumas mudanças no serviço de consulta de tarifas. Basicamente o que muda é que agora é necessário o uso de usuário e senha.
Este usuário e senha está disponível para empresas que tenha contrato com os correios, e é necessário o envio de pelo menos R$ 100,00 por mês para que possa utilizar o serviço.
Para o script, temos as seguintes mudanças:
- Os códigos dos produtos mudam para 40096 e 41068, Sedex e Pac respectivamente
- O endereço do serviço: http://www.correios.com.br/encomendas/precos/calculo_contrato.cfm
- E agora é necessário informar os campos tx_código e tx_senha (para obter os esta informação é necessário entrar em contato com os Correios e verificar com eles o seu contrato)
Abaixo uma versão do script com as devidas atualizações, observe porem que a txt_codigo e tx_senha deve ser definidos: