代码改变世界

CocoaPods简介——依赖关系管理工具

2013-09-12 18:02  张智清  阅读(1530)  评论(0编辑  收藏  举报

作为一个iOS开发者,你肯定会使用第三方库。通常,我们直接把第三方库的源代码直接加入到我们的项目中(手动创建一个static library还是很无聊滴),但是这么做有一些缺点:

  • 浪费空间。源代码可能已经存在你的代码托管中
  • 有些时候,很难获得某个具体版本的第三方库
  • 没有一个集中的地方可以查看哪些库现在可以使用
  • 更新新版本的时候,是件无聊的事情,有些时候还很痛苦

一个依赖关系管理工具可以帮助你克服大部分上面提到的问题。它会帮你下载你所用到的库的源代码、创建和维护你所需要的环境。

 

 

安装CocoaPods

安装RubyGems

CocoaPods需要ruby环境,幸运的是所有的mac电脑都已经预装了ruby,所以你需要更新一下你的RubyGems(如果你的系统版本低于OS X Lion)

只需要输入如下命令就可以更新你的RubyGems:

sudo gem update --system

安装command line工具

确保你在你的Xcode中安装了command line tool(命令行工具)。在最新的Mac OS X Lion和Xcode中,命令行工具默认没有安装。可以通过如下方式安装command line tool:

  • 这里下载,然后安装
  • 打开xcode,打开components界面。Xcode->Preferences->Downloads->Components.里面应该有一个选项是"Command Line Tools",后面应该“Install”或者“Update”按钮,点一下按钮就行。

    安装完成后,按钮的文字会变成“Installed”。如下图:

    Install Xcode Command Line

安装CocoaPods

完成以上步骤后,只需要输入如下命令就可以安装CocoaPods了:

$ sudo gem install cocoapods

$ pod setup

第一次安装可能需要一些时间,耐心等待一下

创建一个“CocoaPodsExample”工程

打开Xcode,然后创建一个基于“Single View Application”的工程。工程的名字“CocoaPodsExample”,“Device Family”选为“iPhone”,选中“Use Storyboards”和“Use Automatic Reference Counting”。如下图:

Create CocoaPodsExample

点击下一步然后选择一个地方存放你的工程。

找一张图片作为Launch Images。如果没有合适的可以下载这一张-placeholder.png。把这张图片拖到工程中,选中“Copy items into destination group's folder(if needed)”。

下面打开MainStoryboard.storyboard,并按照如下步骤进行修改:

  1. 添加一个scroll view。确保这个scroll view的宽度和高度是100%
  2. 修改scroll view的属性。打开属性选择器,不选“Shows Horizontal Scrollers”,"Shows Verticall Scollers"。选中“Scrolling Enabled”, “Paging Enabled”, “Direction Lock Enabled”
  3. 添加一个page control。确保这个page control是之前scroll view的兄弟视图,而不是scroll view的子视图,并且page control应该在scroll view的前面,不然你就看不到page control了。

storyboard应该看起来像下图:

Storyboard

最后把scroll view和page view连接到一个outlet中,我们把scroll view的outlet命名为showsScrollView,并且把当前的view controller做为scroll view的delegate。把page control的outlet命名为showPageControl,给page control的“Value Changed”事件绑定一个方法,方法名称是pageChanged。

现在你可以关了你的Xcode了,接下来就是开始创建你的Podfile了。

创建你的第一个依赖关系

打开终端,并且打开存放你的“CocoaPodsExample”工程的文件夹。输入如下命令:

touch Podfile
open -e Podfile

TextEdit会被打开,你可以往打开的空白Podfile中添加内容了。

我们往Podfile中加入如下内容:

    
platform :ios, '5.0'
pod 'AFNetworking', '0.9.1'

如你所见,Podfile的格式很简单。首先,你设置platform为ios(因为有一些框架只支持iOS或者Mac OS X中的一个,而不是都有)。然后,你添加你的第一个依赖-“AFNetworking”,并且指定了,你需要的是0.9.1。

编辑Podfile,除了上面的方法,你还可以使用别的你喜欢的编辑工具,比如vim

有关Podfile的格式,你可以在A PodfilePodfile(frames)中得到更详细信息

保存Podfile之后,我们可以开始配置你的工程了。

在终端中执行如下命令:

$ pod install

执行完后,你应该会在终端中看到下图:

Pod Install Log

如果这个时候,你打开你工程所在的文件夹会看到下图:

CocoaPods Project Folder

CocoaPods创建了一个文件夹-“Pods”,这个文件夹存放了所有的依赖的库和一个workspace文件,CocoaPodsExample.xcworkspace

VERY IMPORTANT!

从现在开始,你必须用workspace文件(CocoaPodsExample.xcworkspace)打开工程而不是再是用工程文件(CocoaPodsExample.xcodeproj)

测试AFNetworking

测试AFNetworking是否成功加入已经CocoaPods是否真的工作,可以创建一个基于iOS/Cocoa Touch/Objective-C class的类,我们称之为SKTraktAPIClient,并且是这个类是NSObject的子类。切记把这个类加入到CocoaPodsExample中而不是Pods工程中。如果你现在看一下你工程文件的导航,你会看到有两个独立的项目:CocoaPodsExample和Pods

打开SKTraktAPIClient.h,并且用如下代码替换已有代码:

    
#import <Foundation/Foundation.h>
#import <AFNetworking/AFHTTPClient.h>

extern NSString *const kTraktAPIKey;
extern NSString *const kTraktBaseURLString;

@interface SKTrakeAPIClient : AFHTTPClient

+(SKTrakeAPIClient *)sharedClient; 

@end

上面的代码做了如下事情:

  1. 第一行代码导入Foundation头文件
  2. 第二行代码导入AFNetworking的头文件,AFNetworking将会是SKTraktAPIClient的头文件
  3. 接下来的两行定了两个变量
  4. 最后我们定义了一个方法,该方法会返回一个独立的SKTraktAPIClient实力

为什么在已经有AFNetworking可以处理所有的HTTP请求的情况下,我们还要创建一个SKTraktAPIClient类?原因就在于,我们希望有一个类可以处理所有我们和trakt.tv的请求,可以使用同样的Base URL和api key。这样子可以方便之后的维护。

现在打开SKTraktAPIClient.m,并且用如下的代码替换已有的代码:

    
#import "SKTraktAPIClient.h"
#import <AFJSONRequestOperation.h>

NSString *const kTraktAPIKey = @"fc3df235908f83107cedd7914950d7a0";
NSString *const kTraktBaseURLString = @"http://api.trakt.tv";

@implementation SKTraktAPIClient

+(SKTraktAPIClient *)sharedClient{
    static SKTraktAPIClient *_sharedClient = nil;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedClient = [[self alloc] initWithBaseURL:[NSURL URLWithString:kTraktBaseURLString]];
    });
    return _sharedClient;
}

-(id)initWithBaseURL:(NSURL *)url{
    self = [super initWithBaseURL:url];
    if(!self){
        return nil;
    }
    [self registerHTTPOperationClass:[AFJSONRequestOperation class]];
    [self setDefaultHeader:@"Accept" value:@"application/json"];
    self.parameterEncoding = AFJSONParameterEncoding;
    return self;
}
@end

首先我们导入了AFJSONRequestOperation.h,这样子所有的返回值都是JSON格式的。我们创建了sharedClient,这里使用了GCD(Grand Central Dispatch),确保了实现SKTraktAPIClient的单例,随意只要是通过sharedClient方法获得的SKTraktAPIClient都是同一个实例,不会重复创建。除了这个以外,我们还重写了initWithBaseURL方法,原因就是之后所有用initiWithBaseURL创建的方法,它们都有同样的response格式-json格式

下面打开AppDelegate.m加入下面代码:

    
#import <AFNetworking.h>
    

application:didFinishLaunchingWithOptions:加入如下代码:

    
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
    

以上代码开启了automatic network activity indication manager,这个是AFNetworking支持的功能。通过这种方法,你就不需要每次发送请求打开activity indication,完成后关闭activity indication。

现在打开ViewController.m,并且加入如下代码:

    
#import "SKTraktAPIClient.h"
#import <AFNetworking.h>
    

并用如下代码替换viewDidLoad

    
-(void)viewDidLoad {
    [super viewDidLoad];
    // 1 - Create trakt API client
    SKTraktAPIClient* client = [SKTraktAPIClient sharedClient];
    // 2 - Create date instance with today's date
    NSDate* today = [NSDate date];
    // 3 - Create date formatter
    NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormat = @"yyyyMMdd";
    NSString* todayString = [formatter stringFromDate:today];
    // 4 - Create API query request
    NSString* path = [NSString stringWithFormat:@"user/calendar/shows.json/%@/%@/%@/%d", kTraktAPIKey, @"marcelofabri", todayString, 3];
    NSURLRequest* request = [client requestWithMethod:@"GET" path:path parameters:nil];
    // 5 - Create JSON request operation
    AFJSONRequestOperation* operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        // 6 - Request succeeded block
        NSLog(@"%@", JSON);
    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        // 7 - Request failed block
    }];
    // 8 - Start request
    [operation start];
}

编译运行之后,你可以在你的控制台中看到类似下图的日志:

trakt.tv shows.json log

可见,CocoaPods正确帮我们配置了AFNetworking。