Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '3party/Alohalytics/src/apple/alohalytics_objc.mm')
-rw-r--r--3party/Alohalytics/src/apple/alohalytics_objc.mm115
1 files changed, 96 insertions, 19 deletions
diff --git a/3party/Alohalytics/src/apple/alohalytics_objc.mm b/3party/Alohalytics/src/apple/alohalytics_objc.mm
index 6adc88f34a..b9820d7b7b 100644
--- a/3party/Alohalytics/src/apple/alohalytics_objc.mm
+++ b/3party/Alohalytics/src/apple/alohalytics_objc.mm
@@ -123,11 +123,9 @@ static Location ExtractLocation(CLLocation * l) {
return extracted;
}
-// Returns string representing uint64_t timestamp of given file or directory (modification date in millis from 1970).
-static std::string PathTimestampMillis(NSString * path) {
- NSDictionary * attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
- if (attributes) {
- NSDate * date = [attributes objectForKey:NSFileModificationDate];
+// Internal helper.
+static std::string NSDateToMillisFrom1970(NSDate * date) {
+ if (date) {
return std::to_string(static_cast<uint64_t>([date timeIntervalSince1970] * 1000.));
}
return std::string("0");
@@ -328,6 +326,14 @@ bool IsConnectionActive() {
// Keys for NSUserDefaults.
static NSString * const kInstalledVersionKey = @"AlohalyticsInstalledVersion";
+static NSString * const kFirstLaunchDateKey = @"AlohalyticsFirstLaunchDate";
+static NSString * const kTotalSecondsInTheApp = @"AlohalyticsTotalSecondsInTheApp";
+
+// Used to calculate session length and total time spent in the app.
+// setup should be called to activate counting.
+static NSDate * gSessionStartTime = nil;
+static BOOL gIsFirstSession = NO;
+
@implementation Alohalytics
+ (void)setDebugMode:(BOOL)enable {
@@ -335,10 +341,6 @@ static NSString * const kInstalledVersionKey = @"AlohalyticsInstalledVersion";
}
+ (void)setup:(NSString *)serverUrl withLaunchOptions:(NSDictionary *)options {
- [Alohalytics setup:serverUrl andFirstLaunch:YES withLaunchOptions:options];
-}
-
-+ (void)setup:(NSString *)serverUrl andFirstLaunch:(BOOL)isFirstLaunch withLaunchOptions:(NSDictionary *)options {
const NSBundle * bundle = [NSBundle mainBundle];
NSString * bundleIdentifier = [bundle bundleIdentifier];
NSString * version = [[bundle infoDictionary] objectForKey:@"CFBundleShortVersionString"];
@@ -372,21 +374,26 @@ static NSString * const kInstalledVersionKey = @"AlohalyticsInstalledVersion";
NSUserDefaults * userDataBase = [NSUserDefaults standardUserDefaults];
NSString * installedVersion = [userDataBase objectForKey:kInstalledVersionKey];
BOOL shouldSendUpdatedSystemInformation = NO;
- if (installationId.second && isFirstLaunch && installedVersion == nil) {
- // Documents folder modification time can be interpreted as a "first app launch time" or an approx. "app install time".
- // App bundle modification time can be interpreted as an "app update time".
- instance.LogEvent("$install", {{"CFBundleShortVersionString", [version UTF8String]},
- {"documentsTimestampMillis", PathTimestampMillis([NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject])},
- {"bundleTimestampMillis", PathTimestampMillis([bundle executablePath])}});
+ // Do not generate $install event for old users who did not have Alohalytics installed but already used the app.
+ const BOOL appWasNeverInstalledAndLaunchedBefore = (NSOrderedAscending == [[Alohalytics buildDate] compare:[Alohalytics installDate]]);
+ if (installationId.second && appWasNeverInstalledAndLaunchedBefore && installedVersion == nil) {
+ gIsFirstSession = YES;
+ instance.LogEvent("$install", [Alohalytics bundleInformation:version]);
[userDataBase setValue:version forKey:kInstalledVersionKey];
+ // Also store first launch date for future use.
+ if (nil == [userDataBase objectForKey:kFirstLaunchDateKey]) {
+ [userDataBase setObject:[NSDate date] forKey:kFirstLaunchDateKey];
+ }
[userDataBase synchronize];
shouldSendUpdatedSystemInformation = YES;
} else {
if (installedVersion == nil || ![installedVersion isEqualToString:version]) {
- instance.LogEvent("$update", {{"CFBundleShortVersionString", [version UTF8String]},
- {"documentsTimestampMillis", PathTimestampMillis([NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject])},
- {"bundleTimestampMillis", PathTimestampMillis([bundle executablePath])}});
+ instance.LogEvent("$update", [Alohalytics bundleInformation:version]);
[userDataBase setValue:version forKey:kInstalledVersionKey];
+ // Also store first launch date for future use, if Alohalytics was integrated only in this update.
+ if (nil == [userDataBase objectForKey:kFirstLaunchDateKey]) {
+ [userDataBase setObject:[NSDate date] forKey:kFirstLaunchDateKey];
+ }
[userDataBase synchronize];
shouldSendUpdatedSystemInformation = YES;
}
@@ -409,6 +416,14 @@ static NSString * const kInstalledVersionKey = @"AlohalyticsInstalledVersion";
#endif // TARGET_OS_IPHONE
}
++(alohalytics::TStringMap)bundleInformation:(NSString *)version {
+ return {{"CFBundleShortVersionString", [version UTF8String]},
+ {"installTimestampMillis", NSDateToMillisFrom1970([Alohalytics installDate])},
+ {"updateTimestampMillis", NSDateToMillisFrom1970([Alohalytics updateDate])},
+ {"buildTimestampMillis", NSDateToMillisFrom1970([Alohalytics buildDate])},
+ };
+}
+
+ (void)forceUpload {
Stats::Instance().Upload();
}
@@ -448,11 +463,24 @@ static NSString * const kInstalledVersionKey = @"AlohalyticsInstalledVersion";
#pragma mark App lifecycle notifications used to calculate basic metrics.
#if (TARGET_OS_IPHONE > 0)
+ (void)applicationDidBecomeActive:(NSNotification *)notification {
+ gSessionStartTime = [NSDate date];
Stats::Instance().LogEvent("$applicationDidBecomeActive");
}
+ (void)applicationWillResignActive:(NSNotification *)notification {
- Stats::Instance().LogEvent("$applicationWillResignActive");
+ // Calculate session length.
+ NSInteger seconds = static_cast<NSInteger>(-gSessionStartTime.timeIntervalSinceNow);
+ // nil it to filter time when the app is in the background, but totalSecondsSpentInTheApp is called.
+ gSessionStartTime = nil;
+ Stats & instance = Stats::Instance();
+ instance.LogEvent("$applicationWillResignActive", std::to_string(seconds));
+ NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
+ seconds += [defaults integerForKey:kTotalSecondsInTheApp];
+ [defaults setInteger:seconds forKey:kTotalSecondsInTheApp];
+ [defaults synchronize];
+ if (instance.DebugMode()) {
+ ALOG("Total seconds spent in the app:", seconds);
+ }
}
+ (void)applicationWillEnterForeground:(NSNotificationCenter *)notification {
@@ -479,10 +507,59 @@ static NSString * const kInstalledVersionKey = @"AlohalyticsInstalledVersion";
ALOG("Skipped statistics uploading as connection is not active.");
}
}
+ if (gIsFirstSession) {
+ gIsFirstSession = NO;
+ }
}
+ (void)applicationWillTerminate:(NSNotification *)notification {
Stats::Instance().LogEvent("$applicationWillTerminate");
}
#endif // TARGET_OS_IPHONE
+
+#pragma mark Utility methods
+
++ (BOOL)isFirstSession {
+ return gIsFirstSession;
+}
+
++ (NSDate *)firstLaunchDate {
+ NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
+ NSDate * date = [defaults objectForKey:kFirstLaunchDateKey];
+ if (!date) {
+ // Non-standard situation: this method is called before calling setup. Return current date.
+ date = [NSDate date];
+ [defaults setObject:date forKey:kFirstLaunchDateKey];
+ [defaults synchronize];
+ }
+ return date;
+}
+
++ (NSInteger)totalSecondsSpentInTheApp {
+ NSInteger seconds = [[NSUserDefaults standardUserDefaults] integerForKey:kTotalSecondsInTheApp];
+ // Take into an account currently active session.
+ if (gSessionStartTime) {
+ seconds += static_cast<NSInteger>(-gSessionStartTime.timeIntervalSinceNow);
+ }
+ return seconds;
+}
+
+// Internal helper, returns nil for invalid paths.
++ (NSDate *)fileCreationDate:(NSString *)fullPath {
+ NSDictionary * attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:fullPath error:nil];
+ return attributes ? [attributes objectForKey:NSFileCreationDate] : nil;
+}
+
++ (NSDate *)installDate {
+ return [Alohalytics fileCreationDate:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]];
+}
+
++ (NSDate *)updateDate {
+ return [Alohalytics fileCreationDate:[[NSBundle mainBundle] resourcePath]];
+}
+
++ (NSDate *)buildDate {
+ return [Alohalytics fileCreationDate:[[NSBundle mainBundle] executablePath]];
+}
+
@end