使用xctool自动打包,测试xcode项目

xctool是facebook开源的一个命令行工具,用来替代苹果的xcodebuild工具。

功能如下:

  • 像xcode一样跑测试用例
  • 结构化输出编译测试结果
  • 彩色且方便阅读的编译内容输出

示例截图:

xctool

如何安装xctool

最简单的办法是通过homebrew安装xctool

brew update
brew install xctool

搞定

如何使用xctool

打包


path/to/xctool.sh 
  -workspace YourWorkspace.xcworkspace 
  -scheme YourScheme 
  archive

build

path/to/xctool.sh 
  -workspace YourWorkspace.xcworkspace 
  -scheme YourScheme 
  build

测试

path/to/xctool.sh 
  -workspace YourWorkspace.xcworkspace 
  -scheme YourScheme 
  test

干掉xcode 4.2里的performselector警告

xcode 4.2非常可恶,原来的代码里有调用performselector:withObject:的地方无一例外获得一个警告:

Semantic Issue
PerformSelector may cause a leak because its selector is unknown

warning倒是不影响程序运行,但是这人要是有点代码小洁癖的话,那日子就没法过了,这warning怎么看都碍眼。所以必须得想办法把它弄没了:

#pragma clang diagnostic push
#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"
    [self performSelector:nextView];
#pragma clang diagnostic pop

世界清静啦

实战three20的TTTableViewController自定义单元格

three20中的TTTableCaptionItem实际使用效果是,左侧是较小字体的标题,右侧是大号字体的文本,如下图所示

但是在实际使用中,我希望左侧的字体能变大,右侧字体变小,所以我参照wiki的介绍 在TTTableViewController定制单元格 来进行调整,按文中介绍,我需要实现:

  1. 自定义的tableItem
  2. 自定义的tableItemCell
  3. 自定义的datasource,以便支持新增的tableItem

但是考虑到three20的代码库中已经有个半成品的TTTableRightCaptionItem,所以我只需要在这个基础上加工一下。

实现TTTableTextCaptionItem

我将这个自定义的类命名为TTTableTextCaptionItem以示区别

TTTableTextCaptionItem

TTTableTextCaptionItem.h


#import 

@interface TTTableTextCaptionItem : TTTableRightCaptionItem {
}

@end

TTTableTextCaptionItem.m


#import "TTTableTextCaptionItem.h"

@implementation TTTableTextCaptionItem
@end

TTTableTextCaptionItemCell

TTTableTextCaptionItemCell.h


#import 

@interface TTTableTextCaptionItemCell : TTTableRightCaptionItemCell {
}
@end

TTTableTextCaptionItemCell.m


#import "TTTableTextCaptionItem.h"
#import "TTTableTextCaptionItemCell.h"

static const CGFloat kKeySpacing = 12;
static const CGFloat kKeyWidth = 75;

@implementation TTTableTextCaptionItemCell

///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark UIView


///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)layoutSubviews {
    [super layoutSubviews];
    
    self.detailTextLabel.frame = CGRectMake(kTableCellHPadding, kTableCellVPadding,
                                      kKeyWidth, self.textLabel.font.ttLineHeight);
    
    CGFloat valueWidth = self.contentView.width - (kTableCellHPadding*2 + kKeyWidth + kKeySpacing);
    CGFloat innerHeight = self.contentView.height - kTableCellVPadding*2;
    self.textLabel.frame = CGRectMake(kTableCellHPadding + kKeyWidth + kKeySpacing,
                                            kTableCellVPadding,
                                            valueWidth, innerHeight);
}

///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark TTTableViewCell


///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setObject:(id)object {
    if (_item != object) {
        [super setObject:object];
        
        TTTableTextCaptionItem* item = object;
        self.textLabel.text = item.text;
        self.detailTextLabel.text = item.caption;
    }
}

@end

如何使用TTTableTextCaptionItem

首先实现一个自定义的DataSource,然后在后续代码中使用这个DataSource

#import "TTTableTextCaptionItemCell.h"
#import "TTTableTextCaptionItem.h"

@interface MyCustomDataSource : TTSectionedDataSource
@end

@implementation MyCustomDataSource

- (Class)tableView:(UITableView*)tableView cellClassForObject:(id)object {
    if ([object isKindOfClass:[TTTableTextCaptionItem class]]) {
        return [TTTableTextCaptionItemCell class];
    } else {
        return [super tableView:tableView cellClassForObject:object];
    }
}

@end

代码下载

我把代码放到github上,方便大家参考 TTTableTextCaptionItem.git

如何将TTURLRequest和OAuthConsumer搭配使用

TTURLRequest是three20开发框架提供的一个url请求类,它是NSURLRequest类的扩展,有如下优点:

  • post数据方便,只需要构建一个参数的dictionary就可以了,像get方法一样简单
  • 支持磁盘缓存,而NSURLRequest仅支持内存缓存
  • 因为TTTableViewController + TTURLRequestModel的存在,搭配使用效果良好

在ios的开发中我有时也用到了OAuthConsumer进行oauth授权,利用OAuthConsumer的fetcher类请求远程数据,所以我想TTURLRequest和OAuthConsumer能不能搭配使用,这样就能用上three20相关便利方法加载远程数据。于是做了点简单的测试,果然成功了:)大体思路是:

  • 先利用OAuthConsumer根据提交的参数计算出oauth的Authorization认证头
  • 把Authorization头加到TTURLRequest
  • 由TTURLRequest提交数据。

直接上代码说话:

计算Authorization头

利用OAuthConsumer计算出Authorization头,为之后的请求做准备


//start
OAConsumer * consumer = [[OAConsumer alloc] initWithKey:yourConsumerKey secret:yourSecret];
NSURL * url = [NSURL URLWithString:@"http://your-api-host/your-method"];
OAToken * authToken = [[OAToken alloc] initWithKey:yourAuthToken secret:yourAuthSecrent];
OAMutableURLRequest * request = [[OAMutableURLRequest alloc] initWithURL:url 
                                                                consumer:consumer 
                                                                   token:authToken 
                                                                   realm:nil 
                                                       signatureProvider:[[[OAPlaintextSignatureProvider alloc] init] autorelease]];
[request setHTTPMethod:@"POST"];

NSMutableArray * params = [NSMutableArray array];
OARequestParameter * p1 = [[OARequestParameter alloc] initWithName:@"param1" value:@"i'm param1"];
[params addObject:p1];

[request setParameters:params];
[request prepare];

TTDINFO(@"Authorization is %@", [request valueForHTTPHeaderField:@"Authorization"]);

使用TTURLRequest请求数据

将Authorization头附加到TTURLRequest,然后请求远程接口


TTURLRequest* req = [TTURLRequest requestWithURL:request.URL.absoluteString delegate:self];
req.response = [[[TTURLDataResponse alloc] init] autorelease];
req.httpMethod = @"POST";
req.cachePolicy = TTURLRequestCachePolicyNone;
[req setValue:[request valueForHTTPHeaderField:@"Authorization"] forHTTPHeaderField:@"Authorization"];
[req send];

这个方法不需要对TTURLRequest进行修改,简单有效。

一个关于three20开发框架的wiki

我最近花了不少时间做iphone上的app,由于是刚刚接触objective-c,需要从头学习的东西比较多。我从使用facebook开源的three20开发框架来学习ios应用开发,这种方式不能说是最好的学习方式,但是我也从中获得了不少乐趣。

关于three20的中文资料不是太多,所以我搜集整理翻译了一些内容,放到了wiki上:

three20  wiki

本人才疏学浅,翻译的内容难免出错或者词不达意,欢迎批评指正。