From f4173d1653d2ff87b427eda6d01d5eca88236265 Mon Sep 17 00:00:00 2001 From: nvtu Date: Sat, 5 Aug 2017 23:46:25 +0700 Subject: [PATCH] Add API for request history list and graph in today with selected type and mode --- LifeLog/LifeLog.xcodeproj/project.pbxproj | 6 ++ LifeLog/LifeLog/Entities.h | 3 + LifeLog/LifeLog/HistoryGraphObject.h | 18 ++++ LifeLog/LifeLog/HistoryGraphObject.m | 33 ++++++++ LifeLog/LifeLog/HistoryObject.m | 17 +++- LifeLog/LifeLog/HistoryViewController.h | 8 +- LifeLog/LifeLog/HistoryViewController.m | 131 ++++++++++++++++++++++-------- LifeLog/LifeLog/ServerAPI.h | 3 +- LifeLog/LifeLog/ServerAPI.m | 73 +++++++++++++++++ 9 files changed, 253 insertions(+), 39 deletions(-) create mode 100644 LifeLog/LifeLog/HistoryGraphObject.h create mode 100644 LifeLog/LifeLog/HistoryGraphObject.m diff --git a/LifeLog/LifeLog.xcodeproj/project.pbxproj b/LifeLog/LifeLog.xcodeproj/project.pbxproj index 4ef73d3..126f88c 100644 --- a/LifeLog/LifeLog.xcodeproj/project.pbxproj +++ b/LifeLog/LifeLog.xcodeproj/project.pbxproj @@ -46,6 +46,7 @@ 9CBDA1001F2F03810055DED1 /* RegisterViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9CBDA0FE1F2F03810055DED1 /* RegisterViewController.xib */; }; E9373E471F3596940059355A /* AutoTransLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = E9373E461F3596940059355A /* AutoTransLabel.m */; }; E9373E4A1F35AA180059355A /* HistoryObject.m in Sources */ = {isa = PBXBuildFile; fileRef = E9373E491F35AA180059355A /* HistoryObject.m */; }; + E9373E4D1F361A230059355A /* HistoryGraphObject.m in Sources */ = {isa = PBXBuildFile; fileRef = E9373E4C1F361A230059355A /* HistoryGraphObject.m */; }; E99E13AB1F336F3600C78787 /* CollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = E99E13AA1F336F3600C78787 /* CollectionView.m */; }; E99E13AD1F336F4500C78787 /* CollectionView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E99E13AC1F336F4500C78787 /* CollectionView.xib */; }; E99E13B11F33720600C78787 /* LabelCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E99E13AF1F33720600C78787 /* LabelCollectionViewCell.m */; }; @@ -143,6 +144,8 @@ E9373E461F3596940059355A /* AutoTransLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AutoTransLabel.m; sourceTree = ""; }; E9373E481F35AA180059355A /* HistoryObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryObject.h; sourceTree = ""; }; E9373E491F35AA180059355A /* HistoryObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HistoryObject.m; sourceTree = ""; }; + E9373E4B1F361A230059355A /* HistoryGraphObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryGraphObject.h; sourceTree = ""; }; + E9373E4C1F361A230059355A /* HistoryGraphObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HistoryGraphObject.m; sourceTree = ""; }; E99E13A91F336F3600C78787 /* CollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollectionView.h; sourceTree = ""; }; E99E13AA1F336F3600C78787 /* CollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CollectionView.m; sourceTree = ""; }; E99E13AC1F336F4500C78787 /* CollectionView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CollectionView.xib; sourceTree = ""; }; @@ -216,6 +219,8 @@ 6E18CEDD1F2E46570029891F /* Entities.h */, E9373E481F35AA180059355A /* HistoryObject.h */, E9373E491F35AA180059355A /* HistoryObject.m */, + E9373E4B1F361A230059355A /* HistoryGraphObject.h */, + E9373E4C1F361A230059355A /* HistoryGraphObject.m */, ); name = Model; sourceTree = ""; @@ -713,6 +718,7 @@ 6E18CED31F2E39DB0029891F /* LoginViewController.m in Sources */, 6E84E3761F27A701001EB88E /* main.m in Sources */, 6E84E3B51F27A98B001EB88E /* HistoryViewController.m in Sources */, + E9373E4D1F361A230059355A /* HistoryGraphObject.m in Sources */, 6E84E3BF1F27A9B1001EB88E /* SNSViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/LifeLog/LifeLog/Entities.h b/LifeLog/LifeLog/Entities.h index 1fa0fb6..efc0af5 100644 --- a/LifeLog/LifeLog/Entities.h +++ b/LifeLog/LifeLog/Entities.h @@ -9,6 +9,9 @@ #ifndef Entities_h #define Entities_h +#import + +#import "HistoryGraphObject.h" #import "HistoryObject.h" #import "User.h" diff --git a/LifeLog/LifeLog/HistoryGraphObject.h b/LifeLog/LifeLog/HistoryGraphObject.h new file mode 100644 index 0000000..b4ad41d --- /dev/null +++ b/LifeLog/LifeLog/HistoryGraphObject.h @@ -0,0 +1,18 @@ +// +// HistoryGraphObject.h +// LifeLog +// +// Created by nvtu on 8/5/17. +// Copyright © 2017 PhongNV. All rights reserved. +// + +#import + +@interface HistoryGraphObject : NSObject + +@property (nonatomic, strong) NSMutableArray * arrayTime; +@property (nonatomic, strong) NSMutableArray * arrayStep; + +-(id) initWithData : (NSDictionary *) dict; + +@end diff --git a/LifeLog/LifeLog/HistoryGraphObject.m b/LifeLog/LifeLog/HistoryGraphObject.m new file mode 100644 index 0000000..a04d27f --- /dev/null +++ b/LifeLog/LifeLog/HistoryGraphObject.m @@ -0,0 +1,33 @@ +// +// HistoryGraphObject.m +// LifeLog +// +// Created by nvtu on 8/5/17. +// Copyright © 2017 PhongNV. All rights reserved. +// + +#import "HistoryGraphObject.h" + +@implementation HistoryGraphObject + +-(id) initWithData : (NSDictionary *) dict { + + if([dict objectForKey:@"data"] != nil) { + self.arrayStep = [[NSMutableArray alloc] init]; + self.arrayTime = [[NSMutableArray alloc] init]; + NSArray *arrayGraph = dict[@"data"]; + for(NSDictionary *sub in arrayGraph) { + if([sub objectForKey:@"hour"] != nil && [sub objectForKey:@"step"] != nil) { + [self.arrayTime addObject:[sub objectForKey:@"hour"]]; + [self.arrayStep addObject:[sub objectForKey:@"step"]]; + } + } + } + else { + return nil; + } + return self; +} + + +@end diff --git a/LifeLog/LifeLog/HistoryObject.m b/LifeLog/LifeLog/HistoryObject.m index f9cb952..cd1ea9d 100644 --- a/LifeLog/LifeLog/HistoryObject.m +++ b/LifeLog/LifeLog/HistoryObject.m @@ -24,16 +24,27 @@ self.percent = [dict[@"percent"] floatValue]; } if([dict objectForKey:@"distance"] != nil) { - self.distance = [dict[@"distance"] floatValue]; + if([dict[@"distance"] isKindOfClass:[NSString class]]) { + NSString *distance = dict[@"distance"]; + self.distance = [distance floatValue]; + } + else { + self.distance = [dict[@"distance"] floatValue]; + } } if([dict objectForKey:@"kcal"] != nil) { self.calories = [dict[@"kcal"] floatValue]; } if([dict objectForKey:@"time"] != nil) { - self.time = dict[@"time"]; + if([dict[@"time"] isKindOfClass:[NSString class]]) { + self.time = dict[@"time"]; + } + else { + self.time = @"0:0"; + } } if([dict objectForKey:@"date"] != nil) { - NSString *dateString = dict[@"time"]; + NSString *dateString = dict[@"date"]; NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; [dateFormat setDateFormat:@"yyyy-MM-dd"]; self.date = [dateFormat dateFromString:dateString]; diff --git a/LifeLog/LifeLog/HistoryViewController.h b/LifeLog/LifeLog/HistoryViewController.h index 2d38411..8221ff4 100644 --- a/LifeLog/LifeLog/HistoryViewController.h +++ b/LifeLog/LifeLog/HistoryViewController.h @@ -14,8 +14,12 @@ #import "Entities.h" @interface HistoryViewController : UIViewController { - NSDate * _currentDate; - HistoryObject * _currentHistoryObject; + NSDate * _curDate; + HistoryObject * _curHisObj; + HistoryGraphObject * _curHisGraphObj; + NSMutableArray * _curHisList; + + int _curPageIndex; } @property (weak, nonatomic) IBOutlet UILabel *lblHeader; diff --git a/LifeLog/LifeLog/HistoryViewController.m b/LifeLog/LifeLog/HistoryViewController.m index a32b7c4..86d0302 100644 --- a/LifeLog/LifeLog/HistoryViewController.m +++ b/LifeLog/LifeLog/HistoryViewController.m @@ -27,7 +27,8 @@ [self setupView]; [self setupChartView]; - _currentDate = [NSDate date]; + _curDate = [NSDate date]; + _curHisList = [[NSMutableArray alloc] init]; [self callRequestToUpdateData]; @@ -75,15 +76,6 @@ [self.viewCollectionShare setArrayTitle:shareTitle]; } --(void) updateView { - self.lblStep.text = [NSString stringWithFormat:@"%d", _currentHistoryObject.step]; - self.lblRemaining.text = [NSString stringWithFormat:@"%d", _currentHistoryObject.missing]; - self.lblPercent.text = [NSString stringWithFormat:@"%0.2f", _currentHistoryObject.percent * 100]; - self.lblCalories.text = [NSString stringWithFormat:@"%1.0f", _currentHistoryObject.calories]; - self.lblDistance.text = [NSString stringWithFormat:@"%0.1f", _currentHistoryObject.distance]; - self.lblTime.text = _currentHistoryObject.time; -} - - (void)setupChartView { self.viewBarChart.chartDescription.enabled = NO; self.viewBarChart.leftAxis.drawGridLinesEnabled = NO; @@ -103,14 +95,22 @@ self.viewBarChart.leftAxis.drawAxisLineEnabled = NO; self.viewBarChart.rightAxis.drawAxisLineEnabled = NO; - - /*fake data for test*/ +} + +-(void) updateView { + self.lblStep.text = [NSString stringWithFormat:@"%d", _curHisObj.step]; + self.lblRemaining.text = [NSString stringWithFormat:@"%d", _curHisObj.missing]; + self.lblPercent.text = [NSString stringWithFormat:@"%0.2f", _curHisObj.percent * 100]; + self.lblCalories.text = [NSString stringWithFormat:@"%0.2f", _curHisObj.calories]; + self.lblDistance.text = [NSString stringWithFormat:@"%0.1f", _curHisObj.distance]; + self.lblTime.text = _curHisObj.time; +} + +-(void) updateGraphView { NSMutableArray *yVals = [[NSMutableArray alloc] init]; - - for (int i = 0; i < 24; i++) + for (int i = 0; i < _curHisGraphObj.arrayStep.count; i++) { - double val = (double) (arc4random_uniform(100)); - [yVals addObject:[[BarChartDataEntry alloc] initWithX:i y:val]]; + [yVals addObject:[[BarChartDataEntry alloc] initWithX:i y:[[_curHisGraphObj.arrayStep objectAtIndex:i] doubleValue]]]; } BarChartDataSet *set1 = nil; @@ -131,27 +131,71 @@ BarChartData *data = [[BarChartData alloc] initWithDataSets:dataSets]; data.barWidth = 0.5f; - + self.viewBarChart.data = data; } } -(void) callRequestToUpdateData { - [[ServerAPI server] requestHistory:[[NSUserDefaults standardUserDefaults] stringForKey:kToken] atDate:_currentDate withType:self.viewCollectionType.getCurrentIndex andMode:self.viewCollectionMode.getCurrentIndex + 1 CompletionHandler:^(HistoryObject *object, NSError *error) { - HistoryViewController __weak *weakSelf = self; - if(error == nil) { - _currentHistoryObject = object; - dispatch_async(dispatch_get_main_queue(), ^{ - [self updateView]; - }); - } - else { - dispatch_async(dispatch_get_main_queue(), ^{ - NSString *message = [error.userInfo objectForKey:@"message"]; - [Utilities showErrorMessage:message withViewController:weakSelf]; - }); - } - }]; + MBProgressHUD *hudView = [MBProgressHUD showHUDAddedTo:self.view animated:true]; + NSString * token = [[NSUserDefaults standardUserDefaults] stringForKey:kToken]; + int type = self.viewCollectionType.getCurrentIndex; + int mode = self.viewCollectionMode.getCurrentIndex + 1; + + if(self.tableListHistory.alpha == 0.0) { + [[ServerAPI server] requestHistory:token atDate:_curDate withType:type andMode:mode CompletionHandler:^(HistoryObject *object, NSError *error) { + HistoryViewController __weak *weakSelf = self; + if(error == nil) { + _curHisObj = object; + dispatch_async(dispatch_get_main_queue(), ^{ + [hudView hideAnimated:true]; + [weakSelf updateView]; + }); + } + else { + dispatch_async(dispatch_get_main_queue(), ^{ + [hudView hideAnimated:true]; + NSString *message = [error.userInfo objectForKey:@"message"]; + [Utilities showErrorMessage:message withViewController:weakSelf]; + }); + } + }]; + + [[ServerAPI server] requestHistoryGraph:token withType:type andMode:mode CompletionHandler:^(HistoryGraphObject *object, NSError *error) { + HistoryViewController __weak *weakSelf = self; + if(error == nil) { + _curHisGraphObj = object; + dispatch_async(dispatch_get_main_queue(), ^{ + [self updateGraphView]; + }); + } + else { + dispatch_async(dispatch_get_main_queue(), ^{ + NSString *message = [error.userInfo objectForKey:@"message"]; + [Utilities showErrorMessage:message withViewController:weakSelf]; + }); + } + }]; + } + else { + [[ServerAPI server] requestHistoryList:token withType:type andMode:mode AtPage:1 CompletionHandler:^(NSMutableArray *object, NSError *error) { + HistoryViewController __weak *weakSelf = self; + if(error == nil) { + _curHisList = object; + dispatch_async(dispatch_get_main_queue(), ^{ + [hudView hideAnimated:true]; + [weakSelf.tableListHistory reloadData]; + }); + } + else { + dispatch_async(dispatch_get_main_queue(), ^{ + [hudView hideAnimated:true]; + NSString *message = [error.userInfo objectForKey:@"message"]; + [Utilities showErrorMessage:message withViewController:weakSelf]; + }); + } + }]; + } } #pragma mark IBAction @@ -161,16 +205,37 @@ self.tableListHistory.alpha = alphaValue; self.scrollView.alpha = 1.0 - alphaValue; } completion:^(bool completed) { + [self callRequestToUpdateData]; }]; } #pragma mark UITableView Delegate +- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView { + if(_curHisList == nil || _curHisList.count == 0) { + UILabel * noDataLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, tableView.frame.size.height)]; + noDataLabel.text = @"No data available"; + noDataLabel.backgroundColor = [UIColor clearColor]; + noDataLabel.textColor = [UIColor whiteColor]; + noDataLabel.textAlignment = NSTextAlignmentCenter; + tableView.backgroundView = noDataLabel; + tableView.backgroundView.layer.zPosition -= 1; + return 0; + } + tableView.backgroundView = nil; + return 1; +} + - (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return 4; + return _curHisList.count; } - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { HistoryListTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"HistoryListCell"]; + HistoryObject * obj = [_curHisList objectAtIndex:indexPath.row]; + cell.lblStep.text = [NSString stringWithFormat:@"%d", obj.step]; + cell.lblPower.text = [NSString stringWithFormat:@"%0.2f", obj.calories]; + cell.lblDistance.text = [NSString stringWithFormat:@"%0.1f", obj.distance]; + cell.lblDuration.text = obj.time; return cell; } diff --git a/LifeLog/LifeLog/ServerAPI.h b/LifeLog/LifeLog/ServerAPI.h index d809aff..b146ad8 100644 --- a/LifeLog/LifeLog/ServerAPI.h +++ b/LifeLog/LifeLog/ServerAPI.h @@ -23,5 +23,6 @@ extern NSString *const kToken; - (void)confirmForgetPass:(NSString *)email withConfirm:(NSString *)confirm CompletionHandler:(void (^)(NSError *)) completion; - (void) requestHistory:(NSString *)token atDate:(NSDate *)date withType:(int)type andMode:(int) mode CompletionHandler:(void (^)(HistoryObject *, NSError *)) completion; - +- (void) requestHistoryGraph:(NSString *)token withType:(int)type andMode:(int) mode CompletionHandler:(void (^)(HistoryGraphObject *, NSError *)) completion; +- (void) requestHistoryList:(NSString *)token withType:(int)type andMode:(int) mode AtPage:(int) page CompletionHandler:(void (^)(NSMutableArray *, NSError *)) completion; @end diff --git a/LifeLog/LifeLog/ServerAPI.m b/LifeLog/LifeLog/ServerAPI.m index f6b7e31..9e8f781 100644 --- a/LifeLog/LifeLog/ServerAPI.m +++ b/LifeLog/LifeLog/ServerAPI.m @@ -304,6 +304,79 @@ static ServerAPI *_server = nil; }]; } +- (void) requestHistoryGraph:(NSString *)token withType:(int)type andMode:(int) mode CompletionHandler:(void (^)(HistoryGraphObject *, NSError *)) completion { + NSString *url = [kServerAddress stringByAppendingFormat:@"/api/history/graph/%@/%d", [self convertIntToString:type], mode]; + NSLog(@"requestHistoryGraph link %@", url); + [self _request:url method:@"GET" token:token paras:nil completion:^(NSData *data, NSError *error) { + + if (completion == NULL) { + return ; + } + + if (error == nil) + { + NSDictionary *dataResult = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingAllowFragments error: &error]; + NSLog(@"%@", dataResult); + int status = [dataResult[@"status"] intValue]; + if (status == 1) { // status = 1 success + HistoryGraphObject * object = [[HistoryGraphObject alloc] initWithData:dataResult[@"result"]]; + completion(object, nil); + } + else { + NSString *message = dataResult[@"message"]; + NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}]; + completion(nil, errorObject); + } + } + else + { + completion(nil, error); + } + }]; +} + +- (void) requestHistoryList:(NSString *)token withType:(int)type andMode:(int) mode AtPage:(int) page CompletionHandler:(void (^)(NSMutableArray *, NSError *)) completion { + NSString *url = [kServerAddress stringByAppendingFormat:@"/api/history/list/%@/%d?page=%d&record=50", [self convertIntToString:type], mode, page]; + NSLog(@"requestHistoryList link %@", url); + [self _request:url method:@"GET" token:token paras:nil completion:^(NSData *data, NSError *error) { + + if (completion == NULL) { + return ; + } + + if (error == nil) + { + NSDictionary *dataResult = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingAllowFragments error: &error]; + NSLog(@"%@", dataResult); + int status = [dataResult[@"status"] intValue]; + if (status == 1) { // status = 1 success + if(dataResult[@"result"] != nil) { + NSArray * array = dataResult[@"result"][@"data"]; + NSMutableArray * arrayHistory = [[NSMutableArray alloc] init]; + for(NSDictionary * dict in array) { + HistoryObject * object = [[HistoryObject alloc] initWithData:dict]; + [arrayHistory addObject:object]; + } + completion(arrayHistory, nil); + } + else { + NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":@"Unknown Error"}]; + completion(nil, errorObject); + } + } + else { + NSString *message = dataResult[@"message"]; + NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}]; + completion(nil, errorObject); + } + } + else + { + completion(nil, error); + } + }]; +} + #pragma mark - Private Function - (NSData *) _encodeDictionary: (NSDictionary *) dictionary { -- 1.8.5.3