ios影視項目解析 主要為講block的細節 如果瞭解了 block的定義等 但是對運用不是很熟悉可以參考本文章,iosblock
源於github上的影視項目解析
此項目在4app 和 github上都可以下載
項目:
此處為程式剛運行介面
程式應有一個discover控制器
找到discover控制器,然後可以根據項目的流程熟悉此項目的原理,從而學習到他們的架構思想
1 - (void)setupTableView2 {3 if (!_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) [self processData: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"typedef void (^KMDiscoverListCompletionBlock)(NSArray* data, NSString* errorString);@interface KMDiscoverSource : KMBaseSource+ (KMDiscoverSource*)discoverSource;- (void)getDiscoverList:(NSString*)pageLimit completion:(KMDiscoverListCompletionBlock)completionBlock;@end
這個應該是一個工具類 用來返回discover 的資料
1 - (void)getDiscoverList:(NSString*)pageLimit completion:(KMDiscoverListCompletionBlock)completionBlock; 2 { 3 if (completionBlock) 4 { 5 NSDictionary* parameters = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:pageLimit, nil] forKeys:[NSArray arrayWithObjects:@"page", nil]]; 6 7 [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 8 9 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];10 [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];11 12 [manager GET:[self prepareUrl] parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject)13 {14 NSLog(@"JSON: %@", responseObject);15 NSDictionary* infosDictionary = [self dictionaryFromResponseData:operation.responseData jsonPatternFile:@"KMDiscoverSourceJsonPattern.json"];16 dispatch_async(dispatch_get_main_queue(), ^{17 [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;18 completionBlock([self processResponseObject:infosDictionary], nil);19 });20 }21 failure:^(AFHTTPRequestOperation *operation, NSError *error)22 {23 NSLog(@"Error: %@", error);24 dispatch_async(dispatch_get_main_queue(), ^{25 [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;26 NSString* errorString = error.localizedDescription;27 if ([errorString length] == 0)28 errorString = nil;29 completionBlock(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) return nil; NSArray* itemsList = [NSArray arrayWithArray:[data objectForKey:@"results"]]; NSMutableArray* sortedArray = [[NSMutableArray alloc] init]; for (NSDictionary* item in itemsList) { KMMovie* movie = [[KMMovie alloc] initWithDictionary:item]; [sortedArray addObject:movie]; } return sortedArray;}
可以清楚的看到這個函數 傳出了一個字典
-------------------未完待續