Commit cedcb87d8a4e170d8cb99ebeea59e5b739d6a220

Authored by phong
1 parent 2bab9a9ab1

update MAP screen and update api get new token, api create log step

Showing 6 changed files with 433 additions and 29 deletions Side-by-side Diff

LifeLog/LifeLog/HomeViewController.m
... ... @@ -235,20 +235,23 @@
235 235 // NSLog(@"%@", activityExtra.activity.startDate);
236 236 [weakSelf.pedometer queryPedometerDataFromDate:activityExtra.activity.startDate toDate:activityExtra.endDate withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) {
237 237 NSInteger numberStep = [pedometerData.numberOfSteps integerValue];
238   -
  238 + int mode = 1;
239 239 if (activityExtra.activity.cycling) {
240 240 // self.bike
241 241 weakSelf.bike += numberStep;
242 242 //NSLog(@"Step cycling");
  243 + mode = 3;
243 244 }
244 245 else if (activityExtra.activity.walking) {
245 246 // self.walking
246 247 weakSelf.walking += numberStep;
247 248 //NSLog(@"Step walking");
  249 + mode = 1;
248 250 }
249 251 else if (activityExtra.activity.running) {
250 252 weakSelf.running += numberStep;
251 253 //NSLog(@"Step running");
  254 + mode = 2;
252 255 }
253 256 else {
254 257 // unknown
... ... @@ -256,6 +259,19 @@
256 259 }
257 260 // NSLog(@"Number of step--> %ld", numberStep);
258 261 weakSelf.countComplete += 1;
  262 +
  263 + // save step to server
  264 + if (numberStep > 0) {
  265 + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
  266 + [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  267 + NSString *dateBegin = [dateFormatter stringFromDate:activityExtra.activity.startDate];
  268 + NSString *dateEnd = [dateFormatter stringFromDate:activityExtra.endDate];
  269 + [[ServerAPI server] requestCreateLog:mode withStep:(int)numberStep startDate:dateBegin endDate:dateEnd CompletionHandler:^(NSError *error) {
  270 + if (error) {
  271 + NSLog(@"Error: %@", error);
  272 + }
  273 + }];
  274 + }
259 275 dispatch_async(dispatch_get_main_queue(), ^{
260 276 [weakSelf updateStepUI];
261 277 });
LifeLog/LifeLog/Info.plist
... ... @@ -60,6 +60,10 @@
60 60 </array>
61 61 <key>UIViewControllerBasedStatusBarAppearance</key>
62 62 <false/>
  63 + <key>NSLocationWhenInUseUsageDescription</key>
  64 + <string>This application requires location services to work</string>
  65 + <key>NSLocationAlwaysUsageDescription</key>
  66 + <string>This application requires location services to work</string>
63 67 </dict>
64 68 </plist>
LifeLog/LifeLog/MapViewController.m
... ... @@ -7,9 +7,33 @@
7 7 //
8 8  
9 9 #import "MapViewController.h"
  10 +#import <MapKit/MapKit.h>
  11 +#import<CoreLocation/CoreLocation.h>
  12 +#import <CoreMotion/CoreMotion.h>
  13 +#import "NSDate+helper.h"
  14 +#import "Utilities.h"
10 15  
11   -@interface MapViewController ()
  16 +@interface MapViewController ()<CLLocationManagerDelegate, MKMapViewDelegate>
  17 +{
  18 + CLGeocoder *geocoder;
  19 + CLPlacemark *placemark;
  20 + CLLocation *previousLocation;
  21 +}
  22 +@property (weak, nonatomic) IBOutlet MKMapView *mapView;
  23 +@property (weak, nonatomic) IBOutlet UILabel *lblTime;
  24 +@property (weak, nonatomic) IBOutlet UISlider *slider;
12 25  
  26 +@property (nonatomic, weak) IBOutlet UILabel *lblValueStep;
  27 +@property (nonatomic, weak) IBOutlet UILabel *lblUnitStep;
  28 +
  29 +@property (strong, nonatomic) CLLocationManager *locationManager;
  30 +
  31 +@property (nonatomic, strong) CMPedometer *pedometer;
  32 +@property (nonatomic, strong) CMMotionActivityManager *motionActivityManager;
  33 +@property (nonatomic, strong) NSOperationQueue *operationQueue;
  34 +@property (nonatomic, strong) NSTimer *timer;
  35 +@property (nonatomic) int countTime;
  36 +@property (nonatomic, assign) BOOL isRequesting;
13 37 @end
14 38  
15 39 @implementation MapViewController
16 40  
... ... @@ -18,11 +42,153 @@
18 42 [super viewDidLoad];
19 43 // Do any additional setup after loading the view from its nib.
20 44 self.title = NSLocalizedString(@"lifelog.tapbar.map", nil);
  45 + [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.topLayoutGuide attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.mapView attribute:NSLayoutAttributeTop multiplier:1 constant:0]];
  46 + geocoder = [[CLGeocoder alloc] init];
  47 + [self setupLocation];
  48 + [self setupMapView];
  49 + previousLocation = nil;
  50 +
  51 + if ([CMPedometer isStepCountingAvailable]) {
  52 + _pedometer = [[CMPedometer alloc] init];
  53 + }
  54 + if ([CMMotionActivityManager isActivityAvailable]) {
  55 + _motionActivityManager = [[CMMotionActivityManager alloc] init];
  56 + }
  57 + self.isRequesting = NO;
  58 + _countTime = 0;
  59 + self.lblUnitStep.text = NSLocalizedString(@"lifelog.home.unit.step", nil);
21 60 }
22 61  
23 62 - (void)didReceiveMemoryWarning {
24 63 [super didReceiveMemoryWarning];
25 64 // Dispose of any resources that can be recreated.
  65 +}
  66 +
  67 +- (void)viewWillAppear:(BOOL)animated {
  68 + [super viewWillAppear:animated];
  69 + _timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(countStep) userInfo:nil repeats:YES];
  70 + [_timer fire];
  71 +}
  72 +
  73 +- (void)viewWillDisappear:(BOOL)animated {
  74 + [super viewWillDisappear:animated];
  75 + [_timer invalidate];
  76 +}
  77 +
  78 +#pragma mark - CLLocationManagerDelegate
  79 +-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
  80 +
  81 + CLLocation *newLocation = [locations lastObject];
  82 + if (previousLocation == nil) {
  83 + [self addAnnotationsOnMap:newLocation];
  84 + }
  85 + else {
  86 + CLLocationCoordinate2D area[2];
  87 + area[0] = previousLocation.coordinate;
  88 + area[1] = newLocation.coordinate;
  89 + MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:area count:2];
  90 + [_mapView addOverlay:polyLine];
  91 + }
  92 +
  93 + previousLocation = newLocation;
  94 +}
  95 +
  96 +- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
  97 +{
  98 + NSLog(@"Cannot find the location.");
  99 +}
  100 +
  101 +#pragma mark - MKMapViewDelegate
  102 +- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOverlay>)overlay
  103 +{
  104 + if ([overlay isKindOfClass:[MKPolyline class]]) {
  105 + MKPolylineRenderer *pr = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
  106 + pr.strokeColor = [UIColor redColor];
  107 + pr.lineWidth = 5;
  108 + return pr;
  109 + }
  110 + return nil;
  111 +}
  112 +
  113 +#pragma mark - Functions Private
  114 +
  115 +- (void)addAnnotationsOnMap:(CLLocation *)locationToPoint {
  116 + MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
  117 + annotation.coordinate = locationToPoint.coordinate;
  118 + [geocoder reverseGeocodeLocation:locationToPoint completionHandler:^(NSArray *placemarks, NSError *error) {
  119 + if (error == nil && [placemarks count] >0) {
  120 + placemark = [placemarks firstObject];
  121 + NSDictionary *addressDict = placemark.addressDictionary;
  122 + annotation.title = [NSString stringWithFormat:@"%@", addressDict[@"Name"]];
  123 + [_mapView addAnnotation:annotation];
  124 + }
  125 + }];
  126 +}
  127 +
  128 +- (void)setupLocation {
  129 + _locationManager = [[CLLocationManager alloc] init];
  130 + _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
  131 + _locationManager.delegate = self;
  132 + CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
  133 + if (status == kCLAuthorizationStatusNotDetermined || status == kCLAuthorizationStatusDenied || status == kCLAuthorizationStatusAuthorizedWhenInUse) {
  134 + [_locationManager requestWhenInUseAuthorization];
  135 + [_locationManager requestAlwaysAuthorization];
  136 + }
  137 + [_locationManager startUpdatingLocation];
  138 + [_locationManager startUpdatingHeading];
  139 +}
  140 +
  141 +- (void)setupMapView {
  142 + _mapView.delegate = self;
  143 + _mapView.showsUserLocation = YES;
  144 + _mapView.mapType = MKMapTypeStandard;
  145 + _mapView.userTrackingMode = MKUserTrackingModeFollowWithHeading;
  146 +}
  147 +
  148 +#pragma mark - Functions Private
  149 +- (void)countStep
  150 +{
  151 + _countTime++;
  152 + _lblTime.text = [self convertTime:_countTime];
  153 + _slider.value = _countTime;
  154 + if (self.isRequesting == YES) {
  155 + return;
  156 + }
  157 + if ([CMMotionActivityManager isActivityAvailable]) {
  158 + self.isRequesting = YES;
  159 + NSDate *endDate = [NSDate date];
  160 + NSDate *startDate = [endDate beginningAtMidnightOfDay];
  161 + MapViewController __weak *weakSelf = self;
  162 + dispatch_queue_t myQueue = dispatch_queue_create("mobileworld.jp.lifelog", NULL);
  163 + dispatch_async(myQueue, ^{
  164 + if (weakSelf == nil) {
  165 + return ;
  166 + }
  167 + [weakSelf.pedometer queryPedometerDataFromDate:startDate toDate:endDate withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) {
  168 + NSInteger numberStep = [pedometerData.numberOfSteps integerValue];
  169 + dispatch_async(dispatch_get_main_queue(), ^{
  170 + [weakSelf updateStepUI:numberStep];
  171 + });
  172 + }];
  173 + });
  174 + }
  175 +}
  176 +
  177 +- (NSString *)convertTime:(int)time
  178 +{
  179 + NSString *result = @"";
  180 + int hour = time/3600;
  181 + int minute = time/60;
  182 + int second = time % 60;
  183 + result = [NSString stringWithFormat:@"%02d:%02d:%02d", hour, minute, second];
  184 + return result;
  185 +}
  186 +
  187 +- (void)updateStepUI:(NSInteger)numberStep
  188 +{
  189 + // NSLog(@"Number of step: %ld", numberStep);
  190 + self.isRequesting = NO;
  191 + self.lblValueStep.text = [Utilities addCommaFromNumber:numberStep];
26 192 }
27 193  
28 194 @end
LifeLog/LifeLog/MapViewController.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="12121" systemVersion="16G29" 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   - <deployment identifier="iOS"/>
8 7 <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
9 8 <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
10 9 </dependencies>
11 10 <objects>
12 11 <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="MapViewController">
13 12 <connections>
  13 + <outlet property="lblTime" destination="EMF-vR-v3k" id="nRs-ga-YjW"/>
  14 + <outlet property="lblUnitStep" destination="bSt-HN-qcq" id="opK-5F-PG8"/>
  15 + <outlet property="lblValueStep" destination="qLg-XF-Dyf" id="lvl-yi-U7d"/>
  16 + <outlet property="mapView" destination="GCl-mf-CD8" id="SpU-ML-EIf"/>
  17 + <outlet property="slider" destination="79Q-XB-cW2" id="NXm-rp-Ycy"/>
14 18 <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
15 19 </connections>
16 20 </placeholder>
... ... @@ -18,7 +22,89 @@
18 22 <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
19 23 <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
20 24 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
21   - <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
  25 + <subviews>
  26 + <mapView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="GCl-mf-CD8">
  27 + <rect key="frame" x="0.0" y="0.0" width="375" height="579"/>
  28 + <connections>
  29 + <outlet property="delegate" destination="-1" id="fjQ-MR-pO8"/>
  30 + </connections>
  31 + </mapView>
  32 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qLg-XF-Dyf" userLabel="valueStep">
  33 + <rect key="frame" x="20" y="531" width="275" height="40"/>
  34 + <constraints>
  35 + <constraint firstAttribute="height" constant="40" id="uDh-v6-rG3"/>
  36 + </constraints>
  37 + <fontDescription key="fontDescription" type="system" pointSize="45"/>
  38 + <color key="textColor" red="0.047200520830000002" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
  39 + <nil key="highlightedColor"/>
  40 + </label>
  41 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="step" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bSt-HN-qcq" userLabel="unitStep">
  42 + <rect key="frame" x="305" y="541" width="50" height="30"/>
  43 + <constraints>
  44 + <constraint firstAttribute="height" constant="30" id="CNj-tm-yOG"/>
  45 + <constraint firstAttribute="width" constant="50" id="fac-mE-Hfh"/>
  46 + </constraints>
  47 + <fontDescription key="fontDescription" type="system" pointSize="25"/>
  48 + <color key="textColor" red="0.047200520830000002" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
  49 + <nil key="highlightedColor"/>
  50 + </label>
  51 + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ayh-Y4-2QM" userLabel="ViewOther">
  52 + <rect key="frame" x="0.0" y="579" width="375" height="44"/>
  53 + <subviews>
  54 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="TIME LINE" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ibI-Db-Rc6">
  55 + <rect key="frame" x="8" y="0.0" width="90" height="44"/>
  56 + <constraints>
  57 + <constraint firstAttribute="width" constant="90" id="Lof-Td-i7Y"/>
  58 + </constraints>
  59 + <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
  60 + <nil key="textColor"/>
  61 + <nil key="highlightedColor"/>
  62 + </label>
  63 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="12:05:01" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EMF-vR-v3k">
  64 + <rect key="frame" x="106" y="0.0" width="80" height="44"/>
  65 + <constraints>
  66 + <constraint firstAttribute="width" constant="80" id="57B-fF-bdc"/>
  67 + </constraints>
  68 + <fontDescription key="fontDescription" type="system" pointSize="17"/>
  69 + <nil key="textColor"/>
  70 + <nil key="highlightedColor"/>
  71 + </label>
  72 + <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" minValue="0.0" maxValue="86400" translatesAutoresizingMaskIntoConstraints="NO" id="79Q-XB-cW2">
  73 + <rect key="frame" x="192" y="7" width="177" height="31"/>
  74 + </slider>
  75 + </subviews>
  76 + <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
  77 + <constraints>
  78 + <constraint firstItem="79Q-XB-cW2" firstAttribute="leading" secondItem="EMF-vR-v3k" secondAttribute="trailing" constant="8" id="0a0-t9-1tR"/>
  79 + <constraint firstItem="EMF-vR-v3k" firstAttribute="leading" secondItem="ibI-Db-Rc6" secondAttribute="trailing" constant="8" id="1a3-pA-ato"/>
  80 + <constraint firstAttribute="bottom" secondItem="79Q-XB-cW2" secondAttribute="bottom" constant="7" id="3l2-mK-se7"/>
  81 + <constraint firstItem="79Q-XB-cW2" firstAttribute="top" secondItem="ayh-Y4-2QM" secondAttribute="top" constant="7" id="6uV-xl-zpg"/>
  82 + <constraint firstAttribute="bottom" secondItem="EMF-vR-v3k" secondAttribute="bottom" id="7AD-qZ-VE4"/>
  83 + <constraint firstItem="EMF-vR-v3k" firstAttribute="top" secondItem="ayh-Y4-2QM" secondAttribute="top" id="B8d-wr-H0p"/>
  84 + <constraint firstAttribute="height" constant="44" id="G4K-Ic-5xS"/>
  85 + <constraint firstItem="ibI-Db-Rc6" firstAttribute="leading" secondItem="ayh-Y4-2QM" secondAttribute="leading" constant="8" id="NC8-xC-nBM"/>
  86 + <constraint firstAttribute="bottom" secondItem="ibI-Db-Rc6" secondAttribute="bottom" id="TKv-6Y-DHi"/>
  87 + <constraint firstAttribute="trailing" secondItem="79Q-XB-cW2" secondAttribute="trailing" constant="8" id="bzZ-US-1Hm"/>
  88 + <constraint firstItem="ibI-Db-Rc6" firstAttribute="top" secondItem="ayh-Y4-2QM" secondAttribute="top" id="lyI-MR-Y5S"/>
  89 + </constraints>
  90 + </view>
  91 + </subviews>
  92 + <color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
  93 + <constraints>
  94 + <constraint firstAttribute="bottom" secondItem="GCl-mf-CD8" secondAttribute="bottom" constant="88" id="8R5-IL-ZOZ"/>
  95 + <constraint firstItem="ayh-Y4-2QM" firstAttribute="top" secondItem="qLg-XF-Dyf" secondAttribute="bottom" constant="8" id="CCW-El-IlM"/>
  96 + <constraint firstAttribute="trailing" secondItem="bSt-HN-qcq" secondAttribute="trailing" constant="20" id="GmG-Qy-kpO"/>
  97 + <constraint firstAttribute="trailing" secondItem="ayh-Y4-2QM" secondAttribute="trailing" id="Mwo-O6-jk0"/>
  98 + <constraint firstAttribute="trailing" secondItem="GCl-mf-CD8" secondAttribute="trailing" id="PwQ-mm-AeM"/>
  99 + <constraint firstItem="GCl-mf-CD8" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" placeholder="YES" id="TRc-4D-tbT"/>
  100 + <constraint firstItem="ayh-Y4-2QM" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" id="Zc1-Ki-ENV"/>
  101 + <constraint firstItem="GCl-mf-CD8" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" id="aM7-E7-p41"/>
  102 + <constraint firstItem="bSt-HN-qcq" firstAttribute="leading" secondItem="qLg-XF-Dyf" secondAttribute="trailing" constant="10" id="hlg-b5-9sd"/>
  103 + <constraint firstItem="qLg-XF-Dyf" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" constant="20" id="nAo-mi-AuL"/>
  104 + <constraint firstItem="ayh-Y4-2QM" firstAttribute="top" secondItem="GCl-mf-CD8" secondAttribute="bottom" id="qaI-c1-69r"/>
  105 + <constraint firstItem="qLg-XF-Dyf" firstAttribute="centerY" secondItem="bSt-HN-qcq" secondAttribute="centerY" constant="-5" id="tA8-lE-abe"/>
  106 + </constraints>
  107 + <point key="canvasLocation" x="32.5" y="70.5"/>
22 108 </view>
23 109 </objects>
24 110 </document>
LifeLog/LifeLog/ServerAPI.h
... ... @@ -27,6 +27,7 @@
27 27  
28 28 #pragma mark - Home Screen Function
29 29 - (void)requestTopWithMode:(int)mode andDate:(NSString *)date CompletionHandler:(void (^)(TopObject *, NSError *)) completion;
  30 +- (void)requestCreateLog:(int)mode withStep:(int)numStep startDate:(NSString *)startDate endDate:(NSString *)endDate CompletionHandler:(void (^)(NSError *))completion;
30 31  
31 32 #pragma mark - History Screen Function
32 33 - (void) requestHistory:(NSString *)token atDate:(NSDate *)date withType:(int)type andMode:(int) mode CompletionHandler:(void (^)(HistoryObject *, NSError *)) completion;
... ... @@ -40,5 +41,7 @@
40 41 */
41 42 - (void) requestTweetsList:(NSString *)token groupID: (int) groupID withPage:(int)page CompletionHandler:(void (^)(NSArray *, NSError *)) completion;
42 43 - (void) searchGroup:(NSString *)token withKey:(NSString *)key andPage:(int)page CompletionHandler:(void (^)(NSArray *, NSError *)) completion;
  44 +#pragma mark - Common API
  45 +- (void)refreshToken: (NSString *)userID CompletionHandler:(void (^)(NSString *, NSError *))completion;
43 46 @end
LifeLog/LifeLog/ServerAPI.m
... ... @@ -262,7 +262,7 @@
262 262 {
263 263 completion(nil, error);
264 264 }
265   - }];
  265 + }];
266 266 }
267 267  
268 268 -(NSString *) convertIntToString : (int) type {
... ... @@ -289,7 +289,7 @@
289 289 - (void)requestTopWithMode:(int)mode andDate:(NSString *)date CompletionHandler:(void (^)(TopObject *, NSError *)) completion
290 290 {
291 291 NSString * token = [[NSUserDefaults standardUserDefaults] stringForKey:kToken];
292   - NSString *url = [kServerAddress stringByAppendingFormat:@"/api/top/%d/%@", mode, date];
  292 + NSString *url = [kServerAddress stringByAppendingFormat:@"api/top/%d/%@", mode, date];
293 293 [self _request:url method:@"GET" token:token paras:nil completion:^(NSData *data, NSError *error) {
294 294  
295 295 if (completion == NULL) {
... ... @@ -347,9 +347,15 @@
347 347 if (message == nil) {
348 348 message = @"Unknown error";
349 349 }
350   - NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}];
351   - completion(nil, errorObject);
352   - [self checkToken:message];
  350 +
  351 + if ([message isEqualToString:@"Token is invalid"]) {
  352 + [self performSelectorOnMainThread:@selector(checkToken) withObject:nil waitUntilDone:YES];
  353 + [self requestTopWithMode:mode andDate:date CompletionHandler:completion];
  354 + }
  355 + else {
  356 + NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}];
  357 + completion(nil, errorObject);
  358 + }
353 359 }
354 360 }
355 361 else
... ... @@ -359,6 +365,46 @@
359 365 }];
360 366 }
361 367  
  368 +- (void)requestCreateLog:(int)mode withStep:(int)numStep startDate:(NSString *)startDate endDate:(NSString *)endDate CompletionHandler:(void (^)(NSError *))completion {
  369 + NSString * token = [[NSUserDefaults standardUserDefaults] stringForKey:kToken];
  370 + NSString *url = [kServerAddress stringByAppendingFormat:@"api/createLog"];
  371 + NSDictionary *dict = @{@"mode": [NSNumber numberWithInt:mode], @"numStep": [NSNumber numberWithInt:numStep], @"startTime": startDate, @"endTime": endDate};
  372 + [self _request:url method:@"POST" token:token paras:dict completion:^(NSData *data, NSError *error) {
  373 +
  374 + if (completion == NULL) {
  375 + return ;
  376 + }
  377 +
  378 + if (error == nil)
  379 + {
  380 + NSDictionary *dataResult = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingAllowFragments error: &error];
  381 + int status = [dataResult[@"status"] intValue];
  382 + if (status == 1) { // status = 1 success
  383 + completion(nil);
  384 + }
  385 + else {
  386 + NSString *message = dataResult[@"message"];
  387 + if (message == nil) {
  388 + message = @"Unknown error";
  389 + }
  390 +
  391 + if ([message isEqualToString:@"Token is invalid"]) {
  392 + [self performSelectorOnMainThread:@selector(checkToken) withObject:nil waitUntilDone:YES];
  393 + [self requestCreateLog:mode withStep:numStep startDate:startDate endDate:endDate CompletionHandler:completion];
  394 + }
  395 + else {
  396 + NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}];
  397 + completion(errorObject);
  398 + }
  399 + }
  400 + }
  401 + else
  402 + {
  403 + completion(error);
  404 + }
  405 + }];
  406 +}
  407 +
362 408 #pragma mark - History Screen Function
363 409 - (void) requestHistory:(NSString *)token atDate:(NSDate *)date withType:(int)type andMode:(int) mode CompletionHandler:(void (^)(HistoryObject *, NSError *)) completion {
364 410 NSString *url = [kServerAddress stringByAppendingFormat:@"/api/history/%@/%d", [self convertIntToString:type], mode];
... ... @@ -383,9 +429,16 @@
383 429 if (message == nil) {
384 430 message = @"Unknown error";
385 431 }
386   - NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}];
387   - completion(nil, errorObject);
388   - [self checkToken:message];
  432 +
  433 + if ([message isEqualToString:@"Token is invalid"]) {
  434 + [self performSelectorOnMainThread:@selector(checkToken) withObject:nil waitUntilDone:YES];
  435 + NSString *tokenNew = [[NSUserDefaults standardUserDefaults] objectForKey:kToken];
  436 + [self requestHistory:tokenNew atDate:date withType:type andMode:mode CompletionHandler:completion];
  437 + }
  438 + else {
  439 + NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}];
  440 + completion(nil, errorObject);
  441 + }
389 442 }
390 443 }
391 444 else
... ... @@ -418,9 +471,16 @@
418 471 if (message == nil) {
419 472 message = @"Unknown error";
420 473 }
421   - NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}];
422   - completion(nil, errorObject);
423   - [self checkToken:message];
  474 +
  475 + if ([message isEqualToString:@"Token is invalid"]) {
  476 + [self performSelectorOnMainThread:@selector(checkToken) withObject:nil waitUntilDone:YES];
  477 + NSString *tokenNew = [[NSUserDefaults standardUserDefaults] objectForKey:kToken];
  478 + [self requestHistoryGraph:tokenNew withType:type andMode:mode CompletionHandler:completion];
  479 + }
  480 + else {
  481 + NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}];
  482 + completion(nil, errorObject);
  483 + }
424 484 }
425 485 }
426 486 else
... ... @@ -464,9 +524,16 @@
464 524 if (message == nil) {
465 525 message = @"Unknown error";
466 526 }
467   - NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}];
468   - completion(nil, errorObject);
469   - [self checkToken:message];
  527 +
  528 + if ([message isEqualToString:@"Token is invalid"]) {
  529 + [self performSelectorOnMainThread:@selector(checkToken) withObject:nil waitUntilDone:YES];
  530 + NSString *tokenNew = [[NSUserDefaults standardUserDefaults] objectForKey:kToken];
  531 + [self requestHistoryList:tokenNew withType:type andMode:mode AtPage:page CompletionHandler:completion];
  532 + }
  533 + else {
  534 + NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}];
  535 + completion(nil, errorObject);
  536 + }
470 537 }
471 538 }
472 539 else
... ... @@ -511,9 +578,19 @@
511 578 }
512 579 else {
513 580 NSString *message = dataResult[@"message"];
514   - NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}];
515   - completion(nil, errorObject);
516   - [self checkToken:message];
  581 + if (message == nil) {
  582 + message = @"Unknown error";
  583 + }
  584 +
  585 + if ([message isEqualToString:@"Token is invalid"]) {
  586 + [self performSelectorOnMainThread:@selector(checkToken) withObject:nil waitUntilDone:YES];
  587 + NSString *tokenNew = [[NSUserDefaults standardUserDefaults] objectForKey:kToken];
  588 + [self requestTweetsList:tokenNew groupID:groupID withPage:page CompletionHandler:completion];
  589 + }
  590 + else {
  591 + NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}];
  592 + completion(nil, errorObject);
  593 + }
517 594 }
518 595 }
519 596 else
520 597  
521 598  
... ... @@ -569,15 +646,60 @@
569 646 }];
570 647 }
571 648  
  649 +#pragma mark - Common API
  650 +- (void)refreshToken: (NSString *)userID CompletionHandler:(void (^)(NSString *, NSError *))completion {
  651 + [self _request:[kServerAddress stringByAppendingFormat: @"refreshToken"] method:@"POST" token:@"" paras:@{@"userId":userID} completion:^(NSData *data, NSError *error) {
  652 +
  653 + if (completion == NULL) {
  654 + return ;
  655 + }
  656 +
  657 + if (error == nil)
  658 + {
  659 + NSDictionary *dataResult = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingAllowFragments error: &error];
  660 +
  661 + int status = [dataResult[@"status"] intValue];
  662 + if (status == 1) { // status = 1 success
  663 + NSArray *arrayResult = dataResult[@"result"];
  664 + if (arrayResult.count > 0) {
  665 + NSString *token = arrayResult[0];
  666 + completion(token, nil);
  667 + }
  668 + else {
  669 + NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":@"Unknown Error"}];
  670 + completion(nil, errorObject);
  671 + }
  672 +
  673 + }
  674 + else { // status = 0 error
  675 + NSString *message = dataResult[@"message"];
  676 + if (message == nil) {
  677 + message = @"Unknown error";
  678 + }
  679 + NSError *loginFaild = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}];
  680 + completion(nil, loginFaild);
  681 + }
  682 + }
  683 + else
  684 + {
  685 + completion(nil, error);
  686 + }
  687 + }];
  688 +}
  689 +
572 690 #pragma mark - Private Function
573   -- (BOOL) checkToken:(NSString *)message {
574   - if ([message isEqualToString:@"Token is invalid"]) {
575   - [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationToken object:nil];
576   - return YES;
  691 +- (void) checkToken {
  692 + // [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationToken object:nil];
  693 + NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:kUser];
  694 + User *user = (User *)[NSKeyedUnarchiver unarchiveObjectWithData:data];
  695 + if (user != nil) {
  696 + [self refreshToken:user.user_id CompletionHandler:^(NSString *token, NSError *error) {
  697 + if (error == nil) {
  698 + [[NSUserDefaults standardUserDefaults] setObject:token forKey:kToken];
  699 + [[NSUserDefaults standardUserDefaults] synchronize];
  700 + }
  701 + }];
577 702 }
578   - else {
579   - return NO;
580   - }
581 703 }
582 704 - (NSData *) _encodeDictionary: (NSDictionary *) dictionary
583 705 {
... ... @@ -630,6 +752,13 @@
630 752 }];
631 753 [task resume];
632 754 return task;
  755 +}
  756 +
  757 +-(void)waitUntilDone:(void(^)(void))waitBlock {
  758 + //use your statement or call method here
  759 + if(waitBlock){
  760 + waitBlock();
  761 + }
633 762 }
634 763  
635 764 @end