开始
你有两个选择开始本教程:您可以使用在本教程的第1部分你已完成的项目,或者你可以在这里下载第1部分已完成的项目。
在前面的教程中你创建了你的App的天气模型 – 现在你需要使用OpenWeatherMap API为你的App来获取一些数据。你将使用两个类抽象数据抓取、分析、存储:WXClient
和WXManager
。
WXClient
的唯一责任是创建API请求,并解析它们;别人可以不用担心用数据做什么以及如何存储它。划分类的不同工作职责的设计模式被称为关注点分离。这使你的代码更容易理解,扩展和维护。
与ReactiveCocoa工作
确保你使用SimpleWeather.xcworkspace
,打开WXClient.h
并增加imports
1 2 |
@import CoreLocation; #import <ReactiveCocoa/ReactiveCocoa/ReactiveCocoa.h> |
1 |
注意:您可能之前没有见过的@import指令,它在Xcode5中被引入,是由苹果公司看作是一个现代的,更高效的替代 #import。有一个非常好的教程,涵盖了最新的Objective-C特性-[What’s New in Objective-C and Foundation in iOS 7](http://www.raywenderlich.com/49850/whats-new-in-objective-c-and-foundation-in-ios-7)。 |
在WXClient.h
中添加下列四个方法到接口申明:
1 2 3 4 5 |
@import Foundation; - (RACSignal *)fetchJSONFromURL:(NSURL *)url; - (RACSignal *)fetchCurrentConditionsForLocation:(CLLocationCoordinate2D)coordinate; - (RACSignal *)fetchHourlyForecastForLocation:(CLLocationCoordinate2D)coordinate; - (RACSignal *)fetchDailyForecastForLocation:(CLLocationCoordinate2D)coordinate; |
现在,似乎是一个很好的机会来介绍ReactiveCocoa!
ReactiveCocoa(RAC)是一个Objective-C的框架,用于函数式反应型编程,它提供了组合和转化数据流的API。代替专注于编写串行的代码 – 执行有序的代码队列 – 可以响应非确定性事件。
Github上提供的a great overview of the benefits:
- 对未来数据的进行组合操作的能力。
- 减少状态和可变性。
- 用声明的形式来定义行为和属性之间的关系。
- 为异步操作带来一个统一的,高层次的接口。
- 在KVO的基础上建立一个优雅的API。
例如,你可以监听username
属性的变化,用这样的代码:
1 2 3 |
[RACAble(self.username) subscribeNext:^(NSString *newName) { NSLog(@"%@", newName); }]; |
subscribeNext
这个block会在self.username
属性变化的时候执行。新的值会传递给这个block。
您还可以合并信号并组合数据到一个组合数据中。下面的示例取自于ReactiveCocoa的Github页面:
1 2 3 4 5 6 7 8 |
[[RACSignal combineLatest:@[ RACAble(self.password), RACAble(self.passwordConfirmation) ] reduce:^(NSString *currentPassword, NSString *currentConfirmPassword) { return [NSNumber numberWithBool:[currentConfirmPassword isEqualToString:currentPassword]]; }] subscribeNext:^(NSNumber *passwordsMatch) { self.createEnabled = [passwordsMatch boolValue]; }]; |
RACSignal对象捕捉当前和未来的值。信号可以被观察者链接,组合和反应。信号实际上不会执行,直到它被订阅。
这意味着调用[mySignal fetchCurrentConditionsForLocation:someLocation];
不会做什么,但创建并返回一个信号。你将看到之后如何订阅和反应。
打开WXClient.m
加入以下imports:
1 2 |
#import "WXCondition.h" #import "WXDailyForecast.h" |
在imports下,添加私有接口:
1 2 3 4 5 |
@interface WXClient () @property (nonatomic, strong) NSURLSession *session; @end |
这个接口用这个属性来管理API请求的URL session。
添加以下init
放到到@implementation
和@end
之间:
开始
你有两个选择开始本教程:您可以使用在本教程的第1部分你已完成的项目,或者你可以在这里下载第1部分已完成的项目。
在前面的教程中你创建了你的App的天气模型 – 现在你需要使用OpenWeatherMap API为你的App来获取一些数据。你将使用两个类抽象数据抓取、分析、存储:WXClient
和WXManager
。
WXClient
的唯一责任是创建API请求,并解析它们;别人可以不用担心用数据做什么以及如何存储它。划分类的不同工作职责的设计模式被称为关注点分离。这使你的代码更容易理解,扩展和维护。
与ReactiveCocoa工作
确保你使用SimpleWeather.xcworkspace
,打开WXClient.h
并增加imports
1 2 |
@import CoreLocation; #import <ReactiveCocoa/ReactiveCocoa/ReactiveCocoa.h> |
1 |
注意:您可能之前没有见过的@import指令,它在Xcode5中被引入,是由苹果公司看作是一个现代的,更高效的替代 #import。有一个非常好的教程,涵盖了最新的Objective-C特性-[What’s New in Objective-C and Foundation in iOS 7](http://www.raywenderlich.com/49850/whats-new-in-objective-c-and-foundation-in-ios-7)。 |
在WXClient.h
中添加下列四个方法到接口申明:
1 2 3 4 5 |
@import Foundation; - (RACSignal *)fetchJSONFromURL:(NSURL *)url; - (RACSignal *)fetchCurrentConditionsForLocation:(CLLocationCoordinate2D)coordinate; - (RACSignal *)fetchHourlyForecastForLocation:(CLLocationCoordinate2D)coordinate; - (RACSignal *)fetchDailyForecastForLocation:(CLLocationCoordinate2D)coordinate; |
现在,似乎是一个很好的机会来介绍ReactiveCocoa!
ReactiveCocoa(RAC)是一个Objective-C的框架,用于函数式反应型编程,它提供了组合和转化数据流的API。代替专注于编写串行的代码 – 执行有序的代码队列 – 可以响应非确定性事件。
Github上提供的a great overview of the benefits:
- 对未来数据的进行组合操作的能力。
- 减少状态和可变性。
- 用声明的形式来定义行为和属性之间的关系。
- 为异步操作带来一个统一的,高层次的接口。
- 在KVO的基础上建立一个优雅的API。
例如,你可以监听username
属性的变化,用这样的代码:
1 2 3 |
[RACAble(self.username) subscribeNext:^(NSString *newName) { NSLog(@"%@", newName); }]; |
subscribeNext
这个block会在self.username
属性变化的时候执行。新的值会传递给这个block。
您还可以合并信号并组合数据到一个组合数据中。下面的示例取自于ReactiveCocoa的Github页面:
1 2 3 4 5 6 7 8 |
[[RACSignal combineLatest:@[ RACAble(self.password), RACAble(self.passwordConfirmation) ] reduce:^(NSString *currentPassword, NSString *currentConfirmPassword) { return [NSNumber numberWithBool:[currentConfirmPassword isEqualToString:currentPassword]]; }] subscribeNext:^(NSNumber *passwordsMatch) { self.createEnabled = [passwordsMatch boolValue]; }]; |
RACSignal对象捕捉当前和未来的值。信号可以被观察者链接,组合和反应。信号实际上不会执行,直到它被订阅。
这意味着调用[mySignal fetchCurrentConditionsForLocation:someLocation];
不会做什么,但创建并返回一个信号。你将看到之后如何订阅和反应。
打开WXClient.m
加入以下imports:
1 2 |
#import "WXCondition.h" #import "WXDailyForecast.h" |
在imports下,添加私有接口:
1 2 3 4 5 |
@interface WXClient () @property (nonatomic, strong) NSURLSession *session; @end |
这个接口用这个属性来管理API请求的URL session。
添加以下init
放到到@implementation
和@end
之间: