Desenvolvimento

26 jan, 2016

Bricks: o fim do Boilerplate iOS

Publicidade

*Este artigo foi originalmente publicado no Medium pessoal do autor, em inglês. Confira aqui.

Mais um dia, mais um projeto, nada novo na vida de um desenvolvedor iOS que trabalha em uma empresa com diversos novos projetos. Durante o ano passado, eu trabalhei em muitos produtos diferentes e mais de uma vez eu me achei repetindo os mesmos padrões antigos, aplicando o mesmo boilerplate, de projeto em projeto.

Em cada novo desafio, o conhecimento e a experiência aumentam. Ainda que essa declaração seja verdade na maioria das vezes, faltava algo. Esse algo me motivou a criar um pod junto com meu amigo Jonas Tomaz, que é responsável por muitas das ideias por trás do Bricks e por inúmeras discussões e reflexões sobre arquitetura e design durante diversos anos de trabalho juntos.

Chamamos esse pod de Bricks. Ele é bastante simples, porém poderoso. Depois desse primeiro release, já usamos em outros projetos e o aumento de produtividade foi enorme.

Nuff Said. O que isso faz?

Contém helper methods para muitas das tarefas diárias, como:

TableViewCells | CollectionViewCells

Se você seguir a convenção que cada cellIdentifier ou xib terá o nome de Cell class, você não tem muito o que fazer, apenas ter certeza de que a sua tableViewCell estende a BKBaseTableViewCell e você está pronto para seguir. Não é mais necessário se preocupar com cellIdentifier, registerOnTableView, cellHeight  e outras coisas do Boilerplate. O pod possui também um versão similar para tratar casos que usam collectionviewcell.

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "BKBaseTableViewCellDelegate.h"

@protocol BKBaseTableViewCellDelegate <NSObject>
+(CGFloat)cellHeight;

+(NSString *)cellIdentifier;
-(void)setup:(id)object;

@optional
+(void)registerForTableView:(UITableView*)tableview;
+(CGFloat)cellHeightWithPadding:(CGFloat)padding;
@end

@interface BKBaseTableViewCell : UITableViewCell<BKBaseTableViewCellDelegate>

@end

@implementation BKBaseTableViewCell

+(CGFloat)cellHeightWithPadding:(CGFloat)padding{
    return [self cellHeight] + padding;
}

+(CGFloat)cellHeight{
    return 0;
}

+(NSString *)cellIdentifier{
    NSString *identifier = NSStringFromClass(self.class);
    return identifier;
}

-(void)setup:(id)object{
    
}

+(void)registerForTableView:(UITableView*)tableview{
    NSString *identifier = NSStringFromClass(self.class);
    UINib *nib = [UINib nibWithNibName:identifier bundle:nil];
    [tableview registerNib:nib forCellReuseIdentifier:[self cellIdentifier]];
}

@end

Json -> Obj com Mantle

Como grandes fãs do Mantle, adicionamos um helper para ele também, que se tornou muito útil. Com ele, prevenimos a exposição do Mantle a outras partes do nosso código que não são modelos.

@interface BKBaseMantleObj : MTLModel<MTLJSONSerializing>

+ (NSDictionary *)JSONKeyPathsByPropertyKey;
+(instancetype)parse:(NSDictionary*)dc error:(NSError**)error;
-(NSDictionary*)asDictError:(NSError**)error;

@end

@interface BKBaseMantleObj (Collections)

+(NSArray*)asArrayOfDictFromModelArray:(NSArray*)objects error:(NSError**)error;
+(NSArray*)parseArray:(NSArray*)objs error:(NSError**)error;

@end

@implementation BKBaseMantleObj

+ (NSDictionary *)JSONKeyPathsByPropertyKey {
    return [NSDictionary mtl_identityPropertyMapWithModel:self.class];
}

-(NSDictionary*)asDictError:(NSError**)error{
    return  [MTLJSONAdapter JSONDictionaryFromModel:self error:error];
}

+(instancetype)parse:(NSDictionary*)dc error:(NSError**)error{
    return [MTLJSONAdapter modelOfClass:self.class
                     fromJSONDictionary:dc
                                  error:error];
}

@end

@implementation BKBaseMantleObj (Collections)

+(NSArray*)asArrayOfDictFromModelArray:(NSArray*)objects error:(NSError**)error{
    return [MTLJSONAdapter JSONArrayFromModels:objects  error:error];
}

+(NSArray*)parseArray:(NSArray*)objs error:(NSError**)error{
    return [MTLJSONAdapter modelsOfClass:self.class
                           fromJSONArray:objs
                                   error:error];
}

@end

Pretendemos continuar adicionando features que julgarmos interessantes para a library do Bricks nas próximas semanas, mas até agora a versão 0.1.0 é bastante útil, simples e poderosa. Como sempre, os pull requests são bem-vindos.

Durante o ano passado, eu criei vários pods e gems para ajudar os desenvolvedores iOS (e a mim próprio dentro da Concrete). Vocês podem conferir nos links abaixo:

Ficou alguma dúvida, tem alguma sugestão ou crítica? Aproveite os campos abaixo e até a próxima!