Specificadores de Formato para NSLog

fevereiro 19th, 2012 by Ricardo Silva No comments »
%@     Object
%d, %i signed int
%u     unsigned int
%f     float/double

%x, %X hexadecimal int
%o     octal int
%zu    size_t
%p     pointer
%e     float/double (in scientific notation)
%g     float/double (as %f or %e, depending on value)
%s     C string (bytes)
%S     C string (unichar)
%.*s   Pascal string (requires two arguments, pass pstr[0] as the first, pstr+1 as the second)
%c     character
%C     unichar

%lld   long long
%llu   unsigned long long
%Lf    long double

Bibliotecas & Workspaces

novembro 29th, 2011 by Ricardo Silva No comments »

Tanto se fala que você não deve duplicar código, mas quando se trata de desenvolvimento para iOs é o que eu mais vejo. Especialmente com bibliotecas de terceiros como JSON e ASIHTTPRequest. A gente sempre acaba com várias cópias deles nos projetos, às vezes com diferentes versões.

Bibliotecas estáticas ajuda o programador a resolver este problema.

Para criar o seu projeto de biblioteca estática escolha o template Cocoa Touch Static Library que está sob a opção Framework & Library. Neste projeto você deve efetuar as seguintes mudanças:

  • Marque como public os cabeçalhos que deseja publicar. Isto pode ser feito em Build Phases/Copy Headers em seu target.
  • Configure o Installation Directory para $(BUILT_PRODUCTS_DIR).
  • Escolha Yes para a opçãoSkip Install.
  • Configure Public Headers Folder Path para $(TARGET_NAME).

Este projeto então pode ser utilizado por outros. O recomendado é utilizar uma workspace. Você tanto pode salvar um projeto já existente como workspace ou criar uma vazia e adicionar ambos os projetos a ela, tendo o cuidado de não arrastar o arquivo .xcodeproj dentro de outro projeto já existente na mesma. Os projetos devem estar no mesmo nível!

Então, siga estes passos:

  • Adicione a sua biblioteca na lista Link Binary With Libraries.
  • Modifique User Header Search Paths para $(BUILT_PRODUCTS_DIR) recursivamente.
  • Você pode precisar usar a flag -ObjC em Other Linker Flags se você fizer uso de categorias. Você também talvez possa precisar de adicionar as flags -all_load e -force_load em algumas situações.

Automatic Reference Counting com Frameworks

outubro 12th, 2011 by Ricardo Silva No comments »

ARC é uma tecnologia em tempo de compilação que resulta em uma notável melhora de perfomance. O compilador adiciona as chamadas para retain/release/autorelease no lugar do programador. Nada muda em tempo de execução, o que permite que ARC possa ser ativado e desativado por arquivo ao compilar o seu projeto.

Se você precisa utilizar frameworks de terceiros que não estão disponíveis como bibliotecas estáticas e não suportam ARC em projetos ARC, você pode especificar flags de compilação por aquivo.

Com Xcode 4.2, você pode utilizar -fno-objc-arc para os arquivos do framework, como JSONKit.

Etapas:

  1. Selecione o projeto;
  2. Selecione o target;
  3. Abra a aba “Build Phases”;
  4. Abra “Compile Sources (nn items)”;
  5. Na segunda coluna, especifique “Compiler Flags”. Adicione a flag -fno-objc-arc aos arquivos desejados.

Adeus, EXC_BAD_ACCESS!

agosto 28th, 2011 by Ricardo Silva No comments »

O erro EXC_BAD_ACCESS acontece quando uma mensagem é enviada para um ponto na memória onde não existe nenhum objeto, por isso “bad access”. Na maioria das vezes a mensagem está sendo enviada para uma variável não inicializada ou já liberada (released).

No caso dos objetos já liberados, você pode ativar os zumbis para ajudar a encontrar estas variáveis. Para ativá-los, edite o esquema: em “Run”, abra a tab “Arguments” e adicione uma variável chamada NSZombieEnabled com valor YES em “Environment Variables”. Enquanto ativado, sempre que um objeto for liberado, um zumbi será colocado em seu lugar…

Importante: lembre-se de desativar os zumbis antes de enviar seu aplicativo para a App Store. Também é uma boa ideia desativá-los quando você não precisar deles.

Uso correto do MapKit

junho 24th, 2011 by Ricardo Silva No comments »

Eu já vi alguns aplicativos serem rejeitados por causa do mal uso do MapKit, violando os termos de uso do serviço de mapas do Google. Geralmente isso acontece porque o logo do Google foi ocultado/coberto.

Ao utilizar o MapKit você precisa ter certeza de que o logo do Google estará sempre visível. Uma boa dica é utilizar a seguinte máscara:

mapView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);

Apresentando HttpServletResponse como download de arquivo

junho 17th, 2011 by Ricardo Silva No comments »

O seguinte código apresentará o arquivo em forma de download em vez de ser visualizado no browser. A chave aqui é o cabeçalho Content-disposition.

protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException
{
	byte[] data = null;
	// carregar dados
 
	resp.reset();
	resp.setContentType("image/png");
	resp.setHeader("Content-disposition", "attachment; filename=image.png");
 
	final OutputStream output = resp.getOutputStream();
	output.write(data);
	output.close();
}

Compilação Condicional

junho 16th, 2011 by Ricardo Silva No comments »

Às vezes você precisa trabalhar com configurações diferentes quando você usa o simulador (ou mesmo o seu aparelho de testes). Por exemplo, um cenário em que você precisa usar um servidor de testes/desenvolvimento em vez do de produção para realizar seus testes ou quando você trabalha com In App Purchases.

Para isso a gente pode usar a compilação condicional. Ao contrário do “if” das linguagens de programação, onde o código dos blocos “if” e “else” fazem parte do binário mas somente um deles é executado de acordo com uma condição (mas ambos podem ser executados), este “if” é usado no momento da compilação e a condição negada não fará parte do binário.

Para funcionar você precisa adicionar uma flag para o compilador. No caso do exemplo abaixo, -DDEBUG_BUILD. (Não existe espaço depois do -D).

#ifdef DEBUG_BUILD
    #define SERVER_URL_STRING @"http://desenvolvimento.servidor.com.br"
#else
    #define SERVER_URL_STRING @"http://producao.servidor.com.br"
#endif

NSLog(“Alô, mundo!”)

maio 27th, 2011 by Ricardo Silva No comments »

Todo mundo sabe que o debug é um passo importante durante o desenvolvimento de qualquer software e que o log é um grande parceiro dele. No entanto você pode ter uma certa dor de cabeça após esta fase, quando logar não for mais necessário, e você precisar removê-lo do código. Para resolver este problema você tem o apoio das macros.

#ifdef DEBUG
#   define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#   define DLog(...)
#endif
 
// ALog sempre imprimirá o log, não importando se está em modo de DEBUG ou não
#define ALog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);

Com o código acima você pode utilizar DLog para logar somente no modo de debug e ALog para logar sempre.

Sugiro sue você coloque este código no arquivo .pch ou crie um novo arquivo (por exemplo, Log.h) que você pode reutilizar entre seus projetos e importá-lo no arquivo .pch ou sempre que precisar.

#import “Log.h”

Para que este código funcione você precisa adicionar a flag -DDEBUG na opção “Other C Flags” na configuração de seu projeto.

Um versão mais simples do código seria esta:

#ifdef DEBUG
#	define DLog(...) NSLog(__VA_ARGS__)
#else
#	define DLog(...) /* */
#endif
#define ALog(...) NSLog(__VA_ARGS__)