Commit cedcb87d8a4e170d8cb99ebeea59e5b739d6a220
1 parent
2bab9a9ab1
Exists in
master
and in
1 other branch
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 |