diff --git a/ConnectStats.xcodeproj/project.pbxproj b/ConnectStats.xcodeproj/project.pbxproj index 245098a6..a075f68c 100644 --- a/ConnectStats.xcodeproj/project.pbxproj +++ b/ConnectStats.xcodeproj/project.pbxproj @@ -6948,7 +6948,7 @@ repositoryURL = "https://github.com/roznet/rzexternal"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 1.0.2; + minimumVersion = 1.0.3; }; }; 422DCB6D258A2779000DEE4B /* XCRemoteSwiftPackageReference "rzutils" */ = { diff --git a/ConnectStats.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ConnectStats.xcworkspace/xcshareddata/swiftpm/Package.resolved index bc0887f6..e6d17443 100644 --- a/ConnectStats.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ConnectStats.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -96,8 +96,8 @@ "repositoryURL": "https://github.com/roznet/rzexternal", "state": { "branch": null, - "revision": "13707fe878e88d0dec93bb2b654bca8cadd271bf", - "version": "1.0.2" + "revision": "8196de67f9481c7f2a1ba2d5bf7886fe89f63ce4", + "version": "1.0.3" } }, { diff --git a/ConnectStats/src/GCAppDelegate+Swift.m b/ConnectStats/src/GCAppDelegate+Swift.m index 299b6f52..95f4e242 100644 --- a/ConnectStats/src/GCAppDelegate+Swift.m +++ b/ConnectStats/src/GCAppDelegate+Swift.m @@ -100,6 +100,8 @@ -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NS self.web.notificationHandler = nil; completionHandler(UIBackgroundFetchResultNoData); } + // Don't keep startup file + [RZFileOrganizer removeEditableFile:GC_STARTING_FILE]; } diff --git a/ConnectStats/src/GCAppDelegate.m b/ConnectStats/src/GCAppDelegate.m index 2c432103..e84d395b 100644 --- a/ConnectStats/src/GCAppDelegate.m +++ b/ConnectStats/src/GCAppDelegate.m @@ -217,6 +217,11 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [self registerForPushNotifications]; [self remoteStatusCheck]; + /* FOR TESTING + [self application:application didReceiveRemoteNotification:@{} fetchCompletionHandler:^(UIBackgroundFetchResult res){ + RZLog(RZLogInfo, @"completed with %@", @(res)); + }]; + */ return YES; } diff --git a/ConnectStats/src/GCConnectStatsRequest.m b/ConnectStats/src/GCConnectStatsRequest.m index db907c2f..3618da3c 100644 --- a/ConnectStats/src/GCConnectStatsRequest.m +++ b/ConnectStats/src/GCConnectStatsRequest.m @@ -85,6 +85,8 @@ -(void)checkToken{ self.oauthToken = nil; self.userId = 0; self.tokenId = 0; + }else{ + RZLog(RZLogInfo,@"token there"); } } diff --git a/ConnectStats/src/GCDerivedOrganizer.h b/ConnectStats/src/GCDerivedOrganizer.h index c75767c1..64801fd4 100644 --- a/ConnectStats/src/GCDerivedOrganizer.h +++ b/ConnectStats/src/GCDerivedOrganizer.h @@ -42,6 +42,12 @@ typedef void (^GCDerivedDidCompleteBestMatchingSeriesBlock)(NSArray * historicalSeriesByKeys; @property (nonatomic, retain) NSString * useDerivedFilePrefix; +@property (nonatomic, assign) BOOL loadDetailsNeeded; +@property (nonatomic, assign) BOOL loadDetailsCompleted; @end @implementation GCDerivedOrganizer @@ -118,17 +120,6 @@ -(GCDerivedOrganizer*)initWithDb:(FMDatabase*)aDb thread:(dispatch_queue_t)threa [self.web attach:self]; self.useDerivedFilePrefix = filePrefix; - if (thread==nil) { - if( aDb ){ - [self loadFromDb]; - }else{ - self.derivedSeries= [NSMutableDictionary dictionary]; - } - }else{ - dispatch_async(self.worker,^(){ - [self loadFromDb]; - }); - } } return self; } @@ -137,7 +128,9 @@ -(GCDerivedOrganizer*)initWithDb:(FMDatabase*)aDb andThread:(dispatch_queue_t)th return [self initWithDb:aDb thread:thread andFilePrefix:nil]; } -(GCDerivedOrganizer*)initForTestModeWithDb:(FMDatabase*)aDb thread:(dispatch_queue_t)thread andFilePrefix:(NSString*)filePrefix{ - return [self initWithDb:aDb thread:thread andFilePrefix:filePrefix]; + GCDerivedOrganizer * rv = [self initWithDb:aDb thread:thread andFilePrefix:filePrefix]; + [rv ensureDetailsLoaded]; + return rv; } -(void)dealloc{ @@ -155,6 +148,29 @@ -(void)dealloc{ [super dealloc]; } +-(BOOL)ensureDetailsLoaded{ + @synchronized (self) { + self.loadDetailsNeeded = true; + if( self.loadDetailsCompleted ){ + return true; + } + } + if (self.worker==nil) { + if( self.db ){ + [self loadFromDb]; + }else{ + self.derivedSeries= [NSMutableDictionary dictionary]; + } + return true; + }else{ + dispatch_async(self.worker,^(){ + [self loadFromDb]; + }); + return false; + } +} + + #pragma mark - Load Derived Series -(NSString*)derivedFilePrefix{ @@ -165,6 +181,7 @@ -(void)loadFromDb{ self.derivedSeries = [NSMutableDictionary dictionaryWithCapacity:10]; if ( kDerivedEnabled) { + RZPerformance * perf = [RZPerformance start]; FMDatabase * db = [self deriveddb]; if( db ){ FMResultSet * res= [db executeQuery:@"SELECT * FROM gc_derived_series"]; @@ -191,20 +208,21 @@ -(void)loadFromDb{ } if( self.seriesByKeys.count > 0){ - RZLog(RZLogInfo, @"Loaded %d derived series and %@ series by key", (int)self.derivedSeries.count, @(self.seriesByKeys.count)); + RZLog(RZLogInfo, @"Loaded %d derived series and %@ series by key %@", (int)self.derivedSeries.count, @(self.seriesByKeys.count), perf); }else{ RZLog(RZLogInfo, @"Loaded %d derived series", (int)self.derivedSeries.count); } } } + self.loadDetailsCompleted = true; } -(void)loadHistoricalFileSeries{ BOOL convert = ! [[self deriveddb] tableExists:@"gc_converted_historical_second"]; GCStatsDatabase * statsDb = [GCStatsDatabase database:[self deriveddb] table:@"gc_converted_historical_second"]; - RZPerformance * perf = [RZPerformance start]; if( convert ){ + RZPerformance * perf = [RZPerformance start]; for (NSString * key in self.derivedSeries) { GCDerivedDataSerie * serie = self.derivedSeries[key]; if( serie.derivedPeriod == gcDerivedPeriodMonth){ @@ -224,10 +242,8 @@ -(void)loadHistoricalFileSeries{ } } RZLog(RZLogInfo, @"Converted all in %@", perf); - [perf reset]; } self.historicalSeriesByKeys = [NSMutableDictionary dictionaryWithDictionary:[statsDb loadByKeys]]; - RZLog(RZLogInfo, @"Loaded all db in %@", perf); } -(BOOL)debugCheckSerie:(GCStatsDataSerie*)serie{ diff --git a/ConnectStats/src/GCHealthOrganizer.h b/ConnectStats/src/GCHealthOrganizer.h index d95fc204..e1ebd86e 100644 --- a/ConnectStats/src/GCHealthOrganizer.h +++ b/ConnectStats/src/GCHealthOrganizer.h @@ -45,6 +45,14 @@ -(GCHealthOrganizer*)initForTest NS_DESIGNATED_INITIALIZER; +/** + * call this function when details should be loaded + * typically when the ui is ready, it can be called multiple time + * @return true if details already loaded, false if this actually triggered the load + */ +-(BOOL)ensureDetailsLoaded; + + +(void)ensureDbStructure:(FMDatabase*)db; -(BOOL)addHealthMeasure:(GCHealthMeasure*)one; diff --git a/ConnectStats/src/GCHealthOrganizer.m b/ConnectStats/src/GCHealthOrganizer.m index cc03a481..50687415 100644 --- a/ConnectStats/src/GCHealthOrganizer.m +++ b/ConnectStats/src/GCHealthOrganizer.m @@ -33,7 +33,7 @@ @interface GCHealthOrganizer () - +@property (nonatomic,assign) BOOL loadDetailsCompleted; @end @implementation GCHealthOrganizer @@ -63,13 +63,6 @@ -(GCHealthOrganizer*)initWithDb:(FMDatabase*)db andThread:(dispatch_queue_t)thre if (self) { self.db = db; self.worker = thread; - if( thread ){ - dispatch_async(thread,^(){ - [self loadFromDb]; - }); - }else{ - [self loadFromDb]; - } } return self; } @@ -85,6 +78,25 @@ -(GCHealthOrganizer*)initForTest{ } return self; } + +-(BOOL)ensureDetailsLoaded{ + @synchronized (self) { + if( self.loadDetailsCompleted ){ + return true; + } + } + if( self.worker ){ + dispatch_async(self.worker,^(){ + [self loadFromDb]; + }); + return false; + }else{ + [self loadFromDb]; + } + return true; + +} + -(void)updateForNewProfile{ self.db = [GCAppGlobal db]; if (self.worker) { @@ -103,6 +115,7 @@ -(void)clearAllMeasures{ } } -(void)loadFromDb{ + RZPerformance * perf = [RZPerformance start]; if( self.db == nil){ NSMutableDictionary * dict = [NSMutableDictionary dictionary]; [self addDefaultZoneCalculatorTo:dict]; @@ -131,7 +144,6 @@ -(void)loadFromDb{ } } } - RZLog(RZLogInfo,@"Loaded %lu health measures (%@ types)", (unsigned long)n, @(summary.count)); self.measures = [NSArray arrayWithArray:meas]; NSMutableDictionary * zon = [NSMutableDictionary dictionaryWithCapacity:5]; @@ -168,6 +180,10 @@ -(void)loadFromDb{ } self.sleepBlocks = [blocks sortedArrayUsingSelector:@selector(compare:)]; + RZLog(RZLogInfo,@"Loaded %lu health measures (%@ types) %@", (unsigned long)n, @(summary.count), perf); + @synchronized (self) { + self.loadDetailsCompleted = true; + } } -(BOOL)hasHealthData{ diff --git a/ConnectStats/src/GCSplitViewController.m b/ConnectStats/src/GCSplitViewController.m index ca5468e8..f368bd62 100644 --- a/ConnectStats/src/GCSplitViewController.m +++ b/ConnectStats/src/GCSplitViewController.m @@ -93,11 +93,19 @@ - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibB -(void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; - [GCAppGlobal startSuccessful]; + dispatch_async([GCAppGlobal worker], ^(){ [[GCAppGlobal organizer] ensureDetailsLoaded]; }); + dispatch_async([GCAppGlobal worker], ^(){ + [[GCAppGlobal derived] ensureDetailsLoaded]; + }); + dispatch_async([GCAppGlobal worker], ^(){ + [[GCAppGlobal health] ensureDetailsLoaded]; + }); + + [GCAppGlobal startSuccessful]; } - (void)viewDidLoad { diff --git a/ConnectStats/src/GCStatsMultiFieldViewController.m b/ConnectStats/src/GCStatsMultiFieldViewController.m index 5d7cdf49..47f16ddf 100644 --- a/ConnectStats/src/GCStatsMultiFieldViewController.m +++ b/ConnectStats/src/GCStatsMultiFieldViewController.m @@ -145,6 +145,10 @@ -(void)viewWillAppear:(BOOL)animated{ dispatch_async([GCAppGlobal worker], ^(){ [[GCAppGlobal organizer] ensureDetailsLoaded]; }); + + dispatch_async([GCAppGlobal worker], ^(){ + [[GCAppGlobal derived] ensureDetailsLoaded]; + }); } - (void)didReceiveMemoryWarning { diff --git a/ConnectStats/src/GCTabBarController.m b/ConnectStats/src/GCTabBarController.m index 0d6272cf..df76f85a 100644 --- a/ConnectStats/src/GCTabBarController.m +++ b/ConnectStats/src/GCTabBarController.m @@ -193,10 +193,19 @@ -(void)loadView{ -(void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; + dispatch_async([GCAppGlobal worker], ^(){ [[GCAppGlobal organizer] ensureDetailsLoaded]; }); + dispatch_async([GCAppGlobal worker], ^(){ + [[GCAppGlobal derived] ensureDetailsLoaded]; + }); + + dispatch_async([GCAppGlobal worker], ^(){ + [[GCAppGlobal health] ensureDetailsLoaded]; + }); + [GCAppGlobal startSuccessful]; }