源于github上的影视项目解析
此项目在4app 和 github上都可以下载
项目截图:
此处为程序刚运行界面
程序应有一个discover控制器
找到discover控制器,然后可以根据项目的流程熟悉此项目的原理,从而学习到他们的架构思想
1- (void)setupTableView2{3if(!_refreshControl)4{5_refreshControl = [[UIRefreshControl alloc] initWithFrame:CGRectMake(0, -44,320,44)];6[self.refreshControl addTarget:self action:@selector(refreshFeed) forControlEvents:UIControlEventValueChanged];7[self.tableView addSubview:_refreshControl];8}9}
此处可看出是一个刷新空间的添加 采用懒加载的方式
- (void)refreshFeed
{
[self requestMovies];
}
他在viewdidload 还有刷新控件 改变的时刻调用requestMovies这个方法
找到这个方法
- (void)requestMovies
{
KMDiscoverListCompletionBlock completionBlock= ^(NSArray* data, NSString*errorString)
{
[self.refreshControl endRefreshing];if(data !=nil)
[selfPRocessData:data];else[self.networkLoadingViewController showErrorView];
};
KMDiscoverSource* source =[KMDiscoverSource discoverSource];
[source getDiscoverList:@"1"completion:completionBlock];
}
在这里 看了好久才明白 前面的 block 是对后面的调用来用的
也可以这样写 运行完全没错误
KMDiscoverSource* source =[KMDiscoverSource discoverSource];
[source getDiscoverList:@"1"completion:^(NSArray *data, NSString *errorString) {
[self.refreshControl endRefreshing];if(data !=nil)
[self processData:data];else[self.networkLoadingViewController showErrorView];
}
];
这里面的意思
在这里他将 下载数据的方法 封装为一个block 这个是我主要要看的方法 总是对block不是很熟悉
点进去看一下
#import"KMBaseSource.h"typedefvoid(^KMDiscoverListCompletionBlock)(NSArray* data, NSString*errorString);@interfaceKMDiscoverSource : KMBaseSource+ (KMDiscoverSource*)discoverSource;- (void)getDiscoverList:(NSString*)pageLimit completion:(KMDiscoverListCompletionBlock)completionBlock;@end
这个应该是一个工具类 用来返回discover 的数据
1- (void)getDiscoverList:(NSString*)pageLimit completion:(KMDiscoverListCompletionBlock)completionBlock;2{3if(completionBlock)4{5NSDictionary* parameters = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:pageLimit, nil] forKeys:[NSArray arrayWithObjects:@"page", nil]];67[UIapplicationsharedApplication].networkActivityIndicatorVisible =YES;89AFHTTPRequestOperationManager *manager =[AFHTTPRequestOperationManager manager];10[manager.requestSerializer setValue:@"application/json"forHTTPHeaderField:@"Accept"];1112[manager GET:[self prepareUrl] parameters:parameters success:^(AFHTTPRequestOperation *operation,idresponSEObject)13{14NSLog(@"JSON: %@", responseObject);15NSDictionary* infosDictionary = [self dictionaryFromResponseData:operation.responseData jsonPatternFile:@"KMDiscoverSourceJsonPattern.json"];16dispatch_async(dispatch_get_main_queue(), ^{17[UIApplication sharedApplication].networkActivityIndicatorVisible =NO;18completionBlock([self processResponseObject:infosDictionary], nil);19});20}21failure:^(AFHTTPRequestOperation *operation, NSError *error)22{23NSLog(@"Error: %@", error);24dispatch_async(dispatch_get_main_queue(), ^{25[UIApplication sharedApplication].networkActivityIndicatorVisible =NO;26NSString* errorString =error.localizedDescription;27if([errorString length] ==0)28errorString =nil;29completionBlock(nil, errorString);30});31}];32}33}
这里使用了第三方框架AFN
第一句是传入一个字典参数
第7行是 让状态栏的 网络传输图标 显示
第12行为 发送一个get请求
第15行是对json经行解析的封装 因为AFN是在异步执行 所以要得到主线程更新ui 把block的参数中的 data 给block 然后 在别的控制器调用这个block时候就会有参数 还可以进行自己的操作 可以在下面看到这个方法,还可以监听这个数据下载好没有
因为在err的参数里传的是nil 在运行的时候经行判断就好了
- (NSArray*)processResponseObject:(NSDictionary*)data
{if(data ==nil)returnnil;
NSArray* itemsList = [NSArray arrayWithArray:[data objectForKey:@"results"]];
NSMutableArray* sortedArray =[[NSMutableArray alloc] init];for(NSDictionary* iteminitemsList)
{
KMMovie* movie =[[KMMovie alloc] initWithDictionary:item];
[sortedArray addObject:movie];
}returnsortedArray;
}
可以清楚的看到这个函数 传出了一个字典
-------------------未完待续