ReactiveCocoa使用汇总多线程和UI控件的使用
1.并发请求数据
/****
*封装并发请求数据的类1
***/
@interface ConcurrentNetService : NSObject
+ (void)requestConcurrentNetData:(NSInteger)list_id type:(NSInteger)type forceReload:(BOOL)forceReload completion:(void (^)(NSArray <NSString *> *phones, NSArray <LiveNotificationModel *> *notes, NSArray <LiveInternetCardModel *> *cards, NSArray <LiveContentModel *> *contents, NSError *error))completionHandler;
@end
@implementation ConcurrentNetService
+ (void)requestConcurrentNetData:(NSInteger)list_id type:(NSInteger)type forceReload:(BOOL)forceReload completion:(void (^)(NSArray<NSString *> *, NSArray *, NSArray<LiveInternetCardModel *> *, NSArray<LiveContentModel *> *, NSError *))completionHandler
{
NSMutableArray *signals = [[NSMutableArray alloc] init];
//请求数据1
RACSignal *<#racSignal_1#> = [[[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
<#HTTPSessionManager#> *manager = [[<#HTTPSessionManager#> alloc] initWithPort:<#port#>];
#ifdef DEBUG
if (forceReload) {
manager.cachePolicy = RequestReloadIgnoringCacheData;
}else {
manager.cachePolicy = RequestReturnCacheDataDontLoad;
}
#else
manager.cachePolicy = RequestReloadIgnoringCacheData;
#endif
[manager POST:url_1 parameters:nil success:^(NSDictionary * _Nonnull responseDict) {
NSArray *<#modeArray_1#> = responseDict[kResponseDataKey];
[subscriber sendNext:<#modeArray_1#>];
[subscriber sendCompleted];
} failure:^(NSError * _Nonnull error) {
[subscriber sendError:error];
}];
return nil;
}];
}] execute:nil];
[signals addObject:<#racSignal_1#>];
//请求数据2
RACSignal *<#racSignal_2#> = [[[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
//其他封装的请求类中的请求数据方法
[<#OtherService_1#> requestOtherData:forceReload type:2 completion:^(NSArray<OtherModel_1 *> *<#modeArray_1#>, NSError *error) {
if (!error) {
[subscriber sendNext:<#modeArray_1#>];
[subscriber sendCompleted];
}else {
[subscriber sendError:error];
}
}];
return nil;
}];
}] execute:nil];
[signals addObject:<#racSignal_2#>];
// 请求数据3
RACSignal *<#racSignal_3#> = [[[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
NSString *URLString = [NSString stringWithFormat:@"%@", stringUrl];
<#HTTPSessionManager#> *manager = [[<#HTTPSessionManager#> alloc] initWithPort:<#Port#>];
#ifdef DEBUG
if (forceReload) {
manager.cachePolicy = RequestReloadIgnoringCacheData;
}else {
manager.cachePolicy = RequestReturnCacheDataDontLoad;
}
#else
manager.cachePolicy = RequestReloadIgnoringCacheData;
#endif
[manager POST:URLString parameters:nil success:^(NSDictionary * _Nonnull responseDict) {
NSArray *json = responseDict[kResponseDataKey];
//mjExtension中的字典转模型
NSArray *<#modeArray_3#> = [NSArray modelArrayWithClass:[Mode_3 class] json:json];
[subscriber sendNext:<#modeArray_3#>];
[subscriber sendCompleted];
} failure:^(NSError * _Nonnull error) {
[subscriber sendError:error];
}];
return nil;
}];
}] execute:nil];
[signals addObject:<#racSignal_3#>;
// 请求数据4
RACSignal *<#racSignal_4#> = [[[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
//请他请求封装类中的请求方法
[<#OtherService_2#> requestData:<#参数#> type:<#参数#> pageIndex:1 pageSize:10 forceReload:forceReload completion:^(NSArray<<#Model_4#> *> *<#modeArray_4#>, NSError *error) {
if (!error) {
[subscriber sendNext:<#modeArray_4#>];
[subscriber sendCompleted];
}else {
[subscriber sendError:error];
}
}];
return nil;
}];
}] execute:nil];
[signals addObject:<#racSignal_4#>];
//最有结合所有的racSignal并发请求数据
[[RACSignal combineLatest:signals] subscribeNext:^(RACTuple * _Nullable x) {
RACTupleUnpack(NSArray *<#modeArray_1#>, NSArray *<#modeArray_2#>, NSArray *<#modeArray_3#>, NSArray *<#modeArray_4#>) = x;
if (completionHandler) {
completionHandler(<#modeArray_1#>, <#modeArray_2#>, <#modeArray_3#>, <#modeArray_4#>, nil);
}
} error:^(NSError * _Nullable error) {
if (completionHandler) {
completionHandler(nil, nil, nil, nil, error);
}
}];
}
@end
/*****
*在mvc中使用Rac机制封装的并发请求数据的方法
*请求参数、方法及数据可自己定制
***/
#pragma mark 请求直播列表数据
- (void)requestData:(BOOL)forceReload
{
[super requestData:forceReload];
[ConcurrentNetService requestLiveInternetData:<#参数#> type:<#参数#>forceReload:forceReload completion:^(NSArray <<#Model_1_Calss#> *> *<#modeArray_1#>, NSArray <<#Model_2_Calss#> *> *<#modeArray_2#>, NSArray<<#Model_3_Calss#> *> *<#modeArray_3#>, NSArray<<#Model_4_Calss#> *> *<#modeArray_4#>, NSError *error) {
[self.collectionView.mj_header endRefreshing];
if (!error) {
self.isEmpty = NO;
self.modelArray_1 = <#modeArray_1#>;
self.modelArray_1 = <#modeArray_2#>;
self.modelArray_1 = <#modeArray_3#>;
//定制的flowLayout
self.flowLayout.cards = <#modeArray_#>;
self.flowLayout.contents = <#modeArray_#>;
self.modelArray_4 = <#modeArray_4#>;
[self.collectionView reloadData];
}else {
//errorCode
}
}];
}
辅助的请他请求封装请求类
/***
OtherServece1的请求封装类中的方法
**/
#pragma mark 请求石油广告数据
+ (void)requestOtherData:(BOOL)forceReload type:(NSInteger)type completion:(void (^)(NSArray<<#Mode_Class_1#> *> *, NSError *))completionHandler
{
NSString *URLString = [NSString stringWithFormat:@"%@", strURL];
<#HTTPSessionManager#> *manager = [[ <#HTTPSessionManager#> alloc] initWithPort:<#kPort#>];
#ifdef DEBUG
if (forceReload) {
manager.cachePolicy = RequestReloadIgnoringCacheData;
}else {
manager.cachePolicy = RequestReturnCacheDataDontLoad;
}
#else
manager.cachePolicy = RequestReloadIgnoringCacheData;
#endif
[manager POST:URLString parameters:nil success:^(NSDictionary * _Nonnull responseDict) {
NSArray *json = responseDict[kResponseDataKey];
NSArray *modeArray_2 = [NSArray modelArrayWithClass:[<#Mode_1_calss#> class] json:json];
if (completionHandler) {
completionHandler(notes, nil);
}
} failure:^(NSError * _Nonnull error) {
if (completionHandler) {
completionHandler(nil, error);
}
}];
}
/****
*其他请求类找那个<#OtherService_1#>
***/
#pragma mark 请求直播列表更多数据
+ (void)requestOtherData:(NSInteger)<#参数#> type:(NSInteger)<#参数#> pageIndex:(NSUInteger)pageIndex pageSize:(NSUInteger)pageSize forceReload:(BOOL)forceReload completion:(void (^)(NSArray<<#Model_1_class#> *> *, NSError *))completionHandler
{
// NSString *URLString = [NSString stringWithFormat:@"%@/%lu/%lu/%li/%li/0/0", TVGetLiveListURL, pageSize, pageIndex, type, list_id];
NSDictionary *parameters = @{@"":@(1), @"":@(2), @"": @""};
<#HTTPSessionManager#> *manager = [[<#HTTPSessionManager#> alloc] initWithHost:<#HostName#> port:<#kPort端口#>];
#ifdef DEBUG
if (forceReload) {
manager.cachePolicy = RequestReloadIgnoringCacheData;
}else {
manager.cachePolicy = RequestReturnCacheDataDontLoad;
}
#else
manager.cachePolicy = RequestReloadIgnoringCacheData;
#endif
[manager POST:strURL parameters:parameters success:^(NSDictionary * _Nonnull responseDict) {
NSArray *json = responseDict[kResponseDataKey];
NSArray *modeArray_4 = [NSArray modelArrayWithClass:[<#Mode_4_Calss#> class] json:json];
if (completionHandler) {
completionHandler(modeArray_4, nil);
}
} failure:^(NSError * _Nonnull error) {
if (completionHandler) {
completionHandler(nil, error);
}
}];
}
/****
封装并发请求2
****/
- (void)requestConcurrentData:(ParamType)param forceReload:(BOOL)forceReload completion:(void (^)(NSArray<Model_1_Class *> *<#modelArray_1#>, NSArray *array_2, NSArray<Model_3_Class *> *<#modelArray_3#>, NSError *))completionHandler
{
// 请求横幅广告数据
RACCommand *<#command_1#> = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[LiveAdService requestLiveBannerAdData:forceReload listId:list_id completion:^(NSArray<<#Model_1_Class#> *> *<#modeArray_1#>, NSError *error) {
if (!error) {
[subscriber sendNext:<#modeArray_1#>];
[subscriber sendCompleted];
}else {
[subscriber sendError:error];
}
}];
return nil;
}];
}];
RACCommand *<#command_2#> = nil;
if (<#请求判断条件#>) {
<#command_2#> = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[<#OtherSerivese#> requestOtherData:forceReload type:2 completion:^(NSArray<<#Model_2_Calss#> *> *<#modelArray_2#>, NSError *error) {
if (!error) {
[subscriber sendNext:<#modelArray_2#>];
[subscriber sendCompleted];
}else {
[subscriber sendError:error];
}
}];
return nil;
}];
}];
}else {
<#command_2#> = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[<#OtherService_1#> requestOtherData:<#param#> pageSize:10 forceReload:forceReload completion:^(NSArray<<#Model_2_Class *> *<#modeArray_2#>, NSError *error) {
if (!error) {
[subscriber sendNext:<#modeArray_2#>];
[subscriber sendCompleted];
}else {
[subscriber sendError:error];
}
}];
return nil;
}];
}];
}
// 请求资讯数据
RACCommand *<#command_3#> = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[<#OtherService_2#> requestOtherData:<#param#> pageSize:10 forceReload:forceReload completion:^(NSArray<<#Model_3_Class *> *<#modeArray_3#>, NSError *error) {
if (!error) {
[subscriber sendNext:<#modeArray_3#>];
[subscriber sendCompleted];
}else {
[subscriber sendError:error];
}
}];
return nil;
}];
}];
RACSignal *<#racSignal_1#> = [<#command_1#> execute:nil];
RACSignal *<#racSignal_2#> = [<#command_2#> execute:nil];
RACSignal *<#racSignal_3#> = [<#command_3#> execute:nil];
[[RACSignal combineLatest:@[<#racSignal_1#>, <#racSignal_2#>, <#racSignal_3#>]] subscribeNext:^(RACTuple * _Nullable x) {
RACTupleUnpack(NSArray *<#modeArray_1#>, NSArray *<#modeArray_2#> NSArray *<#modeArray_3#>) = x;
if (completionHandler) {
completionHandler(<#modeArray_1#>, <#modeArray_2#>, <#modeArray_3#>, nil);
}
} error:^(NSError * _Nullable error) {
if (completionHandler) {
completionHandler(nil, nil, nil, error);
}
}];
}
2.使用RAC机制监控多个条件满足时,设置控件的状态变化
RACSignal *<#validSignal_1#> = [<#textField_1#>.rac_textSignal map:^id(NSString *text) {
return @([text isNotBlank]);
}];
RACSignal *<#validSignal_2#> = [<#textField_2#>.rac_textSignal map:^id(NSString *text) {
return @([text isNotBlank]);
}];
RACSignal *<#validSignal_3#> = [<#textField_3#>.rac_textSignal map:^id(NSString *text) {
return @([text isNotBlank]);
}];
//number类型的数据
RACSignal *<#validSignal_4#> = [RACObserve(self.model, id) map:^id _Nullable(NSNumber *value) {
return @(value.boolValue);
}];
RACSignal *<#validSignal_5#> = [RACObserve(self.model, listImagePath) map:^id _Nullable(NSString * _Nullable value) {
return @([value isNotBlank]);
}];
RACSignal *<#validSignal_6#> = RACObserve(otherButton, selected);
//综合多个条件
_validSignal = [[RACSignal combineLatest:@[<#validSignal_1#>, <#validSignal_2#>,<#validSignal_3#>, <#validSignal_4#>, <#validSignal_5#>, <#validSignal_6#>]] map:^id(RACTuple *tuple) {
RACTupleUnpack( NSNumber *<#valid_1#>,NSNumber *<#valid_2#>, NSNumber *<#valid_3#>, NSNumber *<#valid_4#>, NSNumber *<#valid_5#>,NSNumber *<#valid_6#>) = tuple;
return @([<#valid_1#> boolValue] && [<#valid_2#> boolValue]&& [<#valid_3#> boolValue] && [<#valid_4#> boolValue] && [<#valid_5#> boolValue] && [<#valid_6#> boolValue]);
}];
RAC(nextButton, enabled) = _validSignal;
RAC(self.navigationItem.rightBarButtonItem, enabled) = _validSignal;
RACSignal *validOutsizeLiveSignal = [RACObserve(self.model, PushPath) map:^id _Nullable(NSString * _Nullable value) {
return @(value.isNotBlank);
}];
RAC(linkButton, enabled) = validOutsizeLiveSignal;
3.数据并发请求
#pragma mark 搜索
+ (void)search:(NSString *)text completion:(void (^)(NSArray<<#SearchModel#> *> *, NSError *))completionHandler
{
NSMutableArray *signals = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < 4; i++) {
RACSignal *signal = [[[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[self requestMoreData:(NSDictionary *)param completion:^(NSArray *results, NSError *error) {
if (!error) {
[subscriber sendNext:results];
[subscriber sendCompleted];
}else {
[subscriber sendError:error];
}
}];
return nil;
}];
}] execute:nil];
[signals addObject:signal];
}
[[RACSignal combineLatest:signals] subscribeNext:^(RACTuple *tuple) {
NSMutableArray *results = [[NSMutableArray alloc] init];
/////
for (NSInteger i = 0; i < tuple.count; i++) {
NSArray *arr = [tuple objectAtIndex:i];
if (arr.count != 0) {
<#Model#> *model = [[<#Model#> alloc] init];
model.<#property#> = <#propertyValue#>;
model.<#property#> = <#propertyValue#>;
model.results = arr;
[results addObject:model];
}
}
if (completionHandler) {
completionHandler(results, nil);
}
} error:^(NSError * _Nullable error) {
if (completionHandler) {
completionHandler(nil, error);
}
}];
}
#pragma mark 搜索更多
+ (void)requestMoreData:(NSDictionary *)param completion:(void (^)(NSArray *, NSError *))completionHandler
{
NSString *URLString = <#urlString#>;
URLString = [URLString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]];
<#HTTPSessionManager#> *manager = [[<#HTTPSessionManager#> alloc] initWithPort:kPort4000];
[manager POST:URLString parameters:nil success:^(NSDictionary * _Nonnull responseDict) {
Class cls;
switch (type) {
case <#ENumType_1#>:
cls = [<#ModelClass_1#> class];
break;
case <#ENumType_2#>:
cls = [<#ModelClass_2#> class];
break;
case <#ENumType_3#>:
cls = [<#ModelClass_3#> class];
break;
case <#ENumType_4#>:
cls = [<#ModelClass_4#> class];
break;
default:
break;
}
NSArray *json = responseDict[kResponseDataKey];
NSArray *results = [NSArray modelArrayWithClass:cls json:json];
if (completionHandler) {
completionHandler(results, nil);
}
} failure:^(NSError * _Nonnull error) {
if (completionHandler) {
completionHandler(nil, error);
}
}];
}
4.单个数据回传
在ViewController_1中
- (void)handleButtonClick:(UIButton *)sender
{
ViewController_2 *vc_2 = [[CaptureChannelViewController alloc] init];
[cvc.doneSelectingSubject subscribeNext:^(LiveChannelModel *channel) {
[sender setTitle:channel.Name forState:UIControlStateNormal];
self.model.LivechannelId = channel.Id;
self.model.CarbrandId = channel.CarbrandtId;
}];
[self.navigationController pushViewController:vc_2 animated:YES];
}
在ViewController_2中
ViewController_2.h
@property (nonatomic, strong) RACSubject *<#doneSelectingSubjectt#>;
ViewController_2.m
- (RACSubject *)<#doneSelectingSubjectt#>
{
if (!_<#doneSelectingSubjectt#>) {
_<#doneSelectingSubjectt#> = [RACSubject subject];
}
return _<#doneSelectingSubject#>;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
for (<#Model#> *model in self.<#modeArray#>) {
model.selected = NO;
}
<#Model#> *<#modelName#> = self.<#modeArray#>[indexPath.item];
<#modelName#>.selected = YES;
[collectionView reloadData];
if (<#modelName#>.<#property is true#>) {
[self next:<#modelName#>];
}else {
if (<#有二级页面筛选条件#>) {
if (<#modelName#>.<#(属性)进入二级页面条件为真#>) { // 非保险
<#ViewController_3#> *vc_3 = [[<#ViewController_3#> alloc] init];
[vc_3.doneSelectingSubject subscribeNext:^(NSString *<#ReturnString#>) {
<#modelName#>.<#property#> = <#ReturnString#>;
[self done:<#modelName#>];
}];
[self.navigationController pushViewController:<#vc_3#> animated:NO];
}else {
[self done:<#modelName#>];
}
}else {
[self done:<#modelName#>];
}
}
}
#pragma mark 下一步
- (void)next:(<#Mode#> *)<#model#>
{
<#ViewController_#> *<#vc_#> = [[<#ViewController_#> alloc] init];
<#vc_#>.<#propertyName#> = <#mode#>.<#propertyName#>;
<#vc_#>.doneSelectingSubject = self.doneSelectingSubject;
[self.navigationController pushViewController:<#vc_#> animated:NO];
}
#pragma mark 完成
- (void)done:(<#Model#> *)<#model#>
{
////////如有需要实现多选
if (![<#model#>.<#propertyName#> isNotBlank]) {
<#mode#>.<#OtherPropertyName#> = <#@""#>;
}
[self.doneSelectingSubject sendNext:<#mode#>];
//如有需要退出
//1.退出到制定ViewController
UIViewController *vcTo = nil;
for (NSInteger i = 0; i < self.navigationController.viewControllers.count; i++) {
UIViewController *vc = self.navigationController.viewControllers[i];
if ([vc isKindOfClass:NSClassFromString(@"<#ViewController#>")]) {
vcTo = vc;
break;
}
}
[self.navigationController popToViewController:vcTo animated:YES];
//2.直接popView
}
在ViewController_3中
ViewController_3.h
@property (nonatomic, strong) RACSubject *<#doneSelectingSubjectt#>;
ViewController_3.m
- (RACSubject *)<#doneSelectingSubjectt#>
{
if (!_<#doneSelectingSubjectt#>) {
_<#doneSelectingSubjectt#> = [RACSubject subject];
}
return _<#doneSelectingSubject#>;
}
#pragma mark 完成
- (void)done:(<#Model#> *)<#model#>
{
if (![<#model#>.<#propertyName#> isNotBlank]) {
<#mode#>.<#OtherPropertyName#> = <#@""#>;
}
[self.doneSelectingSubject sendNext:<#mode#>];
//如有需要可以退出
}