Commit 26548f2f08a9decba01b756a117a5a80b653dfbb

Authored by phong
1 parent 920357ae44
Exists in master

add notice to Home screen

Showing 12 changed files with 639 additions and 451 deletions Side-by-side Diff

LifeLog/LifeLog.xcodeproj/project.pbxproj
... ... @@ -12,6 +12,8 @@
12 12 6E18CED41F2E39DB0029891F /* LoginViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6E18CED21F2E39DB0029891F /* LoginViewController.xib */; };
13 13 6E18CED81F2E3C840029891F /* ServerAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E18CED71F2E3C840029891F /* ServerAPI.m */; };
14 14 6E18CEDC1F2E40F50029891F /* User.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E18CEDB1F2E40F50029891F /* User.m */; };
  15 + 6E27A74A1F9E41B400C390B3 /* HomeObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E27A7491F9E41B400C390B3 /* HomeObject.m */; };
  16 + 6E27A74D1F9E432900C390B3 /* NoticeInfor.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E27A74C1F9E432900C390B3 /* NoticeInfor.m */; };
15 17 6E48AF0D1F2F9D3300C1D184 /* CustomTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E48AF0C1F2F9D3200C1D184 /* CustomTextField.m */; };
16 18 6E7F93421F35872B00EFBC71 /* TPKeyboardAvoidingCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E7F933B1F35872B00EFBC71 /* TPKeyboardAvoidingCollectionView.m */; };
17 19 6E7F93431F35872B00EFBC71 /* TPKeyboardAvoidingScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E7F933D1F35872B00EFBC71 /* TPKeyboardAvoidingScrollView.m */; };
... ... @@ -23,7 +25,7 @@
23 25 6E84E3841F27A701001EB88E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6E84E3821F27A701001EB88E /* LaunchScreen.storyboard */; };
24 26 6E84E38F1F27A703001EB88E /* LifeLogTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E84E38E1F27A703001EB88E /* LifeLogTests.m */; };
25 27 6E84E39A1F27A703001EB88E /* LifeLogUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E84E3991F27A703001EB88E /* LifeLogUITests.m */; };
26   - 6E84E3B01F27A975001EB88E /* HomeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E84E3AE1F27A975001EB88E /* HomeViewController.m */; };
  28 + 6E84E3B01F27A975001EB88E /* HomeViewConb troller.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E84E3AE1F27A975001EB88E /* HomeViewConb troller.m */; };
27 29 6E84E3B11F27A975001EB88E /* HomeViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6E84E3AF1F27A975001EB88E /* HomeViewController.xib */; };
28 30 6E84E3B51F27A98B001EB88E /* HistoryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E84E3B31F27A98B001EB88E /* HistoryViewController.m */; };
29 31 6E84E3B61F27A98B001EB88E /* HistoryViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6E84E3B41F27A98B001EB88E /* HistoryViewController.xib */; };
... ... @@ -107,6 +109,10 @@
107 109 6E18CEDA1F2E40F50029891F /* User.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = User.h; sourceTree = "<group>"; };
108 110 6E18CEDB1F2E40F50029891F /* User.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = User.m; sourceTree = "<group>"; };
109 111 6E18CEDD1F2E46570029891F /* Entities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Entities.h; sourceTree = "<group>"; };
  112 + 6E27A7481F9E41B300C390B3 /* HomeObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeObject.h; sourceTree = "<group>"; };
  113 + 6E27A7491F9E41B400C390B3 /* HomeObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeObject.m; sourceTree = "<group>"; };
  114 + 6E27A74B1F9E432900C390B3 /* NoticeInfor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NoticeInfor.h; sourceTree = "<group>"; };
  115 + 6E27A74C1F9E432900C390B3 /* NoticeInfor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NoticeInfor.m; sourceTree = "<group>"; };
110 116 6E48AF0B1F2F9D3200C1D184 /* CustomTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomTextField.h; sourceTree = "<group>"; };
111 117 6E48AF0C1F2F9D3200C1D184 /* CustomTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomTextField.m; sourceTree = "<group>"; };
112 118 6E7F933A1F35872B00EFBC71 /* TPKeyboardAvoidingCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPKeyboardAvoidingCollectionView.h; sourceTree = "<group>"; };
... ... @@ -131,7 +137,7 @@
131 137 6E84E3991F27A703001EB88E /* LifeLogUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LifeLogUITests.m; sourceTree = "<group>"; };
132 138 6E84E39B1F27A703001EB88E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
133 139 6E84E3AD1F27A975001EB88E /* HomeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomeViewController.h; sourceTree = "<group>"; };
134   - 6E84E3AE1F27A975001EB88E /* HomeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomeViewController.m; sourceTree = "<group>"; };
  140 + 6E84E3AE1F27A975001EB88E /* HomeViewConb troller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "HomeViewConb troller.m"; sourceTree = "<group>"; };
135 141 6E84E3AF1F27A975001EB88E /* HomeViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = HomeViewController.xib; sourceTree = "<group>"; };
136 142 6E84E3B21F27A98B001EB88E /* HistoryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryViewController.h; sourceTree = "<group>"; };
137 143 6E84E3B31F27A98B001EB88E /* HistoryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HistoryViewController.m; sourceTree = "<group>"; };
... ... @@ -296,6 +302,10 @@
296 302 E9497FD41F46EC1100E6AF8D /* MemberObject.m */,
297 303 E97588FA1F513BAD00782484 /* RankingObject.h */,
298 304 E97588FB1F513BAD00782484 /* RankingObject.m */,
  305 + 6E27A7481F9E41B300C390B3 /* HomeObject.h */,
  306 + 6E27A7491F9E41B400C390B3 /* HomeObject.m */,
  307 + 6E27A74B1F9E432900C390B3 /* NoticeInfor.h */,
  308 + 6E27A74C1F9E432900C390B3 /* NoticeInfor.m */,
299 309 );
300 310 name = Model;
301 311 sourceTree = "<group>";
... ... @@ -411,7 +421,7 @@
411 421 children = (
412 422 6E8DA0F31F2BAC0800CCE941 /* Today */,
413 423 6E84E3AD1F27A975001EB88E /* HomeViewController.h */,
414   - 6E84E3AE1F27A975001EB88E /* HomeViewController.m */,
  424 + 6E84E3AE1F27A975001EB88E /* HomeViewConb troller.m */,
415 425 6E84E3AF1F27A975001EB88E /* HomeViewController.xib */,
416 426 );
417 427 name = Home;
... ... @@ -845,6 +855,7 @@
845 855 E968550A1F3C444900317CEF /* AutoTransButton.m in Sources */,
846 856 6EA4AF321F40BB7A00F52CFE /* TargetInfor.m in Sources */,
847 857 E933E6741F3E0E4E002926F5 /* GroupObject.m in Sources */,
  858 + 6E27A74D1F9E432900C390B3 /* NoticeInfor.m in Sources */,
848 859 9CBDA0FA1F2ECE2C0055DED1 /* BaseViewController.m in Sources */,
849 860 6E8DA0F71F2BAC3400CCE941 /* TodayViewController.m in Sources */,
850 861 6E7F93451F35872B00EFBC71 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */,
851 862  
... ... @@ -852,8 +863,9 @@
852 863 E9D909211F3D559D004CF99F /* TweetObject.m in Sources */,
853 864 6E48AF0D1F2F9D3300C1D184 /* CustomTextField.m in Sources */,
854 865 E99E13AB1F336F3600C78787 /* CollectionView.m in Sources */,
855   - 6E84E3B01F27A975001EB88E /* HomeViewController.m in Sources */,
  866 + 6E84E3B01F27A975001EB88E /* HomeViewConb troller.m in Sources */,
856 867 E9373E471F3596940059355A /* AutoTransLabel.m in Sources */,
  868 + 6E27A74A1F9E41B400C390B3 /* HomeObject.m in Sources */,
857 869 6E84E3791F27A701001EB88E /* AppDelegate.m in Sources */,
858 870 6E84E3BA1F27A9A0001EB88E /* RankingViewController.m in Sources */,
859 871 6E7F93441F35872B00EFBC71 /* TPKeyboardAvoidingTableView.m in Sources */,
860 872  
... ... @@ -1025,8 +1037,10 @@
1025 1037 baseConfigurationReference = 0FC2D57087AF4571C57FAE08 /* Pods-LifeLog.debug.xcconfig */;
1026 1038 buildSettings = {
1027 1039 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  1040 + CODE_SIGN_IDENTITY = "iPhone Distribution";
1028 1041 "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
1029   - DEVELOPMENT_TEAM = "";
  1042 + CODE_SIGN_STYLE = Automatic;
  1043 + DEVELOPMENT_TEAM = UXU4V3VUN4;
1030 1044 INFOPLIST_FILE = LifeLog/Info.plist;
1031 1045 IPHONEOS_DEPLOYMENT_TARGET = 9.0;
1032 1046 LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1033 1047  
... ... @@ -1049,8 +1063,10 @@
1049 1063 baseConfigurationReference = 4CFDA5714AF852358A1EB515 /* Pods-LifeLog.release.xcconfig */;
1050 1064 buildSettings = {
1051 1065 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  1066 + CODE_SIGN_IDENTITY = "iPhone Distribution";
1052 1067 "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
1053   - DEVELOPMENT_TEAM = "";
  1068 + CODE_SIGN_STYLE = Automatic;
  1069 + DEVELOPMENT_TEAM = UXU4V3VUN4;
1054 1070 INFOPLIST_FILE = LifeLog/Info.plist;
1055 1071 IPHONEOS_DEPLOYMENT_TARGET = 9.0;
1056 1072 LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LifeLog/LifeLog/Entities.h
... ... @@ -16,8 +16,8 @@
16 16 #import "TweetObject.h"
17 17 #import "HistoryObject.h"
18 18 #import "User.h"
19   -#import "TopObject.h"
20 19 #import "RankingObject.h"
  20 +#import "HomeObject.h"
21 21  
22 22 #endif /* Entities_h */
LifeLog/LifeLog/HomeObject.h
  1 +//
  2 +// HomeObject.h
  3 +// LifeLog
  4 +//
  5 +// Created by Nguyen Van Phong on 10/23/17.
  6 +// Copyright ยฉ 2017 PhongNV. All rights reserved.
  7 +//
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +#import "TopObject.h"
  11 +#import "NoticeInfor.h"
  12 +
  13 +@interface HomeObject : NSObject
  14 +@property (nonatomic, strong) TargetInfor *targetInfor;
  15 +@property (nonatomic, strong) NSMutableArray *listNotice;
  16 +@end
LifeLog/LifeLog/HomeObject.m
  1 +//
  2 +// HomeObject.m
  3 +// LifeLog
  4 +//
  5 +// Created by Nguyen Van Phong on 10/23/17.
  6 +// Copyright ยฉ 2017 PhongNV. All rights reserved.
  7 +//
  8 +
  9 +#import "HomeObject.h"
  10 +
  11 +@implementation HomeObject
  12 +
  13 +@end
LifeLog/LifeLog/HomeViewConb troller.m
  1 +//
  2 +// HomeViewController.m
  3 +// LifeLog
  4 +//
  5 +// Created by Nguyen Van Phong on 7/25/17.
  6 +// Copyright ยฉ 2017 PhongNV. All rights reserved.
  7 +//
  8 +
  9 +#import "HomeViewController.h"
  10 +#import "NSDate+helper.h"
  11 +#import <CoreMotion/CoreMotion.h>
  12 +#import "CMMotionActivityExtra.h"
  13 +#import "TodayViewController.h"
  14 +#import "Utilities.h"
  15 +#import <MBProgressHUD/MBProgressHUD.h>
  16 +#import "ServerAPI.h"
  17 +
  18 +static NSInteger maxRequest = 20;
  19 +static NSInteger numberTotal = 10000;
  20 +
  21 +@interface HomeViewController ()
  22 +{
  23 + MBProgressHUD *progressHud;
  24 + NSInteger targetStep;
  25 +}
  26 +@property (nonatomic, weak) IBOutlet UILabel *lblTitle;
  27 +@property (nonatomic, weak) IBOutlet UIImageView *avatar;
  28 +@property (nonatomic, weak) IBOutlet UILabel *lblDateCurrent;
  29 +@property (nonatomic, weak) IBOutlet UILabel *lblValueStep;
  30 +@property (nonatomic, weak) IBOutlet UILabel *lblUnitStep;
  31 +@property (nonatomic, weak) IBOutlet UILabel *lblValueStepOther;
  32 +@property (nonatomic, weak) IBOutlet UILabel *lblPercent;
  33 +@property (nonatomic, weak) IBOutlet UILabel *lblNotice;
  34 +@property (weak, nonatomic) IBOutlet UISegmentedControl *segmentHome;
  35 +@property (weak, nonatomic) IBOutlet UITextView *tvNotice;
  36 +
  37 +@property (nonatomic, strong) CMPedometer *pedometer;
  38 +@property (nonatomic, strong) CMMotionActivityManager *motionActivityManager;
  39 +@property (nonatomic, strong) NSOperationQueue *operationQueue;
  40 +@property (nonatomic, strong) NSTimer *timer;
  41 +@property (nonatomic, assign) NSInteger bike;
  42 +@property (nonatomic, assign) NSInteger walking;
  43 +@property (nonatomic, assign) NSInteger running;
  44 +@property (nonatomic, strong) NSDate *dateCurrent;
  45 +
  46 +@property (nonatomic, assign) int totalRequest;
  47 +@property (nonatomic, assign) int countComplete;
  48 +@property (nonatomic, assign) int currentIndex;
  49 +
  50 +@end
  51 +
  52 +@implementation HomeViewController
  53 +
  54 +- (void)viewDidLoad {
  55 + [super viewDidLoad];
  56 +
  57 + self.lblTitle.text = NSLocalizedString(@"lifelog.home.title", nil);
  58 +
  59 + [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.topLayoutGuide attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.lblTitle attribute:NSLayoutAttributeTop multiplier:1 constant:0]];
  60 +
  61 + self.avatar.backgroundColor = [UIColor whiteColor];
  62 + self.avatar.layer.borderWidth = 2.0f;
  63 + self.avatar.layer.borderColor = [[UIColor whiteColor] CGColor];
  64 + self.avatar.layer.cornerRadius = self.avatar.frame.size.width/2.0f;
  65 + self.avatar.layer.masksToBounds = YES;
  66 + NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:kUser];
  67 + User *user = (User *)[NSKeyedUnarchiver unarchiveObjectWithData:data];
  68 + if (user != nil) {
  69 + NSString *linkImage = [NSString stringWithFormat:@"%@%@", kServerAddress, user.profile_image];
  70 + NSURL *urlImage = [NSURL URLWithString:linkImage];
  71 + NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
  72 + sessionConfig.timeoutIntervalForRequest = 30.0;
  73 + sessionConfig.timeoutIntervalForResource = 60.0;
  74 + sessionConfig.HTTPMaximumConnectionsPerHost = 20;
  75 + sessionConfig.allowsCellularAccess = YES;
  76 + HomeViewController __weak *weakSelf = self;
  77 + NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig];
  78 + NSURLSessionDataTask *downloadPhotoTask = [session
  79 + dataTaskWithURL:urlImage completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
  80 + if (weakSelf == nil)
  81 + {
  82 + return;
  83 + }
  84 + if (error == nil) {
  85 + UIImage *image = [[UIImage alloc] initWithData:data];
  86 + [[NSOperationQueue mainQueue] addOperationWithBlock:^{
  87 + weakSelf.avatar.image = image;
  88 + }];
  89 + }
  90 + }];
  91 + [downloadPhotoTask resume];
  92 + }
  93 +
  94 + self.lblNotice.text = NSLocalizedString(@"lifelog.home.notice", nil);
  95 +
  96 + _dateCurrent = [NSDate date];
  97 + self.lblDateCurrent.text = [NSString stringWithFormat:@"%ld%@%ld%@%ld%@", (long)[_dateCurrent getYear], NSLocalizedString(@"lifelog.common.year", nil), (long)[_dateCurrent getMonth], NSLocalizedString(@"lifelog.common.month", nil), (long)[_dateCurrent getDay], NSLocalizedString(@"lifelog.common.day", nil)];
  98 +
  99 + self.lblUnitStep.text = NSLocalizedString(@"lifelog.home.unit.step", nil);
  100 +
  101 + if ([CMPedometer isStepCountingAvailable]) {
  102 + _pedometer = [[CMPedometer alloc] init];
  103 + }
  104 + if ([CMMotionActivityManager isActivityAvailable]) {
  105 + _motionActivityManager = [[CMMotionActivityManager alloc] init];
  106 + }
  107 + _operationQueue = [[NSOperationQueue alloc] init];
  108 + _bike = 0;
  109 + _walking = 0;
  110 + _running = 0;
  111 + _segmentHome.selectedSegmentIndex = 1;
  112 + _totalRequest = 0;
  113 + _countComplete = 0;
  114 +
  115 + progressHud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
  116 + progressHud.mode = MBProgressHUDModeIndeterminate;
  117 + progressHud.detailsLabel.text = NSLocalizedString(@"lifelog.home.progressHud.title", nil);
  118 + // [self saveDataStep7LastDay];
  119 + targetStep = numberTotal;
  120 +}
  121 +
  122 +- (void)viewWillAppear:(BOOL)animated {
  123 + [super viewWillAppear:animated];
  124 + NSDate *dateNow = [NSDate date];
  125 + [self saveStepForDay:dateNow];
  126 +}
  127 +
  128 +- (void)requestTopByDate:(NSDate *)date {
  129 + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
  130 + [dateFormatter setDateFormat:@"yyyy-MM-dd"];
  131 + NSString *dateString = [dateFormatter stringFromDate:date];
  132 + [progressHud showAnimated:YES];
  133 + [progressHud setHidden:NO];
  134 + HomeViewController __weak *weakSelf = self;
  135 + int mode = 1;
  136 + switch (_segmentHome.selectedSegmentIndex) {
  137 + case 0:
  138 + mode = 3;
  139 + break;
  140 +
  141 + case 1:
  142 + mode = 1;
  143 + break;
  144 +
  145 + case 2:
  146 + mode = 2;
  147 + break;
  148 +
  149 + default:
  150 + break;
  151 + }
  152 + [[ServerAPI server] requestTopWithMode:mode andDate:dateString CompletionHandler:^(TopObject *topObject, NSError *error) {
  153 + if(weakSelf == nil) {
  154 + return ;
  155 + }
  156 + if (error == nil) {
  157 + NSLog(@"TopObject: %@", topObject);
  158 + dispatch_async(dispatch_get_main_queue(), ^{
  159 + [weakSelf updateStepUI:topObject.targetInfor];
  160 + });
  161 + }
  162 + else {
  163 + dispatch_async(dispatch_get_main_queue(), ^{
  164 + NSString *message = [error.userInfo objectForKey:@"message"];
  165 + [Utilities showErrorMessage:message withViewController:weakSelf];
  166 + });
  167 + }
  168 + dispatch_async(dispatch_get_main_queue(), ^{
  169 + [progressHud setHidden:YES];
  170 + });
  171 + }];
  172 + [[ServerAPI server] requestHomeWithMode:mode andDate:dateString CompletionHandler:^(HomeObject *homeObject, NSError *error) {
  173 + if(weakSelf == nil) {
  174 + return ;
  175 + }
  176 + if (error == nil) {
  177 + NSLog(@"List Notices: %@", homeObject.listNotice);
  178 + for (NoticeInfor *noticeInfor in homeObject.listNotice) {
  179 + NSLog(@"noticeInfor: %@", noticeInfor.notice_content);
  180 + }
  181 + dispatch_async(dispatch_get_main_queue(), ^{
  182 + [weakSelf updateNoticeUI:homeObject];
  183 + });
  184 + }
  185 + else {
  186 + dispatch_async(dispatch_get_main_queue(), ^{
  187 + NSString *message = [error.userInfo objectForKey:@"message"];
  188 + [Utilities showErrorMessage:message withViewController:weakSelf];
  189 + });
  190 + }
  191 + dispatch_async(dispatch_get_main_queue(), ^{
  192 + [progressHud setHidden:YES];
  193 + });
  194 + }];
  195 +}
  196 +
  197 +- (void)viewWillDisappear:(BOOL)animated {
  198 + [super viewWillDisappear:animated];
  199 +}
  200 +
  201 +- (void)didReceiveMemoryWarning {
  202 + [super didReceiveMemoryWarning];
  203 + // Dispose of any resources that can be recreated.
  204 +}
  205 +
  206 +#pragma mark - IBAction
  207 +- (IBAction)menuButtonTouchUpInside:(id)sender
  208 +{
  209 +
  210 +}
  211 +
  212 +- (IBAction)todayButtonTouchUpInside:(id)sender
  213 +{
  214 + TodayViewController *todayVC = [[TodayViewController alloc] initWithNibName:@"TodayViewController" bundle:nil];
  215 + todayVC.targetStep = targetStep;
  216 + [self.navigationController pushViewController:todayVC animated:YES];
  217 +}
  218 +
  219 +- (IBAction)leftButtonTouchUpInside:(id)sender
  220 +{
  221 + self.dateCurrent = [self.dateCurrent dateByAddingTimeInterval:-(24*60*60)];
  222 + self.lblDateCurrent.text = [NSString stringWithFormat:@"%ld%@%ld%@%ld%@", (long)[_dateCurrent getYear], NSLocalizedString(@"lifelog.common.year", nil), (long)[_dateCurrent getMonth], NSLocalizedString(@"lifelog.common.month", nil), (long)[_dateCurrent getDay], NSLocalizedString(@"lifelog.common.day", nil)];
  223 + [self resetStepUI];
  224 + [self saveStepForDay:self.dateCurrent];
  225 +}
  226 +
  227 +- (IBAction)rightButtonTouchUpInside:(id)sender
  228 +{
  229 + self.dateCurrent = [self.dateCurrent dateByAddingTimeInterval:24*60*60];
  230 + self.lblDateCurrent.text = [NSString stringWithFormat:@"%ld%@%ld%@%ld%@", (long)[_dateCurrent getYear], NSLocalizedString(@"lifelog.common.year", nil), (long)[_dateCurrent getMonth], NSLocalizedString(@"lifelog.common.month", nil), (long)[_dateCurrent getDay], NSLocalizedString(@"lifelog.common.day", nil)];
  231 + [self resetStepUI];
  232 + //[self saveStepForDay:self.dateCurrent];
  233 + [self requestTopByDate:self.dateCurrent];
  234 +}
  235 +
  236 +- (IBAction)segmentValueChange:(id)sender {
  237 + [self resetStepUI];
  238 + [self requestTopByDate:self.dateCurrent];
  239 +}
  240 +
  241 +#pragma mark - Functions Private
  242 +- (void)saveStepForDay:(NSDate *)date
  243 +{
  244 + if ([CMMotionActivityManager isActivityAvailable]) {
  245 + [progressHud showAnimated:YES];
  246 + [progressHud setHidden:NO];
  247 + self.bike = 0;
  248 + self.walking = 0;
  249 + self.running = 0;
  250 + NSDate *startDate = [date beginningAtMidnightOfDay];
  251 + NSDate *endDate = [startDate dateByAddingTimeInterval:(24*60*60 - 1)];
  252 +
  253 + HomeViewController __weak *weakSelf = self;
  254 + dispatch_queue_t myQueue = dispatch_queue_create("mobileworld.jp.lifelog.forDay", NULL);
  255 + dispatch_async(myQueue, ^{
  256 + if (weakSelf == nil) {
  257 + return ;
  258 + }
  259 +
  260 + [weakSelf.motionActivityManager queryActivityStartingFromDate:startDate toDate:endDate toQueue:_operationQueue withHandler:^(NSArray<CMMotionActivity *> * _Nullable activities, NSError * _Nullable error) {
  261 + if (error || activities.count <= 0) {
  262 + dispatch_async(dispatch_get_main_queue(), ^{
  263 + [weakSelf updateStepUI];
  264 + });
  265 + return ;
  266 + }
  267 + // set EndDate
  268 + NSMutableArray *arrayActivities = [[NSMutableArray alloc] init];
  269 + for (int i = 0; i < activities.count; i++) {
  270 + CMMotionActivity *activity = [activities objectAtIndex:i];
  271 + CMMotionActivityExtra *activityExtra = [[CMMotionActivityExtra alloc] init];
  272 + activityExtra.activity = activity;
  273 + if (i == activities.count - 1) {
  274 + activityExtra.endDate = endDate;
  275 + }
  276 + else {
  277 + CMMotionActivity *activityNext = [activities objectAtIndex:i+1];
  278 + // activityExtra.endDate = [activityNext.startDate dateByAddingTimeInterval:-1];
  279 + activityExtra.endDate = activityNext.startDate;
  280 + }
  281 + [arrayActivities addObject:activityExtra];
  282 + }
  283 + // PhongNV
  284 + weakSelf.currentIndex = 0;
  285 + [weakSelf save20objectOfActivityExtras:arrayActivities];
  286 + }];
  287 + });
  288 + }
  289 +}
  290 +
  291 +- (void)complete20Request:(NSArray *)activities {
  292 + if (self.totalRequest == self.countComplete) {
  293 + self.totalRequest = 0;
  294 + self.countComplete = 0;
  295 + self.currentIndex++;
  296 + [self save20objectOfActivityExtras:activities];
  297 + }
  298 +}
  299 +- (void)save20objectOfActivityExtras:(NSArray *)activities
  300 +{
  301 + int result = floor(activities.count / maxRequest);
  302 + if (activities.count <= 0 || self.currentIndex > result) {
  303 + self.totalRequest = 0;
  304 + self.countComplete = 0;
  305 + self.currentIndex = 0;
  306 + dispatch_async(dispatch_get_main_queue(), ^{
  307 + [self updateStepUI];
  308 + });
  309 + return;
  310 + }
  311 +
  312 + HomeViewController __weak *weakSelf = self;
  313 + for (NSInteger index = self.currentIndex*maxRequest; index < self.currentIndex*maxRequest + maxRequest; index++) {
  314 + if ((self.currentIndex*maxRequest + maxRequest) >= activities.count) {
  315 + self.totalRequest = (int)(activities.count - self.currentIndex*maxRequest);
  316 + if (self.totalRequest <= 0) {
  317 + [weakSelf complete20Request:activities];
  318 + }
  319 + }
  320 + else {
  321 + self.totalRequest = (int)maxRequest;
  322 + }
  323 + if (index < activities.count) {
  324 + CMMotionActivityExtra *activityExtra = [activities objectAtIndex:index];
  325 + [self.pedometer queryPedometerDataFromDate:activityExtra.activity.startDate toDate:activityExtra.endDate withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) {
  326 + if (weakSelf == nil) {
  327 + return ;
  328 + }
  329 + NSInteger numberStep = [pedometerData.numberOfSteps integerValue];
  330 + int mode = 1;
  331 + if (activityExtra.activity.cycling) {
  332 + mode = 3;
  333 + }
  334 + else if (activityExtra.activity.walking) {
  335 + mode = 1;
  336 + }
  337 + else if (activityExtra.activity.running) {
  338 + mode = 2;
  339 + }
  340 + else {
  341 + // unknown
  342 + }
  343 + // save step to server
  344 + if (numberStep > 0) {
  345 + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
  346 + [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  347 + NSString *dateBegin = [dateFormatter stringFromDate:activityExtra.activity.startDate];
  348 + NSString *dateEnd = [dateFormatter stringFromDate:activityExtra.endDate];
  349 + NSLog(@"dateBegin: %@ | dateEnd: %@ | numberStep: %li", dateBegin, dateEnd, numberStep);
  350 + [[ServerAPI server] requestCreateLog:mode withStep:(int)numberStep startDate:dateBegin endDate:dateEnd CompletionHandler:^(NSError *error) {
  351 + if (error) {
  352 + NSLog(@"Error: %@", error);
  353 + }
  354 + weakSelf.countComplete++;
  355 + [weakSelf complete20Request:activities];
  356 + }];
  357 + }
  358 + else {
  359 + weakSelf.countComplete++;
  360 + [weakSelf complete20Request:activities];
  361 + }
  362 + }];
  363 + }
  364 + }
  365 +}
  366 +
  367 +- (void)updateStepUI
  368 +{
  369 + [self requestTopByDate:self.dateCurrent];
  370 +}
  371 +
  372 +- (void)saveDataStep7LastDay
  373 +{
  374 + NSDate *dateNow = [NSDate date];
  375 + for (int index = 0; index < 7; index++) {
  376 + dateNow = [dateNow dateByAddingTimeInterval:-(24*60*60)];
  377 + [self saveStepByDate:dateNow];
  378 + }
  379 +}
  380 +
  381 +- (void)saveStepByDate:(NSDate *)date
  382 +{
  383 + if ([CMMotionActivityManager isActivityAvailable]) {
  384 + NSDate *startDate = [date beginningAtMidnightOfDay];
  385 + NSDate *endDate = [startDate dateByAddingTimeInterval:(24*60*60 - 1)];
  386 +
  387 + HomeViewController __weak *weakSelf = self;
  388 + dispatch_queue_t myQueue = dispatch_queue_create("mobileworld.jp.lifelog.7lastday", NULL);
  389 + dispatch_async(myQueue, ^{
  390 + if (weakSelf == nil) {
  391 + return ;
  392 + }
  393 +
  394 + [weakSelf.motionActivityManager queryActivityStartingFromDate:startDate toDate:endDate toQueue:_operationQueue withHandler:^(NSArray<CMMotionActivity *> * _Nullable activities, NSError * _Nullable error) {
  395 + if (error || activities.count <= 0) {
  396 + return ;
  397 + }
  398 + // set EndDate
  399 + NSMutableArray *arrayActivities = [[NSMutableArray alloc] init];
  400 + for (int i = 0; i < activities.count; i++) {
  401 + CMMotionActivity *activity = [activities objectAtIndex:i];
  402 + CMMotionActivityExtra *activityExtra = [[CMMotionActivityExtra alloc] init];
  403 + activityExtra.activity = activity;
  404 + if (i == activities.count - 1) {
  405 + activityExtra.endDate = endDate;
  406 + }
  407 + else {
  408 + CMMotionActivity *activityNext = [activities objectAtIndex:i+1];
  409 + activityExtra.endDate = [activityNext.startDate dateByAddingTimeInterval:-1];
  410 + }
  411 + [arrayActivities addObject:activityExtra];
  412 + }
  413 +
  414 + for (CMMotionActivityExtra *activityExtra in arrayActivities) {
  415 + [weakSelf.pedometer queryPedometerDataFromDate:activityExtra.activity.startDate toDate:activityExtra.endDate withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) {
  416 + NSInteger numberStep = [pedometerData.numberOfSteps integerValue];
  417 + int mode = 1;
  418 + if (activityExtra.activity.cycling) {
  419 + mode = 3;
  420 + }
  421 + else if (activityExtra.activity.walking) {
  422 + mode = 1;
  423 + }
  424 + else if (activityExtra.activity.running) {
  425 + mode = 2;
  426 + }
  427 + else {
  428 + // unknown
  429 + }
  430 +
  431 + // save step to server
  432 + if (numberStep > 0) {
  433 + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
  434 + [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  435 + NSString *dateBegin = [dateFormatter stringFromDate:activityExtra.activity.startDate];
  436 + NSString *dateEnd = [dateFormatter stringFromDate:activityExtra.endDate];
  437 + [[ServerAPI server] requestCreateLog:mode withStep:(int)numberStep startDate:dateBegin endDate:dateEnd CompletionHandler:^(NSError *error) {
  438 + if (error) {
  439 + NSLog(@"Error: %@", error);
  440 + }
  441 + }];
  442 + }
  443 + }];
  444 + }
  445 + }];
  446 + });
  447 + }
  448 +}
  449 +
  450 +- (void)updateStepUI:(TargetInfor *)targetInfor
  451 +{
  452 + NSString *stringTargetStep = [targetInfor.target_step stringByReplacingOccurrencesOfString:@"," withString:@""];
  453 + targetStep = [stringTargetStep integerValue];
  454 + self.lblValueStep.text = targetInfor.num_step;
  455 + self.lblValueStepOther.text = [NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"lifelog.today.remaining.other", nil), targetInfor.remaining_step];
  456 + self.lblPercent.text = [NSString stringWithFormat:@"%@ %i%@", NSLocalizedString(@"lifelog.today.text.percent", nil), [targetInfor.complete_percent intValue], NSLocalizedString(@"lifelog.today.percent", nil)];
  457 +}
  458 +
  459 +- (void)updateNoticeUI:(HomeObject *)homeObject
  460 +{
  461 + NSString *stringNotice = @"";
  462 + for (NoticeInfor *notice in homeObject.listNotice) {
  463 + NSString *noticeString = [NSString stringWithFormat:@"%@\n", notice.notice_content];
  464 + stringNotice = [stringNotice stringByAppendingString:noticeString];
  465 + }
  466 + _tvNotice.text = stringNotice;
  467 +}
  468 +
  469 +- (void)resetStepUI
  470 +{
  471 + self.lblValueStep.text = @"";
  472 + self.lblValueStepOther.text = @"";
  473 + self.lblPercent.text = @"";
  474 +}
  475 +
  476 +@end
LifeLog/LifeLog/HomeViewController.m
1   -//
2   -// HomeViewController.m
3   -// LifeLog
4   -//
5   -// Created by Nguyen Van Phong on 7/25/17.
6   -// Copyright ยฉ 2017 PhongNV. All rights reserved.
7   -//
8   -
9   -#import "HomeViewController.h"
10   -#import "NSDate+helper.h"
11   -#import <CoreMotion/CoreMotion.h>
12   -#import "CMMotionActivityExtra.h"
13   -#import "TodayViewController.h"
14   -#import "Utilities.h"
15   -#import <MBProgressHUD/MBProgressHUD.h>
16   -#import "ServerAPI.h"
17   -
18   -static NSInteger maxRequest = 20;
19   -static NSInteger numberTotal = 10000;
20   -
21   -@interface HomeViewController ()
22   -{
23   - MBProgressHUD *progressHud;
24   - NSInteger targetStep;
25   -}
26   -@property (nonatomic, weak) IBOutlet UILabel *lblTitle;
27   -@property (nonatomic, weak) IBOutlet UIImageView *avatar;
28   -@property (nonatomic, weak) IBOutlet UILabel *lblDateCurrent;
29   -@property (nonatomic, weak) IBOutlet UILabel *lblValueStep;
30   -@property (nonatomic, weak) IBOutlet UILabel *lblUnitStep;
31   -@property (nonatomic, weak) IBOutlet UILabel *lblValueStepOther;
32   -@property (nonatomic, weak) IBOutlet UILabel *lblPercent;
33   -@property (nonatomic, weak) IBOutlet UILabel *lblNotice;
34   -@property (weak, nonatomic) IBOutlet UISegmentedControl *segmentHome;
35   -
36   -@property (nonatomic, strong) CMPedometer *pedometer;
37   -@property (nonatomic, strong) CMMotionActivityManager *motionActivityManager;
38   -@property (nonatomic, strong) NSOperationQueue *operationQueue;
39   -@property (nonatomic, strong) NSTimer *timer;
40   -@property (nonatomic, assign) NSInteger bike;
41   -@property (nonatomic, assign) NSInteger walking;
42   -@property (nonatomic, assign) NSInteger running;
43   -@property (nonatomic, strong) NSDate *dateCurrent;
44   -
45   -@property (nonatomic, assign) int totalRequest;
46   -@property (nonatomic, assign) int countComplete;
47   -@property (nonatomic, assign) int currentIndex;
48   -
49   -@end
50   -
51   -@implementation HomeViewController
52   -
53   -- (void)viewDidLoad {
54   - [super viewDidLoad];
55   -
56   - self.lblTitle.text = NSLocalizedString(@"lifelog.home.title", nil);
57   -
58   - [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.topLayoutGuide attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.lblTitle attribute:NSLayoutAttributeTop multiplier:1 constant:0]];
59   -
60   - self.avatar.backgroundColor = [UIColor whiteColor];
61   - self.avatar.layer.borderWidth = 2.0f;
62   - self.avatar.layer.borderColor = [[UIColor whiteColor] CGColor];
63   - self.avatar.layer.cornerRadius = self.avatar.frame.size.width/2.0f;
64   - self.avatar.layer.masksToBounds = YES;
65   - NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:kUser];
66   - User *user = (User *)[NSKeyedUnarchiver unarchiveObjectWithData:data];
67   - if (user != nil) {
68   - NSString *linkImage = [NSString stringWithFormat:@"%@%@", kServerAddress, user.profile_image];
69   - NSURL *urlImage = [NSURL URLWithString:linkImage];
70   - NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
71   - sessionConfig.timeoutIntervalForRequest = 30.0;
72   - sessionConfig.timeoutIntervalForResource = 60.0;
73   - sessionConfig.HTTPMaximumConnectionsPerHost = 20;
74   - sessionConfig.allowsCellularAccess = YES;
75   - HomeViewController __weak *weakSelf = self;
76   - NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig];
77   - NSURLSessionDataTask *downloadPhotoTask = [session
78   - dataTaskWithURL:urlImage completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
79   - if (weakSelf == nil)
80   - {
81   - return;
82   - }
83   - if (error == nil) {
84   - UIImage *image = [[UIImage alloc] initWithData:data];
85   - [[NSOperationQueue mainQueue] addOperationWithBlock:^{
86   - weakSelf.avatar.image = image;
87   - }];
88   - }
89   - }];
90   - [downloadPhotoTask resume];
91   - }
92   -
93   - self.lblNotice.text = NSLocalizedString(@"lifelog.home.notice", nil);
94   -
95   - _dateCurrent = [NSDate date];
96   - self.lblDateCurrent.text = [NSString stringWithFormat:@"%ld%@%ld%@%ld%@", (long)[_dateCurrent getYear], NSLocalizedString(@"lifelog.common.year", nil), (long)[_dateCurrent getMonth], NSLocalizedString(@"lifelog.common.month", nil), (long)[_dateCurrent getDay], NSLocalizedString(@"lifelog.common.day", nil)];
97   -
98   - self.lblUnitStep.text = NSLocalizedString(@"lifelog.home.unit.step", nil);
99   -
100   - if ([CMPedometer isStepCountingAvailable]) {
101   - _pedometer = [[CMPedometer alloc] init];
102   - }
103   - if ([CMMotionActivityManager isActivityAvailable]) {
104   - _motionActivityManager = [[CMMotionActivityManager alloc] init];
105   - }
106   - _operationQueue = [[NSOperationQueue alloc] init];
107   - _bike = 0;
108   - _walking = 0;
109   - _running = 0;
110   - _segmentHome.selectedSegmentIndex = 1;
111   - _totalRequest = 0;
112   - _countComplete = 0;
113   -
114   - progressHud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
115   - progressHud.mode = MBProgressHUDModeIndeterminate;
116   - progressHud.detailsLabel.text = NSLocalizedString(@"lifelog.home.progressHud.title", nil);
117   - // [self saveDataStep7LastDay];
118   - targetStep = numberTotal;
119   -}
120   -
121   -- (void)viewWillAppear:(BOOL)animated {
122   - [super viewWillAppear:animated];
123   - NSDate *dateNow = [NSDate date];
124   - [self saveStepForDay:dateNow];
125   -}
126   -
127   -- (void)requestTopByDate:(NSDate *)date {
128   - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
129   - [dateFormatter setDateFormat:@"yyyy-MM-dd"];
130   - NSString *dateString = [dateFormatter stringFromDate:date];
131   - [progressHud showAnimated:YES];
132   - [progressHud setHidden:NO];
133   - HomeViewController __weak *weakSelf = self;
134   - int mode = 1;
135   - switch (_segmentHome.selectedSegmentIndex) {
136   - case 0:
137   - mode = 3;
138   - break;
139   -
140   - case 1:
141   - mode = 1;
142   - break;
143   -
144   - case 2:
145   - mode = 2;
146   - break;
147   -
148   - default:
149   - break;
150   - }
151   - [[ServerAPI server] requestTopWithMode:mode andDate:dateString CompletionHandler:^(TopObject *topObject, NSError *error) {
152   - if(weakSelf == nil) {
153   - return ;
154   - }
155   - if (error == nil) {
156   - NSLog(@"TopObject: %@", topObject);
157   - dispatch_async(dispatch_get_main_queue(), ^{
158   - [weakSelf updateStepUI:topObject.targetInfor];
159   - });
160   - }
161   - else {
162   - dispatch_async(dispatch_get_main_queue(), ^{
163   - NSString *message = [error.userInfo objectForKey:@"message"];
164   - [Utilities showErrorMessage:message withViewController:weakSelf];
165   - });
166   - }
167   - dispatch_async(dispatch_get_main_queue(), ^{
168   - [progressHud setHidden:YES];
169   - });
170   - }];
171   -}
172   -
173   -- (void)viewWillDisappear:(BOOL)animated {
174   - [super viewWillDisappear:animated];
175   -}
176   -
177   -- (void)didReceiveMemoryWarning {
178   - [super didReceiveMemoryWarning];
179   - // Dispose of any resources that can be recreated.
180   -}
181   -
182   -#pragma mark - IBAction
183   -- (IBAction)menuButtonTouchUpInside:(id)sender
184   -{
185   -
186   -}
187   -
188   -- (IBAction)todayButtonTouchUpInside:(id)sender
189   -{
190   - TodayViewController *todayVC = [[TodayViewController alloc] initWithNibName:@"TodayViewController" bundle:nil];
191   - todayVC.targetStep = targetStep;
192   - [self.navigationController pushViewController:todayVC animated:YES];
193   -}
194   -
195   -- (IBAction)leftButtonTouchUpInside:(id)sender
196   -{
197   - self.dateCurrent = [self.dateCurrent dateByAddingTimeInterval:-(24*60*60)];
198   - self.lblDateCurrent.text = [NSString stringWithFormat:@"%ld%@%ld%@%ld%@", (long)[_dateCurrent getYear], NSLocalizedString(@"lifelog.common.year", nil), (long)[_dateCurrent getMonth], NSLocalizedString(@"lifelog.common.month", nil), (long)[_dateCurrent getDay], NSLocalizedString(@"lifelog.common.day", nil)];
199   - [self resetStepUI];
200   - [self saveStepForDay:self.dateCurrent];
201   -}
202   -
203   -- (IBAction)rightButtonTouchUpInside:(id)sender
204   -{
205   - self.dateCurrent = [self.dateCurrent dateByAddingTimeInterval:24*60*60];
206   - self.lblDateCurrent.text = [NSString stringWithFormat:@"%ld%@%ld%@%ld%@", (long)[_dateCurrent getYear], NSLocalizedString(@"lifelog.common.year", nil), (long)[_dateCurrent getMonth], NSLocalizedString(@"lifelog.common.month", nil), (long)[_dateCurrent getDay], NSLocalizedString(@"lifelog.common.day", nil)];
207   - [self resetStepUI];
208   - //[self saveStepForDay:self.dateCurrent];
209   - [self requestTopByDate:self.dateCurrent];
210   -}
211   -
212   -- (IBAction)segmentValueChange:(id)sender {
213   - [self resetStepUI];
214   - [self requestTopByDate:self.dateCurrent];
215   -}
216   -
217   -#pragma mark - Functions Private
218   -- (void)saveStepForDay:(NSDate *)date
219   -{
220   - if ([CMMotionActivityManager isActivityAvailable]) {
221   - [progressHud showAnimated:YES];
222   - [progressHud setHidden:NO];
223   - self.bike = 0;
224   - self.walking = 0;
225   - self.running = 0;
226   - NSDate *startDate = [date beginningAtMidnightOfDay];
227   - NSDate *endDate = [startDate dateByAddingTimeInterval:(24*60*60 - 1)];
228   -
229   - HomeViewController __weak *weakSelf = self;
230   - dispatch_queue_t myQueue = dispatch_queue_create("mobileworld.jp.lifelog.forDay", NULL);
231   - dispatch_async(myQueue, ^{
232   - if (weakSelf == nil) {
233   - return ;
234   - }
235   -
236   - [weakSelf.motionActivityManager queryActivityStartingFromDate:startDate toDate:endDate toQueue:_operationQueue withHandler:^(NSArray<CMMotionActivity *> * _Nullable activities, NSError * _Nullable error) {
237   - if (error || activities.count <= 0) {
238   - dispatch_async(dispatch_get_main_queue(), ^{
239   - [weakSelf updateStepUI];
240   - });
241   - return ;
242   - }
243   - // set EndDate
244   - NSMutableArray *arrayActivities = [[NSMutableArray alloc] init];
245   - for (int i = 0; i < activities.count; i++) {
246   - CMMotionActivity *activity = [activities objectAtIndex:i];
247   - CMMotionActivityExtra *activityExtra = [[CMMotionActivityExtra alloc] init];
248   - activityExtra.activity = activity;
249   - if (i == activities.count - 1) {
250   - activityExtra.endDate = endDate;
251   - }
252   - else {
253   - CMMotionActivity *activityNext = [activities objectAtIndex:i+1];
254   - activityExtra.endDate = activityNext.startDate;
255   - }
256   - [arrayActivities addObject:activityExtra];
257   - }
258   - // PhongNV
259   - weakSelf.currentIndex = 0;
260   - [weakSelf save20objectOfActivityExtras:arrayActivities];
261   - }];
262   - });
263   - }
264   -}
265   -
266   -- (void)complete20Request:(NSArray *)activities {
267   - if (self.totalRequest == self.countComplete) {
268   - self.totalRequest = 0;
269   - self.countComplete = 0;
270   - self.currentIndex++;
271   - [self save20objectOfActivityExtras:activities];
272   - }
273   -}
274   -- (void)save20objectOfActivityExtras:(NSArray *)activities
275   -{
276   - int result = floor(activities.count / maxRequest);
277   - if (activities.count <= 0 || self.currentIndex > result) {
278   - self.totalRequest = 0;
279   - self.countComplete = 0;
280   - self.currentIndex = 0;
281   - dispatch_async(dispatch_get_main_queue(), ^{
282   - [self updateStepUI];
283   - });
284   - return;
285   - }
286   -
287   - HomeViewController __weak *weakSelf = self;
288   - for (NSInteger index = self.currentIndex*maxRequest; index < self.currentIndex*maxRequest + maxRequest; index++) {
289   - if ((self.currentIndex*maxRequest + maxRequest) >= activities.count) {
290   - self.totalRequest = (int)(activities.count - self.currentIndex*maxRequest);
291   - if (self.totalRequest <= 0) {
292   - [weakSelf complete20Request:activities];
293   - }
294   - }
295   - else {
296   - self.totalRequest = (int)maxRequest;
297   - }
298   - if (index < activities.count) {
299   - CMMotionActivityExtra *activityExtra = [activities objectAtIndex:index];
300   - [self.pedometer queryPedometerDataFromDate:activityExtra.activity.startDate toDate:activityExtra.endDate withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) {
301   - if (weakSelf == nil) {
302   - return ;
303   - }
304   - NSInteger numberStep = [pedometerData.numberOfSteps integerValue];
305   - int mode = 1;
306   - if (activityExtra.activity.cycling) {
307   - mode = 3;
308   - }
309   - else if (activityExtra.activity.walking) {
310   - mode = 1;
311   - }
312   - else if (activityExtra.activity.running) {
313   - mode = 2;
314   - }
315   - else {
316   - // unknown
317   - }
318   - // save step to server
319   - if (numberStep > 0) {
320   - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
321   - [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
322   - NSString *dateBegin = [dateFormatter stringFromDate:activityExtra.activity.startDate];
323   - NSString *dateEnd = [dateFormatter stringFromDate:activityExtra.endDate];
324   - [[ServerAPI server] requestCreateLog:mode withStep:(int)numberStep startDate:dateBegin endDate:dateEnd CompletionHandler:^(NSError *error) {
325   - if (error) {
326   - NSLog(@"Error: %@", error);
327   - }
328   - weakSelf.countComplete++;
329   - [weakSelf complete20Request:activities];
330   - }];
331   - }
332   - else {
333   - weakSelf.countComplete++;
334   - [weakSelf complete20Request:activities];
335   - }
336   - }];
337   - }
338   - }
339   -}
340   -
341   -- (void)updateStepUI
342   -{
343   - [self requestTopByDate:self.dateCurrent];
344   -}
345   -
346   -- (void)saveDataStep7LastDay
347   -{
348   - NSDate *dateNow = [NSDate date];
349   - for (int index = 0; index < 7; index++) {
350   - dateNow = [dateNow dateByAddingTimeInterval:-(24*60*60)];
351   - [self saveStepByDate:dateNow];
352   - }
353   -}
354   -
355   -- (void)saveStepByDate:(NSDate *)date
356   -{
357   - if ([CMMotionActivityManager isActivityAvailable]) {
358   - NSDate *startDate = [date beginningAtMidnightOfDay];
359   - NSDate *endDate = [startDate dateByAddingTimeInterval:(24*60*60 - 1)];
360   -
361   - HomeViewController __weak *weakSelf = self;
362   - dispatch_queue_t myQueue = dispatch_queue_create("mobileworld.jp.lifelog.7lastday", NULL);
363   - dispatch_async(myQueue, ^{
364   - if (weakSelf == nil) {
365   - return ;
366   - }
367   -
368   - [weakSelf.motionActivityManager queryActivityStartingFromDate:startDate toDate:endDate toQueue:_operationQueue withHandler:^(NSArray<CMMotionActivity *> * _Nullable activities, NSError * _Nullable error) {
369   - if (error || activities.count <= 0) {
370   - return ;
371   - }
372   - // set EndDate
373   - NSMutableArray *arrayActivities = [[NSMutableArray alloc] init];
374   - for (int i = 0; i < activities.count; i++) {
375   - CMMotionActivity *activity = [activities objectAtIndex:i];
376   - CMMotionActivityExtra *activityExtra = [[CMMotionActivityExtra alloc] init];
377   - activityExtra.activity = activity;
378   - if (i == activities.count - 1) {
379   - activityExtra.endDate = endDate;
380   - }
381   - else {
382   - CMMotionActivity *activityNext = [activities objectAtIndex:i+1];
383   - activityExtra.endDate = activityNext.startDate;
384   - }
385   - [arrayActivities addObject:activityExtra];
386   - }
387   -
388   - for (CMMotionActivityExtra *activityExtra in arrayActivities) {
389   - [weakSelf.pedometer queryPedometerDataFromDate:activityExtra.activity.startDate toDate:activityExtra.endDate withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) {
390   - NSInteger numberStep = [pedometerData.numberOfSteps integerValue];
391   - int mode = 1;
392   - if (activityExtra.activity.cycling) {
393   - mode = 3;
394   - }
395   - else if (activityExtra.activity.walking) {
396   - mode = 1;
397   - }
398   - else if (activityExtra.activity.running) {
399   - mode = 2;
400   - }
401   - else {
402   - // unknown
403   - }
404   -
405   - // save step to server
406   - if (numberStep > 0) {
407   - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
408   - [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
409   - NSString *dateBegin = [dateFormatter stringFromDate:activityExtra.activity.startDate];
410   - NSString *dateEnd = [dateFormatter stringFromDate:activityExtra.endDate];
411   - [[ServerAPI server] requestCreateLog:mode withStep:(int)numberStep startDate:dateBegin endDate:dateEnd CompletionHandler:^(NSError *error) {
412   - if (error) {
413   - NSLog(@"Error: %@", error);
414   - }
415   - }];
416   - }
417   - }];
418   - }
419   - }];
420   - });
421   - }
422   -}
423   -
424   -- (void)updateStepUI:(TargetInfor *)targetInfor
425   -{
426   - NSString *stringTargetStep = [targetInfor.target_step stringByReplacingOccurrencesOfString:@"," withString:@""];
427   - targetStep = [stringTargetStep integerValue];
428   - self.lblValueStep.text = targetInfor.num_step;
429   - self.lblValueStepOther.text = [NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"lifelog.today.remaining.other", nil), targetInfor.remaining_step];
430   - self.lblPercent.text = [NSString stringWithFormat:@"%@ %i%@", NSLocalizedString(@"lifelog.today.text.percent", nil), [targetInfor.complete_percent intValue], NSLocalizedString(@"lifelog.today.percent", nil)];
431   -}
432   -
433   -- (void)resetStepUI
434   -{
435   - self.lblValueStep.text = @"";
436   - self.lblValueStepOther.text = @"";
437   - self.lblPercent.text = @"";
438   -}
439   -
440   -@end
LifeLog/LifeLog/HomeViewController.xib
1 1 <?xml version="1.0" encoding="UTF-8"?>
2   -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13196" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
3 3 <device id="retina4_7" orientation="portrait">
4 4 <adaptation id="fullscreen"/>
5 5 </device>
6 6 <dependencies>
7   - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
  7 + <deployment identifier="iOS"/>
  8 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13173"/>
8 9 <capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
9 10 <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
10 11 </dependencies>
... ... @@ -20,6 +21,7 @@
20 21 <outlet property="lblValueStep" destination="TUf-Tp-93t" id="qAh-fl-oW4"/>
21 22 <outlet property="lblValueStepOther" destination="3Xj-IB-96h" id="yXj-HA-fDR"/>
22 23 <outlet property="segmentHome" destination="ibb-Yl-iqu" id="lE6-pr-GgT"/>
  24 + <outlet property="tvNotice" destination="kdD-rj-BtX" id="t6k-l8-l2N"/>
23 25 <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
24 26 </connections>
25 27 </placeholder>
... ... @@ -151,7 +153,7 @@
151 153 <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
152 154 <nil key="highlightedColor"/>
153 155 </label>
154   - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lnt-4H-Ao8">
  156 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ใŠ็Ÿฅใ‚‰ใ›" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lnt-4H-Ao8">
155 157 <rect key="frame" x="8" y="275" width="359" height="30"/>
156 158 <constraints>
157 159 <constraint firstAttribute="height" constant="30" id="isj-iQ-BcF"/>
158 160  
159 161  
160 162  
... ... @@ -179,17 +181,27 @@
179 181 <action selector="segmentValueChange:" destination="-1" eventType="valueChanged" id="kL2-mI-baG"/>
180 182 </connections>
181 183 </segmentedControl>
  184 + <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" editable="NO" textAlignment="natural" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kdD-rj-BtX" userLabel="tvNotice">
  185 + <rect key="frame" x="103" y="313" width="264" height="204"/>
  186 + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
  187 + <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
  188 + <fontDescription key="fontDescription" type="system" pointSize="14"/>
  189 + <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
  190 + </textView>
182 191 </subviews>
183 192 <color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
184 193 <constraints>
185 194 <constraint firstItem="IaR-IO-4RA" firstAttribute="leading" secondItem="vRa-cr-YTe" secondAttribute="trailing" constant="8" id="010-mM-SLU"/>
186 195 <constraint firstAttribute="trailing" secondItem="Low-8n-pqa" secondAttribute="trailing" constant="10" id="0OY-h0-Rgg"/>
  196 + <constraint firstAttribute="trailing" secondItem="kdD-rj-BtX" secondAttribute="trailing" constant="8" id="3bP-sY-1pI"/>
187 197 <constraint firstItem="u3S-9u-GMZ" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" id="4TN-aJ-vQh"/>
188 198 <constraint firstAttribute="trailing" secondItem="u3S-9u-GMZ" secondAttribute="trailing" id="8KH-Mn-IUf"/>
189 199 <constraint firstItem="DuE-Dh-nEe" firstAttribute="top" secondItem="3Xj-IB-96h" secondAttribute="bottom" constant="8" id="9h2-XH-Dd7"/>
  200 + <constraint firstItem="kdD-rj-BtX" firstAttribute="top" secondItem="lnt-4H-Ao8" secondAttribute="bottom" constant="8" id="BCi-jo-C0A"/>
190 201 <constraint firstAttribute="trailing" secondItem="LPY-Zl-cOp" secondAttribute="trailing" constant="10" id="CX3-BL-hNh"/>
191 202 <constraint firstItem="vRa-cr-YTe" firstAttribute="leading" secondItem="J2A-tf-wH0" secondAttribute="trailing" constant="10" id="Cax-pu-Kp7"/>
192 203 <constraint firstItem="3Xj-IB-96h" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" constant="8" id="E8R-qO-PtJ"/>
  204 + <constraint firstItem="kdD-rj-BtX" firstAttribute="leading" secondItem="BoP-c1-c0q" secondAttribute="trailing" constant="8" id="EE0-bp-sbO"/>
193 205 <constraint firstItem="b6V-Bi-4oz" firstAttribute="centerX" secondItem="vRa-cr-YTe" secondAttribute="centerX" id="EEt-Ct-vxb"/>
194 206 <constraint firstItem="u3S-9u-GMZ" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" placeholder="YES" id="GbN-me-UEd"/>
195 207 <constraint firstItem="b6V-Bi-4oz" firstAttribute="centerY" secondItem="vRa-cr-YTe" secondAttribute="centerY" id="HXS-oH-EPB"/>
... ... @@ -216,6 +228,7 @@
216 228 <constraint firstItem="3Xj-IB-96h" firstAttribute="top" secondItem="wfu-aB-xXm" secondAttribute="bottom" constant="8" id="psY-0r-fPJ"/>
217 229 <constraint firstItem="TUf-Tp-93t" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" constant="20" id="sC4-Kr-3bN"/>
218 230 <constraint firstItem="at8-co-gC4" firstAttribute="centerY" secondItem="Low-8n-pqa" secondAttribute="centerY" id="tav-ge-tCT"/>
  231 + <constraint firstItem="VAz-hq-dvR" firstAttribute="top" secondItem="kdD-rj-BtX" secondAttribute="bottom" constant="8" id="ujL-1z-cUf"/>
219 232 <constraint firstItem="lnt-4H-Ao8" firstAttribute="top" secondItem="DuE-Dh-nEe" secondAttribute="bottom" constant="20" id="w4w-Z4-Jzk"/>
220 233 <constraint firstItem="wfu-aB-xXm" firstAttribute="leading" secondItem="TUf-Tp-93t" secondAttribute="trailing" constant="10" id="x51-DA-4Le"/>
221 234 <constraint firstItem="VAz-hq-dvR" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="xE7-ro-k8m"/>
LifeLog/LifeLog/Info.plist
... ... @@ -23,7 +23,7 @@
23 23 <dict/>
24 24 </array>
25 25 <key>CFBundleVersion</key>
26   - <string>2</string>
  26 + <string>4</string>
27 27 <key>LSApplicationQueriesSchemes</key>
28 28 <array>
29 29 <string>line</string>
LifeLog/LifeLog/NoticeInfor.h
  1 +//
  2 +// NoticeInfor.h
  3 +// LifeLog
  4 +//
  5 +// Created by Nguyen Van Phong on 10/23/17.
  6 +// Copyright ยฉ 2017 PhongNV. All rights reserved.
  7 +//
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +
  11 +@interface NoticeInfor : NSObject
  12 +@property (nonatomic, strong) NSString *notice_id;
  13 +@property (nonatomic, strong) NSString *notice_content;
  14 +-(id) initWithData : (NSDictionary *) dict;
  15 +@end
LifeLog/LifeLog/NoticeInfor.m
  1 +//
  2 +// NoticeInfor.m
  3 +// LifeLog
  4 +//
  5 +// Created by Nguyen Van Phong on 10/23/17.
  6 +// Copyright ยฉ 2017 PhongNV. All rights reserved.
  7 +//
  8 +
  9 +#import "NoticeInfor.h"
  10 +
  11 +@implementation NoticeInfor
  12 +-(id) initWithData : (NSDictionary *) dict {
  13 + if([dict objectForKey:@"id"] != nil) {
  14 + self.notice_id = dict[@"id"];
  15 + }
  16 + if([dict objectForKey:@"notice_content"] != nil) {
  17 + self.notice_content = dict[@"notice_content"];
  18 + }
  19 + return self;
  20 +}
  21 +@end
LifeLog/LifeLog/ServerAPI.h
... ... @@ -28,6 +28,7 @@
28 28 #pragma mark - Home Screen Function
29 29 - (void)requestTopWithMode:(int)mode andDate:(NSString *)date CompletionHandler:(void (^)(TopObject *, NSError *)) completion;
30 30 - (void)requestCreateLog:(int)mode withStep:(int)numStep startDate:(NSString *)startDate endDate:(NSString *)endDate CompletionHandler:(void (^)(NSError *))completion;
  31 +- (void)requestHomeWithMode:(int)mode andDate:(NSString *)date CompletionHandler:(void (^)(HomeObject *, NSError *)) completion;
31 32  
32 33 #pragma mark - History Screen Function
33 34 - (void) requestHistory:(NSString *)token startDate:(NSDate *)startDate endDate:(NSDate *)endDate CompletionHandler:(void (^)(NSArray *, NSError *)) completion;
LifeLog/LifeLog/ServerAPI.m
... ... @@ -366,6 +366,63 @@
366 366 }];
367 367 }
368 368  
  369 +- (void)requestHomeWithMode:(int)mode andDate:(NSString *)date CompletionHandler:(void (^)(HomeObject *, NSError *)) completion
  370 +{
  371 + NSString * token = [[NSUserDefaults standardUserDefaults] stringForKey:kToken];
  372 + NSString *url = [kServerAddress stringByAppendingFormat:@"api/home/%d/%@", mode, date];
  373 + [self _request:url method:@"GET" token:token paras:nil completion:^(NSData *data, NSError *error) {
  374 +
  375 + if (completion == NULL) {
  376 + return ;
  377 + }
  378 +
  379 + if (error == nil)
  380 + {
  381 + NSDictionary *dataResult = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingAllowFragments error: &error];
  382 + int status = [dataResult[@"status"] intValue];
  383 + if (status == 1) { // status = 1 success
  384 + if(dataResult[@"result"] != nil) {
  385 + NSDictionary * dictResult = dataResult[@"result"];
  386 + HomeObject *homeObject = [[HomeObject alloc] init];
  387 + TargetInfor *targetInfor = [[TargetInfor alloc] initWithData:dictResult[@"targetInf"]];
  388 + homeObject.targetInfor = targetInfor;
  389 + NSMutableArray *arrayNotice = [[NSMutableArray alloc] init];
  390 + NSArray *array = dictResult[@"listNotice"];
  391 + for(NSDictionary *dict in array) {
  392 + NoticeInfor *object = [[NoticeInfor alloc] initWithData:dict];
  393 + [arrayNotice addObject:object];
  394 + }
  395 + homeObject.listNotice = [[NSMutableArray alloc] initWithArray:arrayNotice];
  396 + completion(homeObject, nil);
  397 + }
  398 + else {
  399 + NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":@"Unknown Error"}];
  400 + completion(nil, errorObject);
  401 + }
  402 + }
  403 + else {
  404 + NSString *message = dataResult[@"message"];
  405 + if (message == nil) {
  406 + message = @"Unknown error";
  407 + }
  408 +
  409 + if ([message isEqualToString:@"Token is invalid"]) {
  410 + [self performSelectorOnMainThread:@selector(checkToken) withObject:nil waitUntilDone:YES];
  411 + [self requestHomeWithMode:mode andDate:date CompletionHandler:completion];
  412 + }
  413 + else {
  414 + NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}];
  415 + completion(nil, errorObject);
  416 + }
  417 + }
  418 + }
  419 + else
  420 + {
  421 + completion(nil, error);
  422 + }
  423 + }];
  424 +}
  425 +
369 426 - (void)requestCreateLog:(int)mode withStep:(int)numStep startDate:(NSString *)startDate endDate:(NSString *)endDate CompletionHandler:(void (^)(NSError *))completion {
370 427 NSString * token = [[NSUserDefaults standardUserDefaults] stringForKey:kToken];
371 428 NSString *url = [kServerAddress stringByAppendingFormat:@"api/createLog"];