From 59347b44733ffbef089a7b383dceaf07cef25a2b Mon Sep 17 00:00:00 2001 From: exiaomo Date: Sun, 21 Jun 2015 23:37:31 +0300 Subject: [PATCH] =?UTF-8?q?#4.=20=E7=94=B1=E4=BA=8E=E5=AE=8C=E5=85=A8?= =?UTF-8?q?=E5=BC=82=E6=AD=A5=E8=AF=BB=E5=8F=96=E7=9A=84=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=BD=93=E9=AA=8C=E5=B7=AE=EF=BC=8C=E6=94=B9=E5=9B=9E=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E6=89=B9=E9=87=8F=E5=88=86=E9=A1=B5=E8=AF=BB=E5=8F=96?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AllBoardsList/TopicListViewController.m | 2 +- .../General/Home/PostListViewController.m | 152 ++++++++---------- ARGO_317_2/Main.storyboard | 11 +- ARGO_317_2/Models/DataManager.m | 30 +++- .../Base.lproj/Localizable.strings | 5 +- xARGO.xcodeproj/project.pbxproj | 2 +- 6 files changed, 106 insertions(+), 96 deletions(-) diff --git a/ARGO_317_2/General/AllBoardsList/TopicListViewController.m b/ARGO_317_2/General/AllBoardsList/TopicListViewController.m index 97cc469..70aa648 100644 --- a/ARGO_317_2/General/AllBoardsList/TopicListViewController.m +++ b/ARGO_317_2/General/AllBoardsList/TopicListViewController.m @@ -45,7 +45,7 @@ - (void)fetchTotal_topicNumWithBoardName:(NSString *)boardname // NSLog(@"Post List."); if (self.boardName && self.boardTitle) { [[DataManager manager] getBoardByBoardName:boardname success:^(NSDictionary *data){ - // NSLog(@"Dictionary: %@", [data description]); + // NSLog(@"Dictionary: %@", [data description]); total_topicNum=[[[data objectForKey:@"data"] objectForKey:@"total_topic"]integerValue]; //记录下拉刷新时间: diff --git a/ARGO_317_2/General/Home/PostListViewController.m b/ARGO_317_2/General/Home/PostListViewController.m index 6cb27ae..2a290c4 100644 --- a/ARGO_317_2/General/Home/PostListViewController.m +++ b/ARGO_317_2/General/Home/PostListViewController.m @@ -8,7 +8,7 @@ // This contains a 3-stages lazy load: // 1. No data. // 2. List ready. -// 3. Rendering cell when visible. +// 3. Rendering cells in page. #import "PostListViewController.h" #import "AddPostViewController.h" @@ -23,21 +23,38 @@ #define floorTag 4 #define hasPictureTag 5 -static long batchCount = 3; +static int pageSize = 10; static NSString *CellIdentifier = @"postCell"; -@implementation PostListViewController +@implementation PostListViewController { + int currentPage; +} @synthesize boardName,fileName; @synthesize postTopicList,postList; -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil + +// ------------------------------------------------------------------------------- +// viewDidLoad +// ------------------------------------------------------------------------------- +- (void)viewDidLoad { - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self) { - - } - return self; + [super viewDidLoad]; + dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.timeZone = [NSTimeZone timeZoneWithName:@"Asia/beijing"]; + dateFormatter.dateFormat=@"yyyy/MM/dd, HH:mm"; + loadingCell=[[LoadingCell alloc]initWithNormalStr:@"上拉刷新" andLoadingStr:@"数据加载中.." andStartViewStr:@"可下拉刷新.."]; + [loadingCell loading]; + + currentPage = 0; + // Load list asynchously. + [self initTopicList]; + UIRefreshControl *refresh=[[UIRefreshControl alloc]init]; + refresh.tintColor=[UIColor lightGrayColor]; + refresh.attributedTitle=[[NSAttributedString alloc]initWithString:@"下拉刷新"]; + [refresh addTarget:self action:@selector(refreshView:) forControlEvents:UIControlEventValueChanged]; + self.refreshControl = refresh; + } -(void) initTopicList { @@ -57,41 +74,23 @@ -(void) initTopicList { [postTopicList addObject:[data objectAtIndex:i]]; } } - //记录数据加载时间 - lastUpdated=[NSString stringWithFormat:@"更新时间 %@", [dateFormatter stringFromDate:[NSDate date]]]; - [self fetchInBatch:0 count: batchCount]; - [loadingCell normal]; - loadingCell.label.text=[NSString stringWithFormat:@"%@",lastUpdated]; - [self.refreshControl endRefreshing]; + [self loadNextPage]; } } failure:^(NSString *data, NSError *error) { // failed? NSLog(@"Loading failed."); + NSString* errorMsg = NSLocalizedString([error.userInfo objectForKey:@"error"],@""); + [loadingCell normal]; + loadingCell.label.text = [NSString stringWithFormat:@"%@%@",NSLocalizedString(@"Reason:", @""), errorMsg]; + UIAlertView *av = [[UIAlertView alloc]initWithTitle:NSLocalizedString(@"Error",@"") message: [NSString stringWithFormat:@"%@%@",NSLocalizedString(@"Reason:", @""), errorMsg] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; + [av show]; } ]; - } -// ------------------------------------------------------------------------------- -// viewDidLoad -// ------------------------------------------------------------------------------- -- (void)viewDidLoad -{ - [super viewDidLoad]; - dateFormatter = [[NSDateFormatter alloc] init]; - dateFormatter.timeZone = [NSTimeZone timeZoneWithName:@"Asia/beijing"]; - dateFormatter.dateFormat=@"yyyy/MM/dd, HH:mm"; - loadingCell=[[LoadingCell alloc]initWithNormalStr:@"上拉刷新" andLoadingStr:@"数据加载中.." andStartViewStr:@"可下拉刷新.."]; +-(void) loadNextPage { [loadingCell loading]; - - // Load list asynchously. - [self initTopicList]; - UIRefreshControl *refresh=[[UIRefreshControl alloc]init]; - refresh.tintColor=[UIColor lightGrayColor]; - refresh.attributedTitle=[[NSAttributedString alloc]initWithString:@"下拉刷新"]; - [refresh addTarget:self action:@selector(refreshView:) forControlEvents:UIControlEventValueChanged]; - self.refreshControl = refresh; - + [self fetchInBatch:currentPage*pageSize count:pageSize]; } //下拉刷新调用的方法 @@ -110,78 +109,51 @@ - (void)clear { [postTopicList removeAllObjects]; [loadingCell loading]; + currentPage = 0; } -// ------------------------------------------------------------------------------- -// didReceiveMemoryWarning -// ------------------------------------------------------------------------------- - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } -#pragma mark - UITableViewDataSource - -// ------------------------------------------------------------------------------- -// tableView:numberOfRowsInSection: -// Customize the number of rows in the table view. -// ------------------------------------------------------------------------------- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Always there is a loading cell. - return self.postTopicList.count + 1; + return [self numberOfRows] + 1; +} + +-(NSInteger) numberOfRows { + return MIN(currentPage * pageSize, self.postTopicList.count); } -// ------------------------------------------------------------------------------- -// tableView:cellForRowAtIndexPath: -// ------------------------------------------------------------------------------- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = nil; - - NSUInteger nodeCount = self.postTopicList.count; - - if (nodeCount == indexPath.row) { + + if ([self numberOfRows] == indexPath.row) { // for the last row always return loading cell. return loadingCell.cell; } cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; - + NSDictionary *post = (self.postList)[indexPath.row]; [self composite:cell at:indexPath with:post]; - - if(post == (id)[NSNull null]) { - NSLog(@"Going to fetch:%@",[postTopicList objectAtIndex:indexPath.row]); - - [[DataManager manager] getPostByBoard:boardName andFile:[postTopicList objectAtIndex:indexPath.row] success:^(NSDictionary *resultDict) { - NSLog(@"On fetching successfully:%@",[[resultDict objectForKey:@"data"] objectForKey:@"filename"]); - if ([resultDict objectForKey:@"data"]&&[[resultDict objectForKey:@"data"]isKindOfClass:[NSDictionary class]]) { - self.postList[indexPath.row]=[resultDict objectForKey:@"data"]; - [self composite:cell at:indexPath with:self.postList[indexPath.row]]; - } - NSLog(@"TableView rows=%ld",(long)[tableView numberOfRowsInSection:0]); - NSLog(@"Going to reload row=%@",indexPath); - NSLog(@"The cell=%@",[tableView cellForRowAtIndexPath:indexPath]); - if([tableView cellForRowAtIndexPath:indexPath]) { [tableView beginUpdates]; - [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; - [tableView endUpdates]; - } - - - } failure:^(NSString *data, NSError *error) { - NSLog(@"When fetching failed."); - }]; - } - NSLog(@"Returning cell=%@",cell); return cell; } --(void) fetchInBatch:(long) from count:(long) count { +-(void) fetchInBatch:(int) from count:(int) count { assert(postTopicList.count > 0); assert(count >= 0); __block int counter = 0; - unsigned long threshold = MIN(count, postTopicList.count - from); - NSLog(@"Going to fetch next %ld from %ld", count, from); - for (int i = 0; i < threshold; ++i) { + int threshold = MIN(count, (int)postTopicList.count - from); + if (threshold < 0) { + // No more data now. + lastUpdated=[NSString stringWithFormat:@"更新时间 %@", [dateFormatter stringFromDate:[NSDate date]]]; + [loadingCell normal]; + loadingCell.label.text=[NSString stringWithFormat:@"%@",lastUpdated]; + } + NSLog(@"Going to fetch next %d from %d", count, from); + for (int i = from; i < from + threshold; ++i) { NSLog(@"Going to fetch :%@", [postTopicList objectAtIndex:i]); [[DataManager manager] getPostByBoard:boardName andFile:[postTopicList objectAtIndex:i] success:^(NSDictionary *resultDict) { NSLog(@"On fetching successfully:%@",[[resultDict objectForKey:@"data"] objectForKey:@"filename"]); @@ -190,6 +162,14 @@ -(void) fetchInBatch:(long) from count:(long) count { } ++counter; if(counter == threshold) { + currentPage++; + [loadingCell normal]; + if (postTopicList.count <= from + threshold) { + lastUpdated=[NSString stringWithFormat:@"更新时间 %@", [dateFormatter stringFromDate:[NSDate date]]]; + loadingCell.label.text=[NSString stringWithFormat:@"%@",lastUpdated]; + } else { + loadingCell.label.text=[NSString stringWithFormat:@"下面还有%lu贴,轻轻上拉继续看",(unsigned long)postTopicList.count-from-threshold]; + } [self.tableView reloadData]; } } failure:^(NSString *data, NSError *error) { @@ -240,10 +220,10 @@ -(NSString *) formatTime:(double)timeStr { - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { //触发上拉加载更多的条件 - if(scrollView.contentSize.height - (scrollView.contentOffset.y + scrollView.bounds.size.height - scrollView.contentInset.bottom) <= -REFRESH_HEADER_HEIGHT && scrollView.contentOffset.y > 0){ + if(scrollView.contentSize.height - (scrollView.contentOffset.y + scrollView.bounds.size.height - scrollView.contentInset.bottom) <= -REFRESH_HEADER_HEIGHT && scrollView.contentOffset.y > 0) { //如果是提醒详情,则不需要上拉加载更多 if ([self.navigationItem.title isEqualToString:@"提醒详情"]==NO) { -// [self performSelector:@selector(loadMorePostFeed) withObject:nil afterDelay:0]; + [self loadNextPage]; } } @@ -254,7 +234,7 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa if (indexPath.row<[postList count] && postList[indexPath.row]!=[NSNull null]) { return [self getTheHeight:indexPath.row]; } else { - return 100; + return 50; } } @@ -274,9 +254,9 @@ -(CGFloat) getTheHeight:(NSInteger)row { // 返回需要的高度,这里的判断不需要那么严格 if ([[postList[row]objectForKey:@"ah"]count]==0) { - return height+58; + return height+28; } else { - return height+88; + return height+38; } } diff --git a/ARGO_317_2/Main.storyboard b/ARGO_317_2/Main.storyboard index aa83cb4..d59dddf 100644 --- a/ARGO_317_2/Main.storyboard +++ b/ARGO_317_2/Main.storyboard @@ -1,7 +1,8 @@ - + - + + @@ -1193,7 +1194,7 @@ - + @@ -1588,10 +1589,10 @@ - + + - diff --git a/ARGO_317_2/Models/DataManager.m b/ARGO_317_2/Models/DataManager.m index c30c440..ec65b29 100644 --- a/ARGO_317_2/Models/DataManager.m +++ b/ARGO_317_2/Models/DataManager.m @@ -31,6 +31,7 @@ @implementation DataManager NSString * const MSG_NETWORK_FAILURE = @"MSG_NETWORK_FAILURE"; +NSString * const MSG_BUSINESS_FAILURE = @"MSG_BUSINESS_FAILURE"; DataManager *manager; @@ -59,7 +60,13 @@ - (void)getData:(NSString*) url [[AFHTTPRequestOperationManager manager] GET:url parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) { [self.postCache setObject:responseObject forKey:cacheKey]; - success(responseObject); + NSError* error = [self isSuccessfulJsonResponse:responseObject]; + if (!error) { + success(responseObject); + } else { + NSError* error = [NSError errorWithDomain:@"" code:123 userInfo:responseObject]; + failure(NSLocalizedString(MSG_BUSINESS_FAILURE, MSG_NETWORK_FAILURE_KEY),error); + } } failure: ^(AFHTTPRequestOperation *operation, NSError *error) { failure(NSLocalizedString(MSG_NETWORK_FAILURE, MSG_NETWORK_FAILURE_KEY),error); }]; @@ -71,12 +78,31 @@ - (void)getData:(NSString*) url success:(void (^)(NSDictionary *resultDict))success failure:(void (^)(NSString *data, NSError *error))failure; { [[AFHTTPRequestOperationManager manager] GET:url parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) { - success(responseObject); + NSError* error = [self isSuccessfulJsonResponse:responseObject]; + if (!error) { + success(responseObject); + } else { + failure(NSLocalizedString(MSG_BUSINESS_FAILURE, @""), error); + } } failure: ^(AFHTTPRequestOperation *operation, NSError *error) { failure(NSLocalizedString(MSG_NETWORK_FAILURE, MSG_NETWORK_FAILURE_KEY),error); }]; } +-(NSError*) isSuccessfulJsonResponse: (id) responseObject { + if ([responseObject isKindOfClass:[NSDictionary class]]) { + NSDictionary* jsonDict = (NSDictionary*) responseObject; + if ([[jsonDict objectForKey:@"success"] isEqual:@"1"] || + [[jsonDict objectForKey:@"success"] isEqual:@(1)] || + [jsonDict objectForKey:@"data"] ){ + return nil; + } + return [NSError errorWithDomain:@"" code:[[jsonDict objectForKey:@"code"] integerValue] userInfo:responseObject]; + } + // Should not happen. + return [NSError errorWithDomain:@"" code:404 userInfo:responseObject]; +} + - (void)getAllSections:(void (^)(NSDictionary *resultDict)) success failure:(void (^)(NSString *data, NSError *error)) failure; { NSString *cacheKey = @"allSection"; diff --git a/ARGO_317_2/Resources/Localization/Base.lproj/Localizable.strings b/ARGO_317_2/Resources/Localization/Base.lproj/Localizable.strings index 66109f3..7d26b34 100644 --- a/ARGO_317_2/Resources/Localization/Base.lproj/Localizable.strings +++ b/ARGO_317_2/Resources/Localization/Base.lproj/Localizable.strings @@ -6,4 +6,7 @@ Copyright (c) 2014 490021684@qq.com. All rights reserved. */ "welcome"="Click on the screen to continue..."; -"MSG_NETWORK_FAILURE"="网络错误。如果您多次看到此提示,请尝试使用浏览器访问http://argo.sysu.edu.cn/"; \ No newline at end of file +"MSG_NETWORK_FAILURE"="网络错误。如果您多次看到此提示,请尝试使用浏览器访问http://argo.sysu.edu.cn/"; +"Post not exists."="该贴不存在"; +"Error"="出错了"; +"Reason:"="错误原因:"; \ No newline at end of file diff --git a/xARGO.xcodeproj/project.pbxproj b/xARGO.xcodeproj/project.pbxproj index 614f8b3..e39faf3 100644 --- a/xARGO.xcodeproj/project.pbxproj +++ b/xARGO.xcodeproj/project.pbxproj @@ -859,7 +859,7 @@ ORGANIZATIONNAME = "490021684@qq.com"; TargetAttributes = { B0C3D86518D6F421004B5F9F = { - DevelopmentTeam = FG2DXVNB5P; + DevelopmentTeam = 38A6JF2N52; }; }; };