From 9b126da91a8bb515ad5184c0420d63ee2077a2ab Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Mon, 20 Nov 2023 11:11:07 -0500 Subject: [PATCH 01/72] first implementation of extended logger --- RadarSDK/RadarLogger.h | 3 ++ RadarSDK/RadarLogger.m | 66 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/RadarSDK/RadarLogger.h b/RadarSDK/RadarLogger.h index 5017b6484..9b16e319b 100644 --- a/RadarSDK/RadarLogger.h +++ b/RadarSDK/RadarLogger.h @@ -16,6 +16,9 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)sharedInstance; - (void)logWithLevel:(RadarLogLevel)level message:(NSString *)message; - (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; +- (void)logWithLevelLocal:(RadarLogLevel)level message:(NSString *)message; +- (void)logWithLevelLocal:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; +- (void)flushLocalLogs; @end NS_ASSUME_NONNULL_END diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index cfb7a1477..16e21febe 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -23,6 +23,17 @@ + (instancetype)sharedInstance { return sharedInstance; } +- (instancetype)init { + self = [super init]; + if (self) { + // Set the default log file path + NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; + NSString *logFileName = @"RadarLogs.txt"; + self.logFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; + } + return self; +} + - (void)logWithLevel:(RadarLogLevel)level message:(NSString *)message { [self logWithLevel:level type:RadarLogTypeNone message:message]; } @@ -42,4 +53,59 @@ - (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSStr }); } +- (void) logWithLevelLocal:(RadarLogLevel)level message:(NSString *)message { + [self logWithLevelLocal:level type:RadarLogTypeNone message:message]; +} + +- (void) logWithLevelLocal:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { + RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; + + if (self.logFilePath) { + NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:self.logFilePath]; + if (!fileHandle) { + [[NSFileManager defaultManager] createFileAtPath:self.logFilePath contents:nil attributes:nil]; + fileHandle = [NSFileHandle fileHandleForWritingAtPath:self.logFilePath]; + } + + if (fileHandle) { + [fileHandle seekToEndOfFile]; + NSData *log = [NSKeyedArchiver archivedDataWithRootObject:radarLog requiringSecureCoding:NO error:nil]; + [fileHandle writeData:[log dataUsingEncoding:NSUTF8StringEncoding]]; + [fileHandle closeFile]; + } + } +} + +- (void)flushlocalLogs { + // read logs from file + NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:self.logFilePath]; + if (fileHandle) { + NSData *data = [fileHandle readDataToEndOfFile]; + [fileHandle closeFile]; + + // delete file + [[NSFileManager defaultManager] removeItemAtPath:self.logFilePath error:nil]; + + // send logs + NSString *logString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + NSArray *localLogs = [RadarLog parseLogs:logString]; + for (RadarLog *localLog in localLogs) { + + dispatch_async(dispatch_get_main_queue(), ^{ + [Radar sendLog:localLog.level type:localLog.type message:localLog.message]; + + RadarLogLevel logLevel = [RadarSettings logLevel]; + if (logLevel >= localLog.level) { + NSString *log = [NSString stringWithFormat:@"%@ | backgroundTimeRemaining = %g", localLog.message, [RadarUtils backgroundTimeRemaining]]; + + os_log(OS_LOG_DEFAULT, "%@", log); + + [[RadarDelegateHolder sharedInstance] didLogMessage:log]; + } + }); + } + } + +} + @end From 86cab0aa916a365086b906df48e9d2c6d087e4f4 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Mon, 20 Nov 2023 14:55:59 -0500 Subject: [PATCH 02/72] new implementation --- RadarSDK/RadarFileSystem.h | 8 +++++++ RadarSDK/RadarFileSystem.m | 24 +++++++++++++++++++ RadarSDK/RadarLogger.h | 2 ++ RadarSDK/RadarLogger.m | 49 ++++++++++++++------------------------ 4 files changed, 52 insertions(+), 31 deletions(-) create mode 100644 RadarSDK/RadarFileSystem.h create mode 100644 RadarSDK/RadarFileSystem.m diff --git a/RadarSDK/RadarFileSystem.h b/RadarSDK/RadarFileSystem.h new file mode 100644 index 000000000..41d2e7579 --- /dev/null +++ b/RadarSDK/RadarFileSystem.h @@ -0,0 +1,8 @@ +#import + +@interface RadarFileSystem : NSObject + +- (NSData *)readFileAtPath:(NSString *)filePath; +- (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath; + +@end \ No newline at end of file diff --git a/RadarSDK/RadarFileSystem.m b/RadarSDK/RadarFileSystem.m new file mode 100644 index 000000000..b3d2f6756 --- /dev/null +++ b/RadarSDK/RadarFileSystem.m @@ -0,0 +1,24 @@ +#import +#import "RadarFileSystem.h" + +@implementation RadarFileSystem + +- (NSData *)readFileAtPath:(NSString *)filePath { + __block NSData *fileData = nil; + + NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; + [fileCoordinator coordinateReadingItemAtURL:[NSURL fileURLWithPath:filePath] options:0 error:nil byAccessor:^(NSURL *newURL) { + fileData = [NSData dataWithContentsOfURL:newURL]; + }]; + + return fileData; +} + +- (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath { + NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; + [fileCoordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:filePath] options:NSFileCoordinatorWritingForReplacing error:nil byAccessor:^(NSURL *newURL) { + [data writeToURL:newURL atomically:YES]; + }]; +} + +@end diff --git a/RadarSDK/RadarLogger.h b/RadarSDK/RadarLogger.h index 9b16e319b..ca968e4ca 100644 --- a/RadarSDK/RadarLogger.h +++ b/RadarSDK/RadarLogger.h @@ -13,6 +13,8 @@ NS_ASSUME_NONNULL_BEGIN @interface RadarLogger : NSObject +@property (assign) NSString *logFilePath; + + (instancetype)sharedInstance; - (void)logWithLevel:(RadarLogLevel)level message:(NSString *)message; - (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index 16e21febe..7f9283267 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -11,6 +11,8 @@ #import "RadarSettings.h" #import "RadarUtils.h" #import +#import "RadarFileSystem.h" +#import "RadarLog.h" @implementation RadarLogger @@ -60,43 +62,28 @@ - (void) logWithLevelLocal:(RadarLogLevel)level message:(NSString *)message { - (void) logWithLevelLocal:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; - if (self.logFilePath) { - NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:self.logFilePath]; - if (!fileHandle) { - [[NSFileManager defaultManager] createFileAtPath:self.logFilePath contents:nil attributes:nil]; - fileHandle = [NSFileHandle fileHandleForWritingAtPath:self.logFilePath]; - } - - if (fileHandle) { - [fileHandle seekToEndOfFile]; - NSData *log = [NSKeyedArchiver archivedDataWithRootObject:radarLog requiringSecureCoding:NO error:nil]; - [fileHandle writeData:[log dataUsingEncoding:NSUTF8StringEncoding]]; - [fileHandle closeFile]; - } - } + NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; + NSString *logFileName = @"RadarLogs.txt"; + NSString *logFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; + NSData *logData = [NSKeyedArchiver archivedDataWithRootObject:radarLog requiringSecureCoding:NO error:nil]; + RadarFileSystem *fileHandler = [[RadarFileSystem alloc] init]; + [fileHandler writeData:logData toFileAtPath:logFilePath]; } -- (void)flushlocalLogs { +- (void)flushLocalLogs { // read logs from file - NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:self.logFilePath]; - if (fileHandle) { - NSData *data = [fileHandle readDataToEndOfFile]; - [fileHandle closeFile]; - - // delete file - [[NSFileManager defaultManager] removeItemAtPath:self.logFilePath error:nil]; - - // send logs - NSString *logString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - NSArray *localLogs = [RadarLog parseLogs:logString]; - for (RadarLog *localLog in localLogs) { - + RadarFileSystem *fileHandler = [[RadarFileSystem alloc] init]; + NSData *fileData = [fileHandler readFileAtPath:self.logFilePath]; + if (fileData) { + // Unarchive the data to get the original object + RadarLog *retrievedLog = [NSKeyedUnarchiver unarchivedObjectOfClass:[RadarLog class] fromData:fileData error:nil]; + if ([retrievedLog isKindOfClass:[RadarLog class]]) { dispatch_async(dispatch_get_main_queue(), ^{ - [Radar sendLog:localLog.level type:localLog.type message:localLog.message]; + [Radar sendLog:retrievedLog.level type:retrievedLog.type message:retrievedLog.message]; RadarLogLevel logLevel = [RadarSettings logLevel]; - if (logLevel >= localLog.level) { - NSString *log = [NSString stringWithFormat:@"%@ | backgroundTimeRemaining = %g", localLog.message, [RadarUtils backgroundTimeRemaining]]; + if (logLevel >= retrievedLog.level) { + NSString *log = [NSString stringWithFormat:@"%@ | backgroundTimeRemaining = %g", retrievedLog.message, [RadarUtils backgroundTimeRemaining]]; os_log(OS_LOG_DEFAULT, "%@", log); From 6708117eba0885cb9b5b5dfc2d3deec61ff2de70 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Mon, 20 Nov 2023 15:12:57 -0500 Subject: [PATCH 03/72] add to target --- RadarSDK.xcodeproj/project.pbxproj | 8 ++++++++ RadarSDK/RadarFileSystem.h | 10 +++++++++- RadarSDK/RadarFileSystem.m | 9 +++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/RadarSDK.xcodeproj/project.pbxproj b/RadarSDK.xcodeproj/project.pbxproj index 1d458c249..22b13c7ae 100644 --- a/RadarSDK.xcodeproj/project.pbxproj +++ b/RadarSDK.xcodeproj/project.pbxproj @@ -159,6 +159,8 @@ DD8E2F7A24018C37002D51AB /* CLLocationManagerMock.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8E2F7924018C37002D51AB /* CLLocationManagerMock.m */; }; DD8E2F7D24018C54002D51AB /* CLVisitMock.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8E2F7C24018C54002D51AB /* CLVisitMock.m */; }; DE1E7644239724FD006F34A1 /* search_geofences.json in Resources */ = {isa = PBXBuildFile; fileRef = DE1E7643239724FD006F34A1 /* search_geofences.json */; }; + E619D29D2B0BF4CE00C88578 /* RadarFileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = E619D29C2B0BF4CE00C88578 /* RadarFileSystem.h */; }; + E619D29F2B0BF50D00C88578 /* RadarFileSystem.m in Sources */ = {isa = PBXBuildFile; fileRef = E619D29E2B0BF50D00C88578 /* RadarFileSystem.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -315,6 +317,8 @@ DDD7BD0325EC3015002473B3 /* RadarRouteMatrix.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RadarRouteMatrix.m; sourceTree = ""; }; DDF1157C2524E18100D575C4 /* RadarTrip.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RadarTrip.m; sourceTree = ""; }; DE1E7643239724FD006F34A1 /* search_geofences.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = search_geofences.json; sourceTree = ""; }; + E619D29C2B0BF4CE00C88578 /* RadarFileSystem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RadarFileSystem.h; sourceTree = ""; }; + E619D29E2B0BF50D00C88578 /* RadarFileSystem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RadarFileSystem.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -447,6 +451,8 @@ 58F950CF2407038300364B15 /* RadarCollectionAdditions.m */, 01F99CFA2965C182004E8CF3 /* RadarConfig.h */, 01F99CFC2965C1C4004E8CF3 /* RadarConfig.m */, + E619D29C2B0BF4CE00C88578 /* RadarFileSystem.h */, + E619D29E2B0BF50D00C88578 /* RadarFileSystem.m */, 96A5A11727ADA02E007B960B /* RadarDelegateHolder.h */, DD4C104925D87E3E009C2E36 /* RadarDelegateHolder.m */, DD236CF723088F8400EB88F9 /* RadarLocationManager.h */, @@ -628,6 +634,7 @@ 96A5A0C427AD9F41007B960B /* RadarCircleGeometry+Internal.h in Headers */, 0114F058284EFDB700ADA4E4 /* RadarRouteMode.h in Headers */, 96A5A0D527AD9F41007B960B /* RadarRouteDuration+Internal.h in Headers */, + E619D29D2B0BF4CE00C88578 /* RadarFileSystem.h in Headers */, 96A5A0CE27AD9F41007B960B /* RadarCoordinate+Internal.h in Headers */, 96A5A11927ADA02F007B960B /* RadarLog.h in Headers */, 96A5A10A27AD9F7F007B960B /* RadarAddress.h in Headers */, @@ -785,6 +792,7 @@ 0107AA9B26220153008AB52F /* RadarContext.m in Sources */, 015C53AE29B8E8BA004F53A6 /* (null) in Sources */, 0107AB23262201EC008AB52F /* RadarSettings.m in Sources */, + E619D29F2B0BF50D00C88578 /* RadarFileSystem.m in Sources */, 0107AAAA26220165008AB52F /* RadarGeofenceGeometry.m in Sources */, 0107AAEC262201A6008AB52F /* RadarTrip.m in Sources */, 9679F4A327CD8DE200800797 /* CLLocation+Radar.m in Sources */, diff --git a/RadarSDK/RadarFileSystem.h b/RadarSDK/RadarFileSystem.h index 41d2e7579..2d0eaa1cc 100644 --- a/RadarSDK/RadarFileSystem.h +++ b/RadarSDK/RadarFileSystem.h @@ -1,3 +1,11 @@ +// +// RadarFileSystem.h +// RadarSDK +// +// Created by Kenny Hu on 11/20/23. +// Copyright © 2023 Radar Labs, Inc. All rights reserved. +// + #import @interface RadarFileSystem : NSObject @@ -5,4 +13,4 @@ - (NSData *)readFileAtPath:(NSString *)filePath; - (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath; -@end \ No newline at end of file +@end diff --git a/RadarSDK/RadarFileSystem.m b/RadarSDK/RadarFileSystem.m index b3d2f6756..5b00cad28 100644 --- a/RadarSDK/RadarFileSystem.m +++ b/RadarSDK/RadarFileSystem.m @@ -1,3 +1,11 @@ +// +// RadarFileSystem.m +// RadarSDK +// +// Created by Kenny Hu on 11/20/23. +// Copyright © 2023 Radar Labs, Inc. All rights reserved. +// + #import #import "RadarFileSystem.h" @@ -22,3 +30,4 @@ - (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath { } @end + From 7e8e5941cbf7ce4bab3ac2a159561f86fc6dd43a Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 21 Nov 2023 15:01:40 -0500 Subject: [PATCH 04/72] working prototype --- RadarSDK/Include/Radar.h | 14 ++++++++++++++ RadarSDK/Radar.m | 15 +++++++++++++++ RadarSDK/RadarFileSystem.h | 1 + RadarSDK/RadarFileSystem.m | 8 ++++++++ RadarSDK/RadarLog.h | 2 ++ RadarSDK/RadarLog.m | 34 ++++++++++++++++++++++++++++++++++ RadarSDK/RadarLogger.m | 19 +++++++++++-------- 7 files changed, 85 insertions(+), 8 deletions(-) diff --git a/RadarSDK/Include/Radar.h b/RadarSDK/Include/Radar.h index cc43eb240..d3aa77859 100644 --- a/RadarSDK/Include/Radar.h +++ b/RadarSDK/Include/Radar.h @@ -1003,6 +1003,20 @@ logConversionWithNotification */ + (void)setLogLevel:(RadarLogLevel)level; +/** + Writes to local logs. + + @param message The message to be logged. + */ ++ (void)writeLocalLog:(NSString *_Nonnull)message; + +/** + Log user terminating application. + + */ ++ (void)logUserTermination; + + #pragma mark - Helpers /** diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index d545cdf80..08c60ac32 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -43,6 +43,8 @@ + (id)sharedInstance { + (void)initializeWithPublishableKey:(NSString *)publishableKey { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeSDKCall message:@"initialize()"]; + + [[RadarLogger sharedInstance] flushLocalLogs]; [[NSNotificationCenter defaultCenter] addObserver:[self sharedInstance] selector:@selector(applicationWillEnterForeground) @@ -1036,6 +1038,19 @@ + (void)setLogLevel:(RadarLogLevel)level { [RadarSettings setLogLevel:level]; } ++ (void)writeLocalLog:(NSString *)message { + [[RadarLogger sharedInstance] logWithLevelLocal:RadarLogLevelInfo type:RadarLogTypeAppLifecycleEvent message:message]; + +} + ++ (void) logUserTermination { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; + NSString *dateString = [dateFormatter stringFromDate:[NSDate date]]; + NSString *message = [NSString stringWithFormat:@"User terminated app at %@", dateString]; + [[RadarLogger sharedInstance] logWithLevelLocal:RadarLogLevelInfo type:RadarLogTypeAppLifecycleEvent message:message]; +} + #pragma mark - Helpers + (NSString *)stringForStatus:(RadarStatus)status { diff --git a/RadarSDK/RadarFileSystem.h b/RadarSDK/RadarFileSystem.h index 2d0eaa1cc..17748033c 100644 --- a/RadarSDK/RadarFileSystem.h +++ b/RadarSDK/RadarFileSystem.h @@ -12,5 +12,6 @@ - (NSData *)readFileAtPath:(NSString *)filePath; - (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath; +- (void)deleteFileAtPath:(NSString *)filePath; @end diff --git a/RadarSDK/RadarFileSystem.m b/RadarSDK/RadarFileSystem.m index 5b00cad28..c66a361dc 100644 --- a/RadarSDK/RadarFileSystem.m +++ b/RadarSDK/RadarFileSystem.m @@ -29,5 +29,13 @@ - (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath { }]; } +//method to delte file at path +- (void)deleteFileAtPath:(NSString *)filePath { + NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; + [fileCoordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:filePath] options:NSFileCoordinatorWritingForDeleting error:nil byAccessor:^(NSURL *newURL) { + [[NSFileManager defaultManager] removeItemAtURL:newURL error:nil]; + }]; +} + @end diff --git a/RadarSDK/RadarLog.h b/RadarSDK/RadarLog.h index fb552a506..882a3a363 100644 --- a/RadarSDK/RadarLog.h +++ b/RadarSDK/RadarLog.h @@ -36,6 +36,8 @@ - (NSDictionary *_Nonnull)dictionaryValue; +- (instancetype)initWithDictionary:(NSDictionary *_Nonnull)dictionary; + + (NSArray *_Nullable)arrayForLogs:(NSArray *_Nullable)logs; /** diff --git a/RadarSDK/RadarLog.m b/RadarSDK/RadarLog.m index cdd218432..7f2273a0b 100644 --- a/RadarSDK/RadarLog.m +++ b/RadarSDK/RadarLog.m @@ -68,6 +68,29 @@ + (NSString *)stringForLogType:(RadarLogType)type { return str; } ++ (RadarLogLevel)logLevelForString:(NSString *)string { + NSDictionary *logLevelMap = @{ + @"none" : @(RadarLogLevelNone), + @"error" : @(RadarLogLevelError), + @"warning" : @(RadarLogLevelWarning), + @"info" : @(RadarLogLevelInfo), + @"debug" : @(RadarLogLevelDebug) + }; + return logLevelMap[string].integerValue; +} + ++ (RadarLogType)logTypeForString:(NSString *)string { + NSDictionary *logTypeMap = @{ + @"NONE" : @(RadarLogTypeNone), + @"SDK_CALL" : @(RadarLogTypeSDKCall), + @"SDK_ERROR" : @(RadarLogTypeSDKError), + @"SDK_EXCEPTION" : @(RadarLogTypeSDKException), + @"APP_LIFECYCLE_EVENT" : @(RadarLogTypeAppLifecycleEvent), + @"PERMISSION_EVENT" : @(RadarLogTypePermissionEvent) + }; + return logTypeMap[string].integerValue; +} + - (NSDictionary *)dictionaryValue { NSMutableDictionary *dict = [NSMutableDictionary new]; dict[@"level"] = [RadarLog stringForLogLevel:self.level]; @@ -81,6 +104,17 @@ - (NSDictionary *)dictionaryValue { return dict; } +- (instancetype)initWithDictionary:(NSDictionary *)dictionary { + self = [super init]; + if (self) { + _level = [RadarLog logLevelForString:dictionary[@"level"]]; + _type = [RadarLog logTypeForString:dictionary[@"type"]]; + _message = dictionary[@"message"]; + _createdAt = dictionary[@"createdAt"]; + } + return self; +} + + (NSArray *)arrayForLogs:(NSArray *)logs { if (!logs) { return nil; diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index 7f9283267..c0ccf804c 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -60,25 +60,26 @@ - (void) logWithLevelLocal:(RadarLogLevel)level message:(NSString *)message { } - (void) logWithLevelLocal:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { - RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; - + RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; NSString *logFileName = @"RadarLogs.txt"; NSString *logFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; - NSData *logData = [NSKeyedArchiver archivedDataWithRootObject:radarLog requiringSecureCoding:NO error:nil]; - RadarFileSystem *fileHandler = [[RadarFileSystem alloc] init]; + NSData *logData = [NSJSONSerialization dataWithJSONObject:[radarLog dictionaryValue] options:0 error:nil]; + RadarFileSystem *fileHandler = [[RadarFileSystem alloc] init]; [fileHandler writeData:logData toFileAtPath:logFilePath]; } - (void)flushLocalLogs { - // read logs from file RadarFileSystem *fileHandler = [[RadarFileSystem alloc] init]; NSData *fileData = [fileHandler readFileAtPath:self.logFilePath]; if (fileData) { - // Unarchive the data to get the original object - RadarLog *retrievedLog = [NSKeyedUnarchiver unarchivedObjectOfClass:[RadarLog class] fromData:fileData error:nil]; + NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:fileData options:0 error:nil]; + RadarLog *retrievedLog = [[RadarLog alloc] initWithDictionary:jsonDict]; + NSLog(@"retrieved log: %@", retrievedLog.message); + [fileHandler deleteFileAtPath:self.logFilePath]; if ([retrievedLog isKindOfClass:[RadarLog class]]) { dispatch_async(dispatch_get_main_queue(), ^{ + [Radar sendLog:retrievedLog.level type:retrievedLog.type message:retrievedLog.message]; RadarLogLevel logLevel = [RadarSettings logLevel]; @@ -90,9 +91,11 @@ - (void)flushLocalLogs { [[RadarDelegateHolder sharedInstance] didLogMessage:log]; } }); - } + } } } + + @end From 047d0e6ef62d2fb735486e5a34a7a13bfdc71646 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 21 Nov 2023 15:14:37 -0500 Subject: [PATCH 05/72] moved file handler to property --- RadarSDK/RadarLogger.h | 4 +++- RadarSDK/RadarLogger.m | 14 ++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/RadarSDK/RadarLogger.h b/RadarSDK/RadarLogger.h index ca968e4ca..02f1fbb18 100644 --- a/RadarSDK/RadarLogger.h +++ b/RadarSDK/RadarLogger.h @@ -8,12 +8,14 @@ #import #import "RadarDelegate.h" +#import "RadarFileSystem.h" NS_ASSUME_NONNULL_BEGIN @interface RadarLogger : NSObject -@property (assign) NSString *logFilePath; +@property (strong, nonatomic) NSString *logFilePath; +@property (strong, nonatomic) RadarFileSystem *fileHandler; + (instancetype)sharedInstance; - (void)logWithLevel:(RadarLogLevel)level message:(NSString *)message; diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index c0ccf804c..25864ec86 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -32,6 +32,7 @@ - (instancetype)init { NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; NSString *logFileName = @"RadarLogs.txt"; self.logFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; + self.fileHandler = [[RadarFileSystem alloc] init]; } return self; } @@ -61,22 +62,19 @@ - (void) logWithLevelLocal:(RadarLogLevel)level message:(NSString *)message { - (void) logWithLevelLocal:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; - NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; - NSString *logFileName = @"RadarLogs.txt"; - NSString *logFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; + NSData *logData = [NSJSONSerialization dataWithJSONObject:[radarLog dictionaryValue] options:0 error:nil]; - RadarFileSystem *fileHandler = [[RadarFileSystem alloc] init]; - [fileHandler writeData:logData toFileAtPath:logFilePath]; + + [self.fileHandler writeData:logData toFileAtPath:self.logFilePath]; } - (void)flushLocalLogs { - RadarFileSystem *fileHandler = [[RadarFileSystem alloc] init]; - NSData *fileData = [fileHandler readFileAtPath:self.logFilePath]; + NSData *fileData = [self.fileHandler readFileAtPath:self.logFilePath]; if (fileData) { NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:fileData options:0 error:nil]; RadarLog *retrievedLog = [[RadarLog alloc] initWithDictionary:jsonDict]; NSLog(@"retrieved log: %@", retrievedLog.message); - [fileHandler deleteFileAtPath:self.logFilePath]; + [self.fileHandler deleteFileAtPath:self.logFilePath]; if ([retrievedLog isKindOfClass:[RadarLog class]]) { dispatch_async(dispatch_get_main_queue(), ^{ From 0975548340fd730e57d2965baa24091c51909ecb Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 21 Nov 2023 15:33:10 -0500 Subject: [PATCH 06/72] implemented array of logs --- RadarSDK/RadarLogger.m | 43 +++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index 25864ec86..111068011 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -63,21 +63,41 @@ - (void) logWithLevelLocal:(RadarLogLevel)level message:(NSString *)message { - (void) logWithLevelLocal:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; - NSData *logData = [NSJSONSerialization dataWithJSONObject:[radarLog dictionaryValue] options:0 error:nil]; - - [self.fileHandler writeData:logData toFileAtPath:self.logFilePath]; + NSData *fileData = [self.fileHandler readFileAtPath:self.logFilePath]; + NSMutableArray *existingLogs = [NSMutableArray array]; + if (fileData) { + NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:fileData options:0 error:nil]; + for (NSDictionary *jsonDict in jsonArray) { + RadarLog *existingLog = [[RadarLog alloc] initWithDictionary:jsonDict]; + [existingLogs addObject:existingLog]; + } + } + [existingLogs addObject:radarLog]; + + NSMutableArray *updatedLogsArray = [NSMutableArray array]; + for (RadarLog *log in existingLogs) { + [updatedLogsArray addObject:[log dictionaryValue]]; + } + + NSData *updatedLogData = [NSJSONSerialization dataWithJSONObject:updatedLogsArray options:0 error:nil]; + [self.fileHandler writeData:updatedLogData toFileAtPath:self.logFilePath]; } - (void)flushLocalLogs { NSData *fileData = [self.fileHandler readFileAtPath:self.logFilePath]; if (fileData) { - NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:fileData options:0 error:nil]; - RadarLog *retrievedLog = [[RadarLog alloc] initWithDictionary:jsonDict]; - NSLog(@"retrieved log: %@", retrievedLog.message); - [self.fileHandler deleteFileAtPath:self.logFilePath]; - if ([retrievedLog isKindOfClass:[RadarLog class]]) { + NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:fileData options:0 error:nil]; + NSMutableArray *existingLogs = [NSMutableArray array]; + + for (NSDictionary *jsonDict in jsonArray) { + RadarLog *existingLog = [[RadarLog alloc] initWithDictionary:jsonDict]; + [existingLogs addObject:existingLog]; + } + + for (RadarLog *retrievedLog in existingLogs) { + NSLog(@"retrieved log: %@", retrievedLog.message); + dispatch_async(dispatch_get_main_queue(), ^{ - [Radar sendLog:retrievedLog.level type:retrievedLog.type message:retrievedLog.message]; RadarLogLevel logLevel = [RadarSettings logLevel]; @@ -89,9 +109,10 @@ - (void)flushLocalLogs { [[RadarDelegateHolder sharedInstance] didLogMessage:log]; } }); - } + } + + [self.fileHandler deleteFileAtPath:self.logFilePath]; } - } From f28ecb4de60b8d7de672a1ded5be47863a8813e3 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 21 Nov 2023 15:41:35 -0500 Subject: [PATCH 07/72] cleanup --- RadarSDK/Radar.m | 2 +- RadarSDK/RadarFileSystem.h | 2 ++ RadarSDK/RadarFileSystem.m | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index 08c60ac32..e070f820b 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1046,7 +1046,7 @@ + (void)writeLocalLog:(NSString *)message { + (void) logUserTermination { NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; - NSString *dateString = [dateFormatter stringFromDate:[NSDate date]]; + NSString *dateString = [dateFormatter stringFromDate:[NSDate date]]; NSString *message = [NSString stringWithFormat:@"User terminated app at %@", dateString]; [[RadarLogger sharedInstance] logWithLevelLocal:RadarLogLevelInfo type:RadarLogTypeAppLifecycleEvent message:message]; } diff --git a/RadarSDK/RadarFileSystem.h b/RadarSDK/RadarFileSystem.h index 17748033c..86c3432d5 100644 --- a/RadarSDK/RadarFileSystem.h +++ b/RadarSDK/RadarFileSystem.h @@ -11,7 +11,9 @@ @interface RadarFileSystem : NSObject - (NSData *)readFileAtPath:(NSString *)filePath; + - (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath; + - (void)deleteFileAtPath:(NSString *)filePath; @end diff --git a/RadarSDK/RadarFileSystem.m b/RadarSDK/RadarFileSystem.m index c66a361dc..bb516dc44 100644 --- a/RadarSDK/RadarFileSystem.m +++ b/RadarSDK/RadarFileSystem.m @@ -29,7 +29,6 @@ - (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath { }]; } -//method to delte file at path - (void)deleteFileAtPath:(NSString *)filePath { NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; [fileCoordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:filePath] options:NSFileCoordinatorWritingForDeleting error:nil byAccessor:^(NSURL *newURL) { From 6a2cb6c4cd7835d41aec4069ad682eb6e76e4729 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 21 Nov 2023 15:55:15 -0500 Subject: [PATCH 08/72] make instance type nullable --- RadarSDK/RadarLog.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RadarSDK/RadarLog.h b/RadarSDK/RadarLog.h index 882a3a363..5af75c233 100644 --- a/RadarSDK/RadarLog.h +++ b/RadarSDK/RadarLog.h @@ -36,7 +36,7 @@ - (NSDictionary *_Nonnull)dictionaryValue; -- (instancetype)initWithDictionary:(NSDictionary *_Nonnull)dictionary; +- (instancetype _Nullable)initWithDictionary:(NSDictionary *_Nonnull)dictionary; + (NSArray *_Nullable)arrayForLogs:(NSArray *_Nullable)logs; From b8a0c5d466de9843da06f99340d968f334c30773 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 22 Nov 2023 11:40:06 -0500 Subject: [PATCH 09/72] change log type --- RadarSDK/Radar.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index e070f820b..7f4554a53 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1039,7 +1039,7 @@ + (void)setLogLevel:(RadarLogLevel)level { } + (void)writeLocalLog:(NSString *)message { - [[RadarLogger sharedInstance] logWithLevelLocal:RadarLogLevelInfo type:RadarLogTypeAppLifecycleEvent message:message]; + [[RadarLogger sharedInstance] logWithLevelLocal:RadarLogLevelInfo type:RadarLogTypeNone message:message]; } @@ -1048,7 +1048,7 @@ + (void) logUserTermination { [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; NSString *dateString = [dateFormatter stringFromDate:[NSDate date]]; NSString *message = [NSString stringWithFormat:@"User terminated app at %@", dateString]; - [[RadarLogger sharedInstance] logWithLevelLocal:RadarLogLevelInfo type:RadarLogTypeAppLifecycleEvent message:message]; + [[RadarLogger sharedInstance] logWithLevelLocal:RadarLogLevelInfo type:RadarLogTypeNone message:message]; } #pragma mark - Helpers From 96cf80f2f6c4ee1770fbab265d2f1ac6357b0992 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 28 Nov 2023 12:39:02 -0500 Subject: [PATCH 10/72] changing naming --- RadarSDK/Include/Radar.h | 2 +- RadarSDK/Radar.m | 6 +++--- RadarSDK/RadarLogger.h | 4 ++-- RadarSDK/RadarLogger.m | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/RadarSDK/Include/Radar.h b/RadarSDK/Include/Radar.h index d3aa77859..17895c24c 100644 --- a/RadarSDK/Include/Radar.h +++ b/RadarSDK/Include/Radar.h @@ -1014,7 +1014,7 @@ logConversionWithNotification Log user terminating application. */ -+ (void)logUserTermination; ++ (void)logTermination; #pragma mark - Helpers diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index 7f4554a53..76707eefd 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1039,7 +1039,7 @@ + (void)setLogLevel:(RadarLogLevel)level { } + (void)writeLocalLog:(NSString *)message { - [[RadarLogger sharedInstance] logWithLevelLocal:RadarLogLevelInfo type:RadarLogTypeNone message:message]; + [[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:message]; } @@ -1047,8 +1047,8 @@ + (void) logUserTermination { NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; NSString *dateString = [dateFormatter stringFromDate:[NSDate date]]; - NSString *message = [NSString stringWithFormat:@"User terminated app at %@", dateString]; - [[RadarLogger sharedInstance] logWithLevelLocal:RadarLogLevelInfo type:RadarLogTypeNone message:message]; + NSString *message = [NSString stringWithFormat:@"App terminated at %@", dateString]; + [[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:message]; } #pragma mark - Helpers diff --git a/RadarSDK/RadarLogger.h b/RadarSDK/RadarLogger.h index 02f1fbb18..9ee4a49a8 100644 --- a/RadarSDK/RadarLogger.h +++ b/RadarSDK/RadarLogger.h @@ -20,8 +20,8 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)sharedInstance; - (void)logWithLevel:(RadarLogLevel)level message:(NSString *)message; - (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; -- (void)logWithLevelLocal:(RadarLogLevel)level message:(NSString *)message; -- (void)logWithLevelLocal:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; +- (void)logWithLevelToFileSystem:(RadarLogLevel)level message:(NSString *)message; +- (void)logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; - (void)flushLocalLogs; @end diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index 111068011..a518a854b 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -56,11 +56,11 @@ - (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSStr }); } -- (void) logWithLevelLocal:(RadarLogLevel)level message:(NSString *)message { +- (void) logWithLevelToFileSystem:(RadarLogLevel)level message:(NSString *)message { [self logWithLevelLocal:level type:RadarLogTypeNone message:message]; } -- (void) logWithLevelLocal:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { +- (void) logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; NSData *fileData = [self.fileHandler readFileAtPath:self.logFilePath]; From 754d441e6150439eb38e47c76edb4a03f46e809a Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 28 Nov 2023 13:47:49 -0500 Subject: [PATCH 11/72] added optional timestamp and battery info --- Example/Example/AppDelegate.swift | 262 ++++++++++++++++-------------- RadarSDK/Include/Radar.h | 15 +- RadarSDK/Radar.m | 17 +- RadarSDK/RadarLogger.h | 4 + RadarSDK/RadarLogger.m | 26 ++- 5 files changed, 190 insertions(+), 134 deletions(-) diff --git a/Example/Example/AppDelegate.swift b/Example/Example/AppDelegate.swift index 173c17f02..3769b5a91 100644 --- a/Example/Example/AppDelegate.swift +++ b/Example/Example/AppDelegate.swift @@ -13,6 +13,17 @@ import RadarSDK class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, CLLocationManagerDelegate, RadarDelegate { let locationManager = CLLocationManager() + + func applicationWillResignActive(_ application: UIApplication) { + // This method is called when the app is about to move from active to inactive state. + // You can log the event here. + print("User is about to quit the application.") + } + + func applicationWillTerminate(_ application: UIApplication) { + Radar.writeLocalLog("another arb log entry.") + print("User is to quit the application.") + } func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { (_, _) in } @@ -22,7 +33,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD self.requestLocationPermissions() // Replace with a valid test publishable key - Radar.initialize(publishableKey: "prj_test_pk_0000000000000000000000000000000000000000") + Radar.writeLocalLog("another arb log entry2.") + Radar.initialize(publishableKey: "prj_test_pk_dda829b0b0bc3621b754e42da53271d07b32992f") Radar.setDelegate(self) if UIApplication.shared.applicationState != .background { @@ -34,131 +46,131 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD print("Track once: status = \(Radar.stringForStatus(status)); location = \(String(describing: location)); events = \(String(describing: events)); user = \(String(describing: user))") } } - - let options = RadarTrackingOptions.presetContinuous +// + let options = RadarTrackingOptions.presetEfficient Radar.startTracking(trackingOptions: options) - - Radar.getContext { (status, location, context) in - print("Context: status = \(Radar.stringForStatus(status)); location = \(String(describing: location)); context?.geofences = \(String(describing: context?.geofences)); context?.place = \(String(describing: context?.place)); context?.country = \(String(describing: context?.country))") - } - - // In the Radar dashboard settings - // (https://radar.com/dashboard/settings), add this to the chain - // metadata: {"mcdonalds":{"orderActive":"true"}}. - Radar.searchPlaces( - radius: 1000, - chains: ["mcdonalds"], - chainMetadata: ["orderActive": "true"], - categories: nil, - groups: nil, - limit: 10 - ) { (status, location, places) in - print("Search places: status = \(Radar.stringForStatus(status)); places = \(String(describing: places))") - } - - Radar.searchGeofences( - radius: 1000, - tags: ["store"], - metadata: nil, - limit: 10 - ) { (status, location, geofences) in - print("Search geofences: status = \(Radar.stringForStatus(status)); geofences = \(String(describing: geofences))") - } - - Radar.geocode(address: "20 jay st brooklyn") { (status, addresses) in - print("Geocode: status = \(Radar.stringForStatus(status)); coordinate = \(String(describing: addresses?.first?.coordinate))") - } - - Radar.reverseGeocode { (status, addresses) in - print("Reverse geocode: status = \(Radar.stringForStatus(status)); formattedAddress = \(String(describing: addresses?.first?.formattedAddress))") - } - - Radar.ipGeocode { (status, address, proxy) in - print("IP geocode: status = \(Radar.stringForStatus(status)); country = \(String(describing: address?.countryCode)); city = \(String(describing: address?.city)); proxy = \(proxy)") - } - - let origin = CLLocation(latitude: 40.78382, longitude: -73.97536) - let destination = CLLocation(latitude: 40.70390, longitude: -73.98670) - - - Radar.autocomplete( - query: "brooklyn", - near: origin, - layers: ["locality"], - limit: 10, - country: "US", - expandUnits:true - ) { (status, addresses) in - print("Autocomplete: status = \(Radar.stringForStatus(status)); formattedAddress = \(String(describing: addresses?.first?.formattedAddress))") - - if let address = addresses?.first { - Radar.validateAddress(address: address) { (status, address, verificationStatus) in - print("Validate address: status = \(Radar.stringForStatus(status)); address = \(String(describing: address)); verificationStatus = \(Radar.stringForVerificationStatus(verificationStatus))") - } - } - } - - Radar.autocomplete( - query: "brooklyn", - near: origin, - layers: ["locality"], - limit: 10, - country: "US" - ) { (status, addresses) in - print("Autocomplete: status = \(Radar.stringForStatus(status)); formattedAddress = \(String(describing: addresses?.first?.formattedAddress))") - } - - Radar.getDistance( - origin: origin, - destination: destination, - modes: [.foot, .car], - units: .imperial - ) { (status, routes) in - print("Distance: status = \(Radar.stringForStatus(status)); routes.car.distance.value = \(String(describing: routes?.car?.distance.value)); routes.car.distance.text = \(String(describing: routes?.car?.distance.text)); routes.car.duration.value = \(String(describing: routes?.car?.duration.value)); routes.car.duration.text = \(String(describing: routes?.car?.duration.text))") - } - - let tripOptions = RadarTripOptions(externalId: "299", destinationGeofenceTag: "store", destinationGeofenceExternalId: "123") - tripOptions.mode = .car - tripOptions.approachingThreshold = 9 - Radar.startTrip(options: tripOptions) - - var i = 0 - Radar.mockTracking( - origin: origin, - destination: destination, - mode: .car, - steps: 3, - interval: 3 - ) { (status, location, events, user) in - print("Mock track: status = \(Radar.stringForStatus(status)); location = \(String(describing: location)); events = \(String(describing: events)); user = \(String(describing: user))") - - if (i == 2) { - Radar.completeTrip() - } - - i += 1 - } - - let origins = [ - CLLocation(latitude: 40.78382, longitude: -73.97536), - CLLocation(latitude: 40.70390, longitude: -73.98670) - ] - let destinations = [ - CLLocation(latitude: 40.64189, longitude: -73.78779), - CLLocation(latitude: 35.99801, longitude: -78.94294) - ] - - Radar.getMatrix(origins: origins, destinations: destinations, mode: .car, units: .imperial) { (status, matrix) in - print("Matrix: status = \(Radar.stringForStatus(status)); matrix[0][0].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 0, destinationIndex: 0)?.duration.text)); matrix[0][1].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 0, destinationIndex: 1)?.duration.text)); matrix[1][0].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 1, destinationIndex: 0)?.duration.text)); matrix[1][1].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 1, destinationIndex: 1)?.duration.text))") - } - - Radar.logConversion(name: "conversion_event", metadata: ["data": "test"]) { (status, event) in - if let conversionEvent = event, conversionEvent.type == .conversion { - print("Conversion name: \(conversionEvent.conversionName!)") - } - - print("Log Conversion: status = \(Radar.stringForStatus(status)); event = \(String(describing: event))") - } +// +// Radar.getContext { (status, location, context) in +// print("Context: status = \(Radar.stringForStatus(status)); location = \(String(describing: location)); context?.geofences = \(String(describing: context?.geofences)); context?.place = \(String(describing: context?.place)); context?.country = \(String(describing: context?.country))") +// } +// +// // In the Radar dashboard settings +// // (https://radar.com/dashboard/settings), add this to the chain +// // metadata: {"mcdonalds":{"orderActive":"true"}}. +// Radar.searchPlaces( +// radius: 1000, +// chains: ["mcdonalds"], +// chainMetadata: ["orderActive": "true"], +// categories: nil, +// groups: nil, +// limit: 10 +// ) { (status, location, places) in +// print("Search places: status = \(Radar.stringForStatus(status)); places = \(String(describing: places))") +// } +// +// Radar.searchGeofences( +// radius: 1000, +// tags: ["store"], +// metadata: nil, +// limit: 10 +// ) { (status, location, geofences) in +// print("Search geofences: status = \(Radar.stringForStatus(status)); geofences = \(String(describing: geofences))") +// } +// +// Radar.geocode(address: "20 jay st brooklyn") { (status, addresses) in +// print("Geocode: status = \(Radar.stringForStatus(status)); coordinate = \(String(describing: addresses?.first?.coordinate))") +// } +// +// Radar.reverseGeocode { (status, addresses) in +// print("Reverse geocode: status = \(Radar.stringForStatus(status)); formattedAddress = \(String(describing: addresses?.first?.formattedAddress))") +// } +// +// Radar.ipGeocode { (status, address, proxy) in +// print("IP geocode: status = \(Radar.stringForStatus(status)); country = \(String(describing: address?.countryCode)); city = \(String(describing: address?.city)); proxy = \(proxy)") +// } +// +// let origin = CLLocation(latitude: 40.78382, longitude: -73.97536) +// let destination = CLLocation(latitude: 40.70390, longitude: -73.98670) +// +// +// Radar.autocomplete( +// query: "brooklyn", +// near: origin, +// layers: ["locality"], +// limit: 10, +// country: "US", +// expandUnits:true +// ) { (status, addresses) in +// print("Autocomplete: status = \(Radar.stringForStatus(status)); formattedAddress = \(String(describing: addresses?.first?.formattedAddress))") +// +// if let address = addresses?.first { +// Radar.validateAddress(address: address) { (status, address, verificationStatus) in +// print("Validate address: status = \(Radar.stringForStatus(status)); address = \(String(describing: address)); verificationStatus = \(Radar.stringForVerificationStatus(verificationStatus))") +// } +// } +// } +// +// Radar.autocomplete( +// query: "brooklyn", +// near: origin, +// layers: ["locality"], +// limit: 10, +// country: "US" +// ) { (status, addresses) in +// print("Autocomplete: status = \(Radar.stringForStatus(status)); formattedAddress = \(String(describing: addresses?.first?.formattedAddress))") +// } +// +// Radar.getDistance( +// origin: origin, +// destination: destination, +// modes: [.foot, .car], +// units: .imperial +// ) { (status, routes) in +// print("Distance: status = \(Radar.stringForStatus(status)); routes.car.distance.value = \(String(describing: routes?.car?.distance.value)); routes.car.distance.text = \(String(describing: routes?.car?.distance.text)); routes.car.duration.value = \(String(describing: routes?.car?.duration.value)); routes.car.duration.text = \(String(describing: routes?.car?.duration.text))") +// } +// +// let tripOptions = RadarTripOptions(externalId: "299", destinationGeofenceTag: "store", destinationGeofenceExternalId: "123") +// tripOptions.mode = .car +// tripOptions.approachingThreshold = 9 +// Radar.startTrip(options: tripOptions) +// +// var i = 0 +// Radar.mockTracking( +// origin: origin, +// destination: destination, +// mode: .car, +// steps: 3, +// interval: 3 +// ) { (status, location, events, user) in +// print("Mock track: status = \(Radar.stringForStatus(status)); location = \(String(describing: location)); events = \(String(describing: events)); user = \(String(describing: user))") +// +// if (i == 2) { +// Radar.completeTrip() +// } +// +// i += 1 +// } +// +// let origins = [ +// CLLocation(latitude: 40.78382, longitude: -73.97536), +// CLLocation(latitude: 40.70390, longitude: -73.98670) +// ] +// let destinations = [ +// CLLocation(latitude: 40.64189, longitude: -73.78779), +// CLLocation(latitude: 35.99801, longitude: -78.94294) +// ] +// +// Radar.getMatrix(origins: origins, destinations: destinations, mode: .car, units: .imperial) { (status, matrix) in +// print("Matrix: status = \(Radar.stringForStatus(status)); matrix[0][0].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 0, destinationIndex: 0)?.duration.text)); matrix[0][1].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 0, destinationIndex: 1)?.duration.text)); matrix[1][0].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 1, destinationIndex: 0)?.duration.text)); matrix[1][1].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 1, destinationIndex: 1)?.duration.text))") +// } +// +// Radar.logConversion(name: "conversion_event", metadata: ["data": "test"]) { (status, event) in +// if let conversionEvent = event, conversionEvent.type == .conversion { +// print("Conversion name: \(conversionEvent.conversionName!)") +// } +// +// print("Log Conversion: status = \(Radar.stringForStatus(status)); event = \(String(describing: event))") +// } return true } diff --git a/RadarSDK/Include/Radar.h b/RadarSDK/Include/Radar.h index 17895c24c..6410e010b 100644 --- a/RadarSDK/Include/Radar.h +++ b/RadarSDK/Include/Radar.h @@ -1011,11 +1011,24 @@ logConversionWithNotification + (void)writeLocalLog:(NSString *_Nonnull)message; /** - Log user terminating application. + Log application termination. */ + (void)logTermination; +/** + Log application entering background. + + */ ++ (void)logEnteringBackground; + +/** + Log application resigning active. + + */ ++ (void)logResignActive; + + #pragma mark - Helpers diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index 76707eefd..90f674245 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1043,14 +1043,19 @@ + (void)writeLocalLog:(NSString *)message { } -+ (void) logUserTermination { - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; - NSString *dateString = [dateFormatter stringFromDate:[NSDate date]]; - NSString *message = [NSString stringWithFormat:@"App terminated at %@", dateString]; - [[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:message]; ++ (void) logTermination { + [[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminated" includeDate:YES includeBattery:YES]; +} + ++ (void) logEnteringBackground { + [[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background" includeDate:YES includeBattery:YES]; } ++ (void) logResignActive { + [[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:@"App resigning active" includeDate:YES includeBattery:YES]; +} + + #pragma mark - Helpers + (NSString *)stringForStatus:(RadarStatus)status { diff --git a/RadarSDK/RadarLogger.h b/RadarSDK/RadarLogger.h index 9ee4a49a8..b089e68b7 100644 --- a/RadarSDK/RadarLogger.h +++ b/RadarSDK/RadarLogger.h @@ -16,12 +16,16 @@ NS_ASSUME_NONNULL_BEGIN @property (strong, nonatomic) NSString *logFilePath; @property (strong, nonatomic) RadarFileSystem *fileHandler; +@property (strong, nonatomic) NSDateFormatter *dateFormatter; +@property (strong, nonatomic) UIDevice *device; + (instancetype)sharedInstance; - (void)logWithLevel:(RadarLogLevel)level message:(NSString *)message; - (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; - (void)logWithLevelToFileSystem:(RadarLogLevel)level message:(NSString *)message; +- (void)logWithLevelToFileSystem:(RadarLogLevel)level message:(NSString *)message includeDate:(BOOL)includeDate includeBattery:(BOOL)includeBattery; - (void)logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; +- (void)logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message includeDate:(BOOL)includeDate includeBattery:(BOOL)includeBattery; - (void)flushLocalLogs; @end diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index a518a854b..781f0b831 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -33,6 +33,10 @@ - (instancetype)init { NSString *logFileName = @"RadarLogs.txt"; self.logFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; self.fileHandler = [[RadarFileSystem alloc] init]; + self.dateFormatter = [[NSDateFormatter alloc] init]; + [self.dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; + self.device = [UIDevice currentDevice]; + self.device.batteryMonitoringEnabled = YES; } return self; } @@ -57,10 +61,28 @@ - (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSStr } - (void) logWithLevelToFileSystem:(RadarLogLevel)level message:(NSString *)message { - [self logWithLevelLocal:level type:RadarLogTypeNone message:message]; + [self logWithLevelToFileSystem:level type:RadarLogTypeNone message:message includeDate:NO includeBattery:NO]; } -- (void) logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { +- (void)logWithLevelToFileSystem:(RadarLogLevel)level message:(NSString *)message includeDate:(BOOL)includeDate includeBattery:(BOOL)includeBattery{ + [self logWithLevelToFileSystem:level type:RadarLogTypeNone message:message includeDate:includeDate includeBattery:includeBattery]; +} + +- (void)logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message{ + [self logWithLevelToFileSystem:level type:type message:message includeDate:NO includeBattery:NO]; +} + +- (void) logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message includeDate:(BOOL)includeDate includeBattery:(BOOL)includeBattery{ + NSString *dateString = [self.dateFormatter stringFromDate:[NSDate date]]; + float batteryLevel = [self.device batteryLevel]; + //append date and battery level to message if requested + if (includeDate && includeBattery) { + message = [NSString stringWithFormat:@"%@ | at %@ | with %2.f%% battery", message, dateString, batteryLevel*100]; + } else if (includeDate) { + message = [NSString stringWithFormat:@"%@ | at %@", message, dateString]; + } else if (includeBattery) { + message = [NSString stringWithFormat:@"%@ | with %2.f%% battery", message, batteryLevel*100]; + } RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; NSData *fileData = [self.fileHandler readFileAtPath:self.logFilePath]; From 48cf311b53fae8ca75917763067d5263a545afc4 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 28 Nov 2023 13:49:10 -0500 Subject: [PATCH 12/72] revert changes to example --- Example/Example/AppDelegate.swift | 262 ++++++++++++++---------------- 1 file changed, 125 insertions(+), 137 deletions(-) diff --git a/Example/Example/AppDelegate.swift b/Example/Example/AppDelegate.swift index 3769b5a91..173c17f02 100644 --- a/Example/Example/AppDelegate.swift +++ b/Example/Example/AppDelegate.swift @@ -13,17 +13,6 @@ import RadarSDK class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, CLLocationManagerDelegate, RadarDelegate { let locationManager = CLLocationManager() - - func applicationWillResignActive(_ application: UIApplication) { - // This method is called when the app is about to move from active to inactive state. - // You can log the event here. - print("User is about to quit the application.") - } - - func applicationWillTerminate(_ application: UIApplication) { - Radar.writeLocalLog("another arb log entry.") - print("User is to quit the application.") - } func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { (_, _) in } @@ -33,8 +22,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD self.requestLocationPermissions() // Replace with a valid test publishable key - Radar.writeLocalLog("another arb log entry2.") - Radar.initialize(publishableKey: "prj_test_pk_dda829b0b0bc3621b754e42da53271d07b32992f") + Radar.initialize(publishableKey: "prj_test_pk_0000000000000000000000000000000000000000") Radar.setDelegate(self) if UIApplication.shared.applicationState != .background { @@ -46,131 +34,131 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD print("Track once: status = \(Radar.stringForStatus(status)); location = \(String(describing: location)); events = \(String(describing: events)); user = \(String(describing: user))") } } -// - let options = RadarTrackingOptions.presetEfficient + + let options = RadarTrackingOptions.presetContinuous Radar.startTracking(trackingOptions: options) -// -// Radar.getContext { (status, location, context) in -// print("Context: status = \(Radar.stringForStatus(status)); location = \(String(describing: location)); context?.geofences = \(String(describing: context?.geofences)); context?.place = \(String(describing: context?.place)); context?.country = \(String(describing: context?.country))") -// } -// -// // In the Radar dashboard settings -// // (https://radar.com/dashboard/settings), add this to the chain -// // metadata: {"mcdonalds":{"orderActive":"true"}}. -// Radar.searchPlaces( -// radius: 1000, -// chains: ["mcdonalds"], -// chainMetadata: ["orderActive": "true"], -// categories: nil, -// groups: nil, -// limit: 10 -// ) { (status, location, places) in -// print("Search places: status = \(Radar.stringForStatus(status)); places = \(String(describing: places))") -// } -// -// Radar.searchGeofences( -// radius: 1000, -// tags: ["store"], -// metadata: nil, -// limit: 10 -// ) { (status, location, geofences) in -// print("Search geofences: status = \(Radar.stringForStatus(status)); geofences = \(String(describing: geofences))") -// } -// -// Radar.geocode(address: "20 jay st brooklyn") { (status, addresses) in -// print("Geocode: status = \(Radar.stringForStatus(status)); coordinate = \(String(describing: addresses?.first?.coordinate))") -// } -// -// Radar.reverseGeocode { (status, addresses) in -// print("Reverse geocode: status = \(Radar.stringForStatus(status)); formattedAddress = \(String(describing: addresses?.first?.formattedAddress))") -// } -// -// Radar.ipGeocode { (status, address, proxy) in -// print("IP geocode: status = \(Radar.stringForStatus(status)); country = \(String(describing: address?.countryCode)); city = \(String(describing: address?.city)); proxy = \(proxy)") -// } -// -// let origin = CLLocation(latitude: 40.78382, longitude: -73.97536) -// let destination = CLLocation(latitude: 40.70390, longitude: -73.98670) -// -// -// Radar.autocomplete( -// query: "brooklyn", -// near: origin, -// layers: ["locality"], -// limit: 10, -// country: "US", -// expandUnits:true -// ) { (status, addresses) in -// print("Autocomplete: status = \(Radar.stringForStatus(status)); formattedAddress = \(String(describing: addresses?.first?.formattedAddress))") -// -// if let address = addresses?.first { -// Radar.validateAddress(address: address) { (status, address, verificationStatus) in -// print("Validate address: status = \(Radar.stringForStatus(status)); address = \(String(describing: address)); verificationStatus = \(Radar.stringForVerificationStatus(verificationStatus))") -// } -// } -// } -// -// Radar.autocomplete( -// query: "brooklyn", -// near: origin, -// layers: ["locality"], -// limit: 10, -// country: "US" -// ) { (status, addresses) in -// print("Autocomplete: status = \(Radar.stringForStatus(status)); formattedAddress = \(String(describing: addresses?.first?.formattedAddress))") -// } -// -// Radar.getDistance( -// origin: origin, -// destination: destination, -// modes: [.foot, .car], -// units: .imperial -// ) { (status, routes) in -// print("Distance: status = \(Radar.stringForStatus(status)); routes.car.distance.value = \(String(describing: routes?.car?.distance.value)); routes.car.distance.text = \(String(describing: routes?.car?.distance.text)); routes.car.duration.value = \(String(describing: routes?.car?.duration.value)); routes.car.duration.text = \(String(describing: routes?.car?.duration.text))") -// } -// -// let tripOptions = RadarTripOptions(externalId: "299", destinationGeofenceTag: "store", destinationGeofenceExternalId: "123") -// tripOptions.mode = .car -// tripOptions.approachingThreshold = 9 -// Radar.startTrip(options: tripOptions) -// -// var i = 0 -// Radar.mockTracking( -// origin: origin, -// destination: destination, -// mode: .car, -// steps: 3, -// interval: 3 -// ) { (status, location, events, user) in -// print("Mock track: status = \(Radar.stringForStatus(status)); location = \(String(describing: location)); events = \(String(describing: events)); user = \(String(describing: user))") -// -// if (i == 2) { -// Radar.completeTrip() -// } -// -// i += 1 -// } -// -// let origins = [ -// CLLocation(latitude: 40.78382, longitude: -73.97536), -// CLLocation(latitude: 40.70390, longitude: -73.98670) -// ] -// let destinations = [ -// CLLocation(latitude: 40.64189, longitude: -73.78779), -// CLLocation(latitude: 35.99801, longitude: -78.94294) -// ] -// -// Radar.getMatrix(origins: origins, destinations: destinations, mode: .car, units: .imperial) { (status, matrix) in -// print("Matrix: status = \(Radar.stringForStatus(status)); matrix[0][0].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 0, destinationIndex: 0)?.duration.text)); matrix[0][1].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 0, destinationIndex: 1)?.duration.text)); matrix[1][0].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 1, destinationIndex: 0)?.duration.text)); matrix[1][1].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 1, destinationIndex: 1)?.duration.text))") -// } -// -// Radar.logConversion(name: "conversion_event", metadata: ["data": "test"]) { (status, event) in -// if let conversionEvent = event, conversionEvent.type == .conversion { -// print("Conversion name: \(conversionEvent.conversionName!)") -// } -// -// print("Log Conversion: status = \(Radar.stringForStatus(status)); event = \(String(describing: event))") -// } + + Radar.getContext { (status, location, context) in + print("Context: status = \(Radar.stringForStatus(status)); location = \(String(describing: location)); context?.geofences = \(String(describing: context?.geofences)); context?.place = \(String(describing: context?.place)); context?.country = \(String(describing: context?.country))") + } + + // In the Radar dashboard settings + // (https://radar.com/dashboard/settings), add this to the chain + // metadata: {"mcdonalds":{"orderActive":"true"}}. + Radar.searchPlaces( + radius: 1000, + chains: ["mcdonalds"], + chainMetadata: ["orderActive": "true"], + categories: nil, + groups: nil, + limit: 10 + ) { (status, location, places) in + print("Search places: status = \(Radar.stringForStatus(status)); places = \(String(describing: places))") + } + + Radar.searchGeofences( + radius: 1000, + tags: ["store"], + metadata: nil, + limit: 10 + ) { (status, location, geofences) in + print("Search geofences: status = \(Radar.stringForStatus(status)); geofences = \(String(describing: geofences))") + } + + Radar.geocode(address: "20 jay st brooklyn") { (status, addresses) in + print("Geocode: status = \(Radar.stringForStatus(status)); coordinate = \(String(describing: addresses?.first?.coordinate))") + } + + Radar.reverseGeocode { (status, addresses) in + print("Reverse geocode: status = \(Radar.stringForStatus(status)); formattedAddress = \(String(describing: addresses?.first?.formattedAddress))") + } + + Radar.ipGeocode { (status, address, proxy) in + print("IP geocode: status = \(Radar.stringForStatus(status)); country = \(String(describing: address?.countryCode)); city = \(String(describing: address?.city)); proxy = \(proxy)") + } + + let origin = CLLocation(latitude: 40.78382, longitude: -73.97536) + let destination = CLLocation(latitude: 40.70390, longitude: -73.98670) + + + Radar.autocomplete( + query: "brooklyn", + near: origin, + layers: ["locality"], + limit: 10, + country: "US", + expandUnits:true + ) { (status, addresses) in + print("Autocomplete: status = \(Radar.stringForStatus(status)); formattedAddress = \(String(describing: addresses?.first?.formattedAddress))") + + if let address = addresses?.first { + Radar.validateAddress(address: address) { (status, address, verificationStatus) in + print("Validate address: status = \(Radar.stringForStatus(status)); address = \(String(describing: address)); verificationStatus = \(Radar.stringForVerificationStatus(verificationStatus))") + } + } + } + + Radar.autocomplete( + query: "brooklyn", + near: origin, + layers: ["locality"], + limit: 10, + country: "US" + ) { (status, addresses) in + print("Autocomplete: status = \(Radar.stringForStatus(status)); formattedAddress = \(String(describing: addresses?.first?.formattedAddress))") + } + + Radar.getDistance( + origin: origin, + destination: destination, + modes: [.foot, .car], + units: .imperial + ) { (status, routes) in + print("Distance: status = \(Radar.stringForStatus(status)); routes.car.distance.value = \(String(describing: routes?.car?.distance.value)); routes.car.distance.text = \(String(describing: routes?.car?.distance.text)); routes.car.duration.value = \(String(describing: routes?.car?.duration.value)); routes.car.duration.text = \(String(describing: routes?.car?.duration.text))") + } + + let tripOptions = RadarTripOptions(externalId: "299", destinationGeofenceTag: "store", destinationGeofenceExternalId: "123") + tripOptions.mode = .car + tripOptions.approachingThreshold = 9 + Radar.startTrip(options: tripOptions) + + var i = 0 + Radar.mockTracking( + origin: origin, + destination: destination, + mode: .car, + steps: 3, + interval: 3 + ) { (status, location, events, user) in + print("Mock track: status = \(Radar.stringForStatus(status)); location = \(String(describing: location)); events = \(String(describing: events)); user = \(String(describing: user))") + + if (i == 2) { + Radar.completeTrip() + } + + i += 1 + } + + let origins = [ + CLLocation(latitude: 40.78382, longitude: -73.97536), + CLLocation(latitude: 40.70390, longitude: -73.98670) + ] + let destinations = [ + CLLocation(latitude: 40.64189, longitude: -73.78779), + CLLocation(latitude: 35.99801, longitude: -78.94294) + ] + + Radar.getMatrix(origins: origins, destinations: destinations, mode: .car, units: .imperial) { (status, matrix) in + print("Matrix: status = \(Radar.stringForStatus(status)); matrix[0][0].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 0, destinationIndex: 0)?.duration.text)); matrix[0][1].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 0, destinationIndex: 1)?.duration.text)); matrix[1][0].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 1, destinationIndex: 0)?.duration.text)); matrix[1][1].duration.text = \(String(describing: matrix?.routeBetween(originIndex: 1, destinationIndex: 1)?.duration.text))") + } + + Radar.logConversion(name: "conversion_event", metadata: ["data": "test"]) { (status, event) in + if let conversionEvent = event, conversionEvent.type == .conversion { + print("Conversion name: \(conversionEvent.conversionName!)") + } + + print("Log Conversion: status = \(Radar.stringForStatus(status)); event = \(String(describing: event))") + } return true } From 7db587a98ee2661cec60bbfdb8c4fcdfaf50bdf5 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 28 Nov 2023 13:54:59 -0500 Subject: [PATCH 13/72] remove comment --- RadarSDK/RadarLogger.m | 1 - 1 file changed, 1 deletion(-) diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index 781f0b831..b5f35a4a5 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -75,7 +75,6 @@ - (void)logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type me - (void) logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message includeDate:(BOOL)includeDate includeBattery:(BOOL)includeBattery{ NSString *dateString = [self.dateFormatter stringFromDate:[NSDate date]]; float batteryLevel = [self.device batteryLevel]; - //append date and battery level to message if requested if (includeDate && includeBattery) { message = [NSString stringWithFormat:@"%@ | at %@ | with %2.f%% battery", message, dateString, batteryLevel*100]; } else if (includeDate) { From fa0ce67532abc945aa37f4447b6e462815ee609b Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 28 Nov 2023 13:56:49 -0500 Subject: [PATCH 14/72] remove log statement --- RadarSDK/RadarLogger.m | 1 - 1 file changed, 1 deletion(-) diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index b5f35a4a5..25eac4a7e 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -116,7 +116,6 @@ - (void)flushLocalLogs { } for (RadarLog *retrievedLog in existingLogs) { - NSLog(@"retrieved log: %@", retrievedLog.message); dispatch_async(dispatch_get_main_queue(), ^{ [Radar sendLog:retrievedLog.level type:retrievedLog.type message:retrievedLog.message]; From 6b71963b763a8c19ad77dc83e0cb2ee1cf0b614e Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 29 Nov 2023 14:57:29 -0500 Subject: [PATCH 15/72] wip save, issue with log terminate? --- RadarSDK/Radar.m | 18 ++++++- RadarSDK/RadarFileSystem.h | 1 + RadarSDK/RadarFileSystem.m | 27 ++++++++++- RadarSDK/RadarLog.m | 2 +- RadarSDK/RadarLogBuffer.h | 5 +- RadarSDK/RadarLogBuffer.m | 97 ++++++++++++++++++++++++++++++++++---- RadarSDK/RadarLogger.m | 20 +------- 7 files changed, 136 insertions(+), 34 deletions(-) diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index 90f674245..6ce0e5bc7 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -44,7 +44,10 @@ + (id)sharedInstance { + (void)initializeWithPublishableKey:(NSString *)publishableKey { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeSDKCall message:@"initialize()"]; - [[RadarLogger sharedInstance] flushLocalLogs]; + [self flushLogs]; + + [[RadarLogBuffer sharedInstance] clear]; + [[NSNotificationCenter defaultCenter] addObserver:[self sharedInstance] selector:@selector(applicationWillEnterForeground) @@ -1044,10 +1047,12 @@ + (void)writeLocalLog:(NSString *)message { } + (void) logTermination { + NSLog(@"logTermination"); [[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminated" includeDate:YES includeBattery:YES]; } + (void) logEnteringBackground { + NSLog(@"logEnteringBackground"); [[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background" includeDate:YES includeBattery:YES]; } @@ -1277,11 +1282,17 @@ + (void)flushLogs { } NSArray *flushableLogs = [[RadarLogBuffer sharedInstance] flushableLogs]; + NSUInteger pendingLogCount = [flushableLogs count]; if (pendingLogCount == 0) { return; } + NSLog(@"Syncing %lu logs", (unsigned long)pendingLogCount); + //print logs to console + // for (RadarLog *log in flushableLogs) { + // NSLog(@"log is %@", log.message); + // } // remove logs from buffer to handle multiple flushLogs calls [[RadarLogBuffer sharedInstance] removeLogsFromBuffer:pendingLogCount]; @@ -1289,10 +1300,13 @@ + (void)flushLogs { RadarSyncLogsAPICompletionHandler onComplete = ^(RadarStatus status) { // if an error occurs in syncing, add the logs back to the buffer if (status != RadarStatusSuccess) { + NSLog(@"Error syncing logs: %@", [Radar stringForStatus:status]); [[RadarLogBuffer sharedInstance] addLogsToBuffer:flushableLogs]; + }else{ + NSLog(@"Successfully synced %lu logs", (unsigned long)pendingLogCount); } }; - + [[RadarAPIClient sharedInstance] syncLogs:flushableLogs completionHandler:^(RadarStatus status) { if (onComplete) { diff --git a/RadarSDK/RadarFileSystem.h b/RadarSDK/RadarFileSystem.h index 86c3432d5..efbff5d14 100644 --- a/RadarSDK/RadarFileSystem.h +++ b/RadarSDK/RadarFileSystem.h @@ -10,6 +10,7 @@ @interface RadarFileSystem : NSObject + - (NSData *)readFileAtPath:(NSString *)filePath; - (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath; diff --git a/RadarSDK/RadarFileSystem.m b/RadarSDK/RadarFileSystem.m index bb516dc44..2f46eabda 100644 --- a/RadarSDK/RadarFileSystem.m +++ b/RadarSDK/RadarFileSystem.m @@ -11,6 +11,26 @@ @implementation RadarFileSystem +// //init temp file path +// - (instancetype)init { +// self = [super init]; +// if (self) { +// NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; +// NSString *logFileName = @"RadarTempLogs.txt"; +// self.tempFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; +// } +// return self; +// } + +// + (instancetype)sharedInstance { +// static dispatch_once_t once; +// static id sharedInstance; +// dispatch_once(&once, ^{ +// sharedInstance = [self new]; +// }); +// return sharedInstance; +// } + - (NSData *)readFileAtPath:(NSString *)filePath { __block NSData *fileData = nil; @@ -23,12 +43,15 @@ - (NSData *)readFileAtPath:(NSString *)filePath { } - (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath { - NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; + + NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; [fileCoordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:filePath] options:NSFileCoordinatorWritingForReplacing error:nil byAccessor:^(NSURL *newURL) { - [data writeToURL:newURL atomically:YES]; + [data writeToURL:newURL options:NSDataWritingAtomic error:nil]; }]; } + + - (void)deleteFileAtPath:(NSString *)filePath { NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; [fileCoordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:filePath] options:NSFileCoordinatorWritingForDeleting error:nil byAccessor:^(NSURL *newURL) { diff --git a/RadarSDK/RadarLog.m b/RadarSDK/RadarLog.m index 7f2273a0b..68559bacc 100644 --- a/RadarSDK/RadarLog.m +++ b/RadarSDK/RadarLog.m @@ -110,7 +110,7 @@ - (instancetype)initWithDictionary:(NSDictionary *)dictionary { _level = [RadarLog logLevelForString:dictionary[@"level"]]; _type = [RadarLog logTypeForString:dictionary[@"type"]]; _message = dictionary[@"message"]; - _createdAt = dictionary[@"createdAt"]; + _createdAt = [RadarUtils.isoDateFormatter dateFromString:dictionary[@"createdAt"]]; } return self; } diff --git a/RadarSDK/RadarLogBuffer.h b/RadarSDK/RadarLogBuffer.h index a8fe5978d..638dd04e5 100644 --- a/RadarSDK/RadarLogBuffer.h +++ b/RadarSDK/RadarLogBuffer.h @@ -8,18 +8,21 @@ #import #import "RadarLog.h" +#import "RadarFileSystem.h" NS_ASSUME_NONNULL_BEGIN @interface RadarLogBuffer : NSObject @property (assign, nonatomic, readonly) NSArray *flushableLogs; +@property (strong, nonatomic) NSString *logFilePath; +@property (strong, nonatomic) RadarFileSystem *fileHandler; + (instancetype)sharedInstance; - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; -- (void)purgeOldestLogs; +- (void)clear; - (void)removeLogsFromBuffer:(NSUInteger)numLogs; diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 294b582d2..094c5fe42 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -7,6 +7,7 @@ #import "RadarLogBuffer.h" #import "RadarLog.h" +#import "RadarFileSystem.h" static const int MAX_BUFFER_SIZE = 500; static const int PURGE_AMOUNT = 200; @@ -21,6 +22,10 @@ - (instancetype)init { self = [super init]; if (self) { mutableLogBuffer = [NSMutableArray new]; + NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; + NSString *logFileName = @"RadarLogs.txt"; + self.logFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; + self.fileHandler = [[RadarFileSystem alloc] init]; } return self; } @@ -35,34 +40,106 @@ + (instancetype)sharedInstance { } - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { + @synchronized (self) { + RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; + NSMutableArray *existingLogs = [self readFromFileSystem]; + NSUInteger logLength = [existingLogs count]; // purge oldest log if reached the max buffer size - NSUInteger logLength = [mutableLogBuffer count]; if (logLength >= MAX_BUFFER_SIZE) { [self purgeOldestLogs]; } - // add new log to buffer - RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; - [mutableLogBuffer addObject:radarLog]; + [existingLogs addObject:radarLog]; + [self writeToFileSystem:existingLogs]; + // [mutableLogBuffer addObject:radarLog]; + } +} + + +- (NSMutableArray *)readFromFileSystem { + NSData *fileData = [self.fileHandler readFileAtPath:self.logFilePath]; + NSMutableArray *existingLogs = [NSMutableArray array]; + if (fileData) { + NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:fileData options:0 error:nil]; + for (NSDictionary *jsonDict in jsonArray) { + RadarLog *existingLog = [[RadarLog alloc] initWithDictionary:jsonDict]; + //NSLog(@"reading log%@", existingLog.message); + [existingLogs addObject:existingLog]; + } + } + return existingLogs; +} + +- (void) writeToFileSystem:(NSMutableArray * )logs { + NSMutableArray *updatedLogsArray = [NSMutableArray array]; + for (RadarLog *log in logs) { + [updatedLogsArray addObject:[log dictionaryValue]]; + } + NSData *updatedLogData = [NSJSONSerialization dataWithJSONObject:updatedLogsArray options:0 error:nil]; + [self.fileHandler writeData:updatedLogData toFileAtPath:self.logFilePath]; } - (NSArray *)flushableLogs { - NSArray *flushableLogs = [mutableLogBuffer copy]; - return flushableLogs; + @synchronized (self) { + NSArray *existingLogsArray = [self.readFromFileSystem copy]; + // NSArray *flushableLogs = [mutableLogBuffer copy]; + // turn both arrays into sets of strings by turning each elem into a json string + // NSMutableSet *existingLogsSet = [NSMutableSet set]; + // NSMutableSet *flushableLogsSet = [NSMutableSet set]; + // for (RadarLog *log in existingLogsArray) { + // [existingLogsSet addObject:[log dictionaryValue]]; + // } + // for (RadarLog *log in flushableLogs) { + // [flushableLogsSet addObject:[log dictionaryValue]]; + // } + // find the difference between the two sets + // [flushableLogsSet minusSet:existingLogsSet]; + // [existingLogsSet minusSet:flushableLogsSet]; + // NSLog(@"mem logs size: %lu, set: %@, ", (unsigned long)[flushableLogsSet count], flushableLogsSet); + // NSLog(@"file system logs size: %lu, set: %@, ", (unsigned long)[existingLogsSet count], existingLogsSet); + + + return existingLogsArray; + } } - (void)purgeOldestLogs { // drop the oldest N logs from the buffer - [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; + //[mutableLogBuffer removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; - [mutableLogBuffer insertObject:purgeLog atIndex:0]; + //[mutableLogBuffer insertObject:purgeLog atIndex:0]; + //new version + NSMutableArray *existingLogs = [self readFromFileSystem]; + [existingLogs removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; + [existingLogs insertObject:purgeLog atIndex:0]; + [self writeToFileSystem:existingLogs]; + // [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; + // [mutableLogBuffer insertObject:purgeLog atIndex:0]; } - (void)removeLogsFromBuffer:(NSUInteger)numLogs { - [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, numLogs)]; + @synchronized (self) { + // [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, numLogs)]; + // new version + NSMutableArray *existingLogs = [self readFromFileSystem]; + [existingLogs removeObjectsInRange:NSMakeRange(0, numLogs)]; + [self writeToFileSystem:existingLogs]; + } } - (void)addLogsToBuffer:(NSArray *)logs { - [mutableLogBuffer addObjectsFromArray:logs]; + @synchronized (self) { + // [mutableLogBuffer addObjectsFromArray:logs]; + NSMutableArray *existingLogs = [self readFromFileSystem]; + [existingLogs addObjectsFromArray:logs]; + [self writeToFileSystem:existingLogs]; + } +} + +-(void)clear { + @synchronized (self) { + // [mutableLogBuffer removeAllObjects]; + [self.fileHandler deleteFileAtPath:self.logFilePath]; + } } @end diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index 25eac4a7e..348a403a3 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -82,26 +82,10 @@ - (void) logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type m } else if (includeBattery) { message = [NSString stringWithFormat:@"%@ | with %2.f%% battery", message, batteryLevel*100]; } - RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; - NSData *fileData = [self.fileHandler readFileAtPath:self.logFilePath]; - NSMutableArray *existingLogs = [NSMutableArray array]; - if (fileData) { - NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:fileData options:0 error:nil]; - for (NSDictionary *jsonDict in jsonArray) { - RadarLog *existingLog = [[RadarLog alloc] initWithDictionary:jsonDict]; - [existingLogs addObject:existingLog]; - } - } - [existingLogs addObject:radarLog]; - - NSMutableArray *updatedLogsArray = [NSMutableArray array]; - for (RadarLog *log in existingLogs) { - [updatedLogsArray addObject:[log dictionaryValue]]; - } + [self logWithLevel:level type:type message:message]; - NSData *updatedLogData = [NSJSONSerialization dataWithJSONObject:updatedLogsArray options:0 error:nil]; - [self.fileHandler writeData:updatedLogData toFileAtPath:self.logFilePath]; + } - (void)flushLocalLogs { From cfb80027735040cba82b0405bbe69cf82be1e3b3 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 29 Nov 2023 15:13:36 -0500 Subject: [PATCH 16/72] added in unit tests --- RadarSDKTests/RadarSDKTests.m | 63 ++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 2835500f8..b1bf5dba2 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -18,13 +18,18 @@ #import "RadarPermissionsHelperMock.h" #import "RadarTestUtils.h" #import "RadarTripOptions.h" +#import "RadarFileSystem.h" +#import "../RadarSDK/RadarLogBuffer.h" + @interface RadarSDKTests : XCTestCase @property (nonnull, strong, nonatomic) RadarAPIHelperMock *apiHelperMock; @property (nonnull, strong, nonatomic) CLLocationManagerMock *locationManagerMock; @property (nonnull, strong, nonatomic) RadarPermissionsHelperMock *permissionsHelperMock; - +@property (nonatomic, strong) RadarFileSystem *fileSystem; +@property (nonatomic, strong) NSString *testFilePath; +@property (nonatomic, strong) RadarLogBuffer *logBuffer; @end @implementation RadarSDKTests @@ -291,9 +296,16 @@ - (void)setUp { self.locationManagerMock.delegate = [RadarLocationManager sharedInstance]; [RadarLocationManager sharedInstance].lowPowerLocationManager = self.locationManagerMock; [RadarLocationManager sharedInstance].permissionsHelper = self.permissionsHelperMock; + self.fileSystem = [[RadarFileSystem alloc] init]; + self.testFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"testfile"]; + self.logBuffer = [RadarLogBuffer sharedInstance]; + [self.logBuffer clear]; } - (void)tearDown { + [[NSFileManager defaultManager] removeItemAtPath:self.testFilePath error:nil]; + [self.logBuffer clear]; + [super tearDown]; } - (void)test_Radar_initialize { @@ -1395,4 +1407,53 @@ - (void)test_RadarTrackingOptions_isEqual { XCTAssertNotEqualObjects(options, @"foo"); } +- (void)testWriteAndRead { + NSData *originalData = [@"Test data" dataUsingEncoding:NSUTF8StringEncoding]; + [self.fileSystem writeData:originalData toFileAtPath:self.testFilePath]; + NSData *originalData2 = [@"Newer Test data" dataUsingEncoding:NSUTF8StringEncoding]; + [self.fileSystem writeData:originalData2 toFileAtPath:self.testFilePath]; + NSData *readData = [self.fileSystem readFileAtPath:self.testFilePath]; + XCTAssertEqualObjects(originalData2, readData, @"Data read from file should be equal to original data"); +} + +- (void)testDeleteFile { + NSData *originalData = [@"Test data" dataUsingEncoding:NSUTF8StringEncoding]; + [self.fileSystem writeData:originalData toFileAtPath:self.testFilePath]; + [self.fileSystem deleteFileAtPath:self.testFilePath]; + NSData *readData = [self.fileSystem readFileAtPath:self.testFilePath]; + XCTAssertNil(readData, @"Data read from file should be nil after file is deleted"); +} + +- (void)testRadarLogBufferWriteAndFlushableLogs { + RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; + [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; + [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; + NSArray *logs = [self.logBuffer flushableLogs]; + XCTAssertEqual(logs.count, 2); + XCTAssertEqualObjects(logs.firstObject.message, @"Test message 1"); + XCTAssertEqualObjects(logs.lastObject.message, @"Test message 2"); +} + +- (void)testRadarLogBufferRemoveLogsFromBuffer { + RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; + [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; + [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; + [self.logBuffer removeLogsFromBuffer:2]; + NSArray *logs = [self.logBuffer flushableLogs]; + XCTAssertEqual(logs.count, 0); +} + +- (void)testRadarLogBufferAddLogsToBuffrer { + RadarLog *log1 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; + RadarLog *log2 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; + [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; + [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; + [self.logBuffer addLogsToBuffer:@[log1, log2]]; + NSArray *logs = [self.logBuffer flushableLogs]; + XCTAssertEqual(logs.count, 4); + XCTAssertEqualObjects(logs.lastObject.message, @"Test message 2"); +} + + + @end From ace1d3b8428211d3a60b77211bd4aff4c4cf86e3 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 30 Nov 2023 15:44:07 -0500 Subject: [PATCH 17/72] wip but looks correct --- RadarSDK/Radar.m | 22 ++++-- RadarSDK/RadarFileSystem.h | 2 + RadarSDK/RadarFileSystem.m | 36 +++++----- RadarSDK/RadarLogBuffer.h | 5 ++ RadarSDK/RadarLogBuffer.m | 132 +++++++++++++++++++++++----------- RadarSDKTests/RadarSDKTests.m | 39 ++++++++-- 6 files changed, 165 insertions(+), 71 deletions(-) diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index 6ce0e5bc7..9925d600f 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1047,13 +1047,17 @@ + (void)writeLocalLog:(NSString *)message { } + (void) logTermination { + + //[[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminated" includeDate:YES includeBattery:YES]; + [[RadarLogBuffer sharedInstance] append:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminated" ]; NSLog(@"logTermination"); - [[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminated" includeDate:YES includeBattery:YES]; } + (void) logEnteringBackground { NSLog(@"logEnteringBackground"); - [[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background" includeDate:YES includeBattery:YES]; + //[[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background" includeDate:YES includeBattery:YES]; + [[RadarLogBuffer sharedInstance] append:RadarLogLevelInfo type:RadarLogTypeNone message:@"App backgrounded" ]; + [[RadarLogBuffer sharedInstance] flushToPersistentStorage ]; } + (void) logResignActive { @@ -1290,9 +1294,13 @@ + (void)flushLogs { } NSLog(@"Syncing %lu logs", (unsigned long)pendingLogCount); //print logs to console - // for (RadarLog *log in flushableLogs) { - // NSLog(@"log is %@", log.message); - // } + for (RadarLog *log in flushableLogs) { + //print log fields to console + + NSLog(@"log is %@", log.message); + } + + // remove logs from buffer to handle multiple flushLogs calls [[RadarLogBuffer sharedInstance] removeLogsFromBuffer:pendingLogCount]; @@ -1307,6 +1315,10 @@ + (void)flushLogs { } }; + //WHY DO WE NEED TO DO THIS? THERE IS PROB A BUG + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"message != nil"]; + flushableLogs = [flushableLogs filteredArrayUsingPredicate:predicate]; + [[RadarAPIClient sharedInstance] syncLogs:flushableLogs completionHandler:^(RadarStatus status) { if (onComplete) { diff --git a/RadarSDK/RadarFileSystem.h b/RadarSDK/RadarFileSystem.h index efbff5d14..784ae695a 100644 --- a/RadarSDK/RadarFileSystem.h +++ b/RadarSDK/RadarFileSystem.h @@ -17,4 +17,6 @@ - (void)deleteFileAtPath:(NSString *)filePath; +- (void)appendData:(NSData *)data toFileAtPath:(NSString *)filePath ; + @end diff --git a/RadarSDK/RadarFileSystem.m b/RadarSDK/RadarFileSystem.m index 2f46eabda..0a31b3ebc 100644 --- a/RadarSDK/RadarFileSystem.m +++ b/RadarSDK/RadarFileSystem.m @@ -11,25 +11,7 @@ @implementation RadarFileSystem -// //init temp file path -// - (instancetype)init { -// self = [super init]; -// if (self) { -// NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; -// NSString *logFileName = @"RadarTempLogs.txt"; -// self.tempFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; -// } -// return self; -// } - -// + (instancetype)sharedInstance { -// static dispatch_once_t once; -// static id sharedInstance; -// dispatch_once(&once, ^{ -// sharedInstance = [self new]; -// }); -// return sharedInstance; -// } + - (NSData *)readFileAtPath:(NSString *)filePath { __block NSData *fileData = nil; @@ -44,12 +26,26 @@ - (NSData *)readFileAtPath:(NSString *)filePath { - (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath { - NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; + NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; [fileCoordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:filePath] options:NSFileCoordinatorWritingForReplacing error:nil byAccessor:^(NSURL *newURL) { [data writeToURL:newURL options:NSDataWritingAtomic error:nil]; }]; } +- (void)appendData:(NSData *)data toFileAtPath:(NSString *)filePath { + NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; + //TODO: not very sure if the option is correct, need to check + [fileCoordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:filePath] options:NSFileCoordinatorWritingForReplacing error:nil byAccessor:^(NSURL *newURL) { + NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingToURL:newURL error:nil]; + if (!fileHandle) { + [[NSFileManager defaultManager] createFileAtPath:[newURL path] contents:nil attributes:nil]; + fileHandle = [NSFileHandle fileHandleForWritingToURL:newURL error:nil]; + } + [fileHandle seekToEndOfFile]; + [fileHandle writeData:data]; + [fileHandle closeFile]; + }]; +} - (void)deleteFileAtPath:(NSString *)filePath { diff --git a/RadarSDK/RadarLogBuffer.h b/RadarSDK/RadarLogBuffer.h index 638dd04e5..dd06a492c 100644 --- a/RadarSDK/RadarLogBuffer.h +++ b/RadarSDK/RadarLogBuffer.h @@ -17,11 +17,16 @@ NS_ASSUME_NONNULL_BEGIN @property (assign, nonatomic, readonly) NSArray *flushableLogs; @property (strong, nonatomic) NSString *logFilePath; @property (strong, nonatomic) RadarFileSystem *fileHandler; +@property (nonatomic, strong) NSTimer *timer; + (instancetype)sharedInstance; - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; +- (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; + +- (void)flushToPersistentStorage; + - (void)clear; - (void)removeLogsFromBuffer:(NSUInteger)numLogs; diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 094c5fe42..3abce17a7 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -13,6 +13,7 @@ static const int PURGE_AMOUNT = 200; static NSString *const kPurgedLogLine = @"----- purged oldest logs -----"; +static NSString *const kdelimiter = @"\?"; @implementation RadarLogBuffer { NSMutableArray *mutableLogBuffer; @@ -26,10 +27,12 @@ - (instancetype)init { NSString *logFileName = @"RadarLogs.txt"; self.logFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; self.fileHandler = [[RadarFileSystem alloc] init]; + _timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(flushToPersistentStorage) userInfo:nil repeats:YES]; } return self; } + + (instancetype)sharedInstance { static dispatch_once_t once; static id sharedInstance; @@ -40,49 +43,104 @@ + (instancetype)sharedInstance { } - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { - @synchronized (self) { RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; - NSMutableArray *existingLogs = [self readFromFileSystem]; - NSUInteger logLength = [existingLogs count]; - // purge oldest log if reached the max buffer size - if (logLength >= MAX_BUFFER_SIZE) { - [self purgeOldestLogs]; - } - [existingLogs addObject:radarLog]; - [self writeToFileSystem:existingLogs]; - // [mutableLogBuffer addObject:radarLog]; + [mutableLogBuffer addObject:radarLog]; +} + + +- (void)flushToPersistentStorage { + @synchronized (self) { + NSArray *flushableLogs = [mutableLogBuffer copy]; + [self addLogsToBuffer:flushableLogs]; + [mutableLogBuffer removeAllObjects]; } } +// //less performant version, but checks for size limits and purges if needed. Should be used by default. +// - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { +// @synchronized (self) { +// RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:[self strip:message]]; +// NSMutableArray *existingLogs = [self readFromFileSystem]; +// NSUInteger logLength = [existingLogs count]; +// // purge oldest log if reached the max buffer size +// if (logLength >= MAX_BUFFER_SIZE) { +// [self purgeOldestLogs]; +// } +// [existingLogs addObject:radarLog]; +// [self writeToFileSystem:existingLogs]; +// } +// } + + - (NSMutableArray *)readFromFileSystem { NSData *fileData = [self.fileHandler readFileAtPath:self.logFilePath]; - NSMutableArray *existingLogs = [NSMutableArray array]; - if (fileData) { - NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:fileData options:0 error:nil]; - for (NSDictionary *jsonDict in jsonArray) { - RadarLog *existingLog = [[RadarLog alloc] initWithDictionary:jsonDict]; - //NSLog(@"reading log%@", existingLog.message); - [existingLogs addObject:existingLog]; - } - } - return existingLogs; + NSString *fileString = [[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding]; + return [self jsonToLogs:fileString]; } - (void) writeToFileSystem:(NSMutableArray * )logs { - NSMutableArray *updatedLogsArray = [NSMutableArray array]; + NSString *updatedLogString = [self logsToJSON:logs]; + NSData *updatedLogData = [updatedLogString dataUsingEncoding:NSUTF8StringEncoding]; + [self.fileHandler writeData:updatedLogData toFileAtPath:self.logFilePath]; +} + +- (void) append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { + @synchronized (self) { + RadarLog *log = [[RadarLog alloc] initWithLevel:level type:type message:[self strip:message]]; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[log dictionaryValue] options:0 error:nil]; + NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + NSString *logString = [NSString stringWithFormat:@"%@%@",kdelimiter ,jsonString]; + NSData *logData = [logString dataUsingEncoding:NSUTF8StringEncoding]; + [self.fileHandler appendData:logData toFileAtPath:self.logFilePath]; + } +} + +//strip a message of a log of delimiter +- (NSString *)strip:(NSString *)message { + return [message stringByReplacingOccurrencesOfString:kdelimiter withString:@""]; +} + +- (NSString *)logsToJSON:(NSMutableArray *)logs { + NSMutableArray *jsonStrings = [NSMutableArray array]; for (RadarLog *log in logs) { - [updatedLogsArray addObject:[log dictionaryValue]]; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[log dictionaryValue] options:0 error:nil]; + NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + [jsonStrings addObject:jsonString]; } - NSData *updatedLogData = [NSJSONSerialization dataWithJSONObject:updatedLogsArray options:0 error:nil]; - [self.fileHandler writeData:updatedLogData toFileAtPath:self.logFilePath]; + return [jsonStrings componentsJoinedByString:kdelimiter]; +} + +- (NSMutableArray *)jsonToLogs:(NSString *)json { + + if([json length] == 0){ + return [NSMutableArray array]; + } + if([json hasPrefix:kdelimiter]){ + json = [json substringFromIndex:1]; + } + + NSMutableArray *logs = [NSMutableArray array]; + NSArray *jsonStrings = [json componentsSeparatedByString:kdelimiter]; + for (NSString *jsonString in jsonStrings) { + NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; + NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil]; + RadarLog *log = [[RadarLog alloc] initWithDictionary:jsonDict]; + if(log){ + [logs addObject:log]; + } + } + return logs; } - (NSArray *)flushableLogs { @synchronized (self) { + [self flushToPersistentStorage]; NSArray *existingLogsArray = [self.readFromFileSystem copy]; + + // NSArray *flushableLogs = [mutableLogBuffer copy]; - // turn both arrays into sets of strings by turning each elem into a json string + // turn both arrays into sets of strings by turning each elem into a json string // NSMutableSet *existingLogsSet = [NSMutableSet set]; // NSMutableSet *flushableLogsSet = [NSMutableSet set]; // for (RadarLog *log in existingLogsArray) { @@ -96,25 +154,11 @@ - (void) writeToFileSystem:(NSMutableArray * )logs { // [existingLogsSet minusSet:flushableLogsSet]; // NSLog(@"mem logs size: %lu, set: %@, ", (unsigned long)[flushableLogsSet count], flushableLogsSet); // NSLog(@"file system logs size: %lu, set: %@, ", (unsigned long)[existingLogsSet count], existingLogsSet); - - + return existingLogsArray; } } -- (void)purgeOldestLogs { - // drop the oldest N logs from the buffer - //[mutableLogBuffer removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; - RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; - //[mutableLogBuffer insertObject:purgeLog atIndex:0]; - //new version - NSMutableArray *existingLogs = [self readFromFileSystem]; - [existingLogs removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; - [existingLogs insertObject:purgeLog atIndex:0]; - [self writeToFileSystem:existingLogs]; - // [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; - // [mutableLogBuffer insertObject:purgeLog atIndex:0]; -} - (void)removeLogsFromBuffer:(NSUInteger)numLogs { @synchronized (self) { @@ -128,9 +172,15 @@ - (void)removeLogsFromBuffer:(NSUInteger)numLogs { - (void)addLogsToBuffer:(NSArray *)logs { @synchronized (self) { - // [mutableLogBuffer addObjectsFromArray:logs]; NSMutableArray *existingLogs = [self readFromFileSystem]; [existingLogs addObjectsFromArray:logs]; + NSUInteger logLength = [existingLogs count]; + if (logLength >= MAX_BUFFER_SIZE) { + [existingLogs removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; + RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; + [existingLogs insertObject:purgeLog atIndex:0]; + } + [self writeToFileSystem:existingLogs]; } } diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index b1bf5dba2..d963638ce 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -1407,7 +1407,7 @@ - (void)test_RadarTrackingOptions_isEqual { XCTAssertNotEqualObjects(options, @"foo"); } -- (void)testWriteAndRead { +- (void)test_RadarFileSystem_WriteAndRead { NSData *originalData = [@"Test data" dataUsingEncoding:NSUTF8StringEncoding]; [self.fileSystem writeData:originalData toFileAtPath:self.testFilePath]; NSData *originalData2 = [@"Newer Test data" dataUsingEncoding:NSUTF8StringEncoding]; @@ -1416,7 +1416,18 @@ - (void)testWriteAndRead { XCTAssertEqualObjects(originalData2, readData, @"Data read from file should be equal to original data"); } -- (void)testDeleteFile { +- (void)test_RadarFileSystem_Append { + NSData *originalData = [@"Test data" dataUsingEncoding:NSUTF8StringEncoding]; + [self.fileSystem writeData:originalData toFileAtPath:self.testFilePath]; + NSData *appendData = [@"Newer Test data" dataUsingEncoding:NSUTF8StringEncoding]; + [self.fileSystem appendData:appendData toFileAtPath:self.testFilePath]; + NSData *readData = [self.fileSystem readFileAtPath:self.testFilePath]; + NSString *readString = [[NSString alloc] initWithData:readData encoding:NSUTF8StringEncoding]; + NSString *expectedString = @"Test dataNewer Test data"; + XCTAssertEqualObjects(readString, expectedString, @"Data read from file should be equal to original data"); +} + +- (void)test_RadarFileSystem_DeleteFile { NSData *originalData = [@"Test data" dataUsingEncoding:NSUTF8StringEncoding]; [self.fileSystem writeData:originalData toFileAtPath:self.testFilePath]; [self.fileSystem deleteFileAtPath:self.testFilePath]; @@ -1428,16 +1439,23 @@ - (void)testRadarLogBufferWriteAndFlushableLogs { RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; + [self.logBuffer flushToPersistentStorage]; NSArray *logs = [self.logBuffer flushableLogs]; XCTAssertEqual(logs.count, 2); XCTAssertEqualObjects(logs.firstObject.message, @"Test message 1"); XCTAssertEqualObjects(logs.lastObject.message, @"Test message 2"); -} + [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 3"]; + NSArray *newLogs = [self.logBuffer flushableLogs]; + XCTAssertEqual(newLogs.count, 3); + XCTAssertEqualObjects(newLogs.firstObject.message, @"Test message 1"); + XCTAssertEqualObjects(newLogs.lastObject.message, @"Test message 3"); +} - (void)testRadarLogBufferRemoveLogsFromBuffer { RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; - [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; + [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; + [self.logBuffer flushToPersistentStorage]; [self.logBuffer removeLogsFromBuffer:2]; NSArray *logs = [self.logBuffer flushableLogs]; XCTAssertEqual(logs.count, 0); @@ -1447,13 +1465,24 @@ - (void)testRadarLogBufferAddLogsToBuffrer { RadarLog *log1 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; RadarLog *log2 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; - [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; + [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; + [self.logBuffer flushToPersistentStorage]; [self.logBuffer addLogsToBuffer:@[log1, log2]]; NSArray *logs = [self.logBuffer flushableLogs]; XCTAssertEqual(logs.count, 4); XCTAssertEqualObjects(logs.lastObject.message, @"Test message 2"); } +- (void)test_RadarLogBuffer_append { + [self.logBuffer append:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; + [self.logBuffer append:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; + NSArray *logs = [self.logBuffer flushableLogs]; + XCTAssertEqual(logs.count, 2); + XCTAssertEqualObjects(logs.firstObject.message, @"Test message 1"); + XCTAssertEqualObjects(logs.lastObject.message, @"Test message 2"); + +} + @end From d298726455424d6029b814c0f07b70a4158ad7ef Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 30 Nov 2023 16:50:51 -0500 Subject: [PATCH 18/72] cleanup --- RadarSDK/RadarLogBuffer.m | 1 + RadarSDK/RadarLogger.m | 31 ------------------------------- 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 3abce17a7..2dc46a1fa 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -17,6 +17,7 @@ @implementation RadarLogBuffer { NSMutableArray *mutableLogBuffer; + } - (instancetype)init { diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index 348a403a3..6b8e4c533 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -88,37 +88,6 @@ - (void) logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type m } -- (void)flushLocalLogs { - NSData *fileData = [self.fileHandler readFileAtPath:self.logFilePath]; - if (fileData) { - NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:fileData options:0 error:nil]; - NSMutableArray *existingLogs = [NSMutableArray array]; - - for (NSDictionary *jsonDict in jsonArray) { - RadarLog *existingLog = [[RadarLog alloc] initWithDictionary:jsonDict]; - [existingLogs addObject:existingLog]; - } - - for (RadarLog *retrievedLog in existingLogs) { - - dispatch_async(dispatch_get_main_queue(), ^{ - [Radar sendLog:retrievedLog.level type:retrievedLog.type message:retrievedLog.message]; - - RadarLogLevel logLevel = [RadarSettings logLevel]; - if (logLevel >= retrievedLog.level) { - NSString *log = [NSString stringWithFormat:@"%@ | backgroundTimeRemaining = %g", retrievedLog.message, [RadarUtils backgroundTimeRemaining]]; - - os_log(OS_LOG_DEFAULT, "%@", log); - - [[RadarDelegateHolder sharedInstance] didLogMessage:log]; - } - }); - } - - [self.fileHandler deleteFileAtPath:self.logFilePath]; - } -} - @end From 2f2f886ce6dfd8716c7053003b1e4ae9038fb73e Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Fri, 1 Dec 2023 13:49:19 -0500 Subject: [PATCH 19/72] fixed bug and cleaned up --- RadarSDK/Radar.m | 27 ++------- RadarSDK/RadarLogBuffer.m | 106 ++++++++++++---------------------- RadarSDK/RadarLogger.h | 8 +-- RadarSDK/RadarLogger.m | 48 +++++++-------- RadarSDKTests/RadarSDKTests.m | 30 ++++++++-- 5 files changed, 90 insertions(+), 129 deletions(-) diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index 9925d600f..e8010220b 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1042,26 +1042,26 @@ + (void)setLogLevel:(RadarLogLevel)level { } + (void)writeLocalLog:(NSString *)message { - [[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:message]; + [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:message]; } + (void) logTermination { - //[[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminated" includeDate:YES includeBattery:YES]; - [[RadarLogBuffer sharedInstance] append:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminated" ]; + [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminated" includeDate:YES includeBattery:YES append:YES]; + //[[RadarLogBuffer sharedInstance] append:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminated" ]; NSLog(@"logTermination"); } + (void) logEnteringBackground { NSLog(@"logEnteringBackground"); - //[[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background" includeDate:YES includeBattery:YES]; - [[RadarLogBuffer sharedInstance] append:RadarLogLevelInfo type:RadarLogTypeNone message:@"App backgrounded" ]; + [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background" includeDate:YES includeBattery:YES append:YES]; + //[[RadarLogBuffer sharedInstance] append:RadarLogLevelInfo type:RadarLogTypeNone message:@"App backgrounded" ]; [[RadarLogBuffer sharedInstance] flushToPersistentStorage ]; } + (void) logResignActive { - [[RadarLogger sharedInstance] logWithLevelToFileSystem:RadarLogLevelInfo type:RadarLogTypeNone message:@"App resigning active" includeDate:YES includeBattery:YES]; + [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App resigning active" includeDate:YES includeBattery:YES]; } @@ -1292,15 +1292,6 @@ + (void)flushLogs { if (pendingLogCount == 0) { return; } - NSLog(@"Syncing %lu logs", (unsigned long)pendingLogCount); - //print logs to console - for (RadarLog *log in flushableLogs) { - //print log fields to console - - NSLog(@"log is %@", log.message); - } - - // remove logs from buffer to handle multiple flushLogs calls [[RadarLogBuffer sharedInstance] removeLogsFromBuffer:pendingLogCount]; @@ -1308,16 +1299,10 @@ + (void)flushLogs { RadarSyncLogsAPICompletionHandler onComplete = ^(RadarStatus status) { // if an error occurs in syncing, add the logs back to the buffer if (status != RadarStatusSuccess) { - NSLog(@"Error syncing logs: %@", [Radar stringForStatus:status]); [[RadarLogBuffer sharedInstance] addLogsToBuffer:flushableLogs]; - }else{ - NSLog(@"Successfully synced %lu logs", (unsigned long)pendingLogCount); } }; - //WHY DO WE NEED TO DO THIS? THERE IS PROB A BUG - NSPredicate *predicate = [NSPredicate predicateWithFormat:@"message != nil"]; - flushableLogs = [flushableLogs filteredArrayUsingPredicate:predicate]; [[RadarAPIClient sharedInstance] syncLogs:flushableLogs completionHandler:^(RadarStatus status) { diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 2dc46a1fa..08b95d721 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -9,15 +9,15 @@ #import "RadarLog.h" #import "RadarFileSystem.h" -static const int MAX_BUFFER_SIZE = 500; +static const int MAX_PERSISTED_BUFFER_SIZE = 500; +static const int MAX_MEMORY_BUFFER_SIZE = 200; static const int PURGE_AMOUNT = 200; static NSString *const kPurgedLogLine = @"----- purged oldest logs -----"; -static NSString *const kdelimiter = @"\?"; +static NSString *const kDelimiter = @"\?"; @implementation RadarLogBuffer { NSMutableArray *mutableLogBuffer; - } - (instancetype)init { @@ -44,8 +44,12 @@ + (instancetype)sharedInstance { } - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { - RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; + RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:[self strip:message]]; [mutableLogBuffer addObject:radarLog]; + NSUInteger logLength = [mutableLogBuffer count]; + if (logLength >= MAX_MEMORY_BUFFER_SIZE) { + [self flushToPersistentStorage]; + } } @@ -58,22 +62,6 @@ - (void)flushToPersistentStorage { } -// //less performant version, but checks for size limits and purges if needed. Should be used by default. -// - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { -// @synchronized (self) { -// RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:[self strip:message]]; -// NSMutableArray *existingLogs = [self readFromFileSystem]; -// NSUInteger logLength = [existingLogs count]; -// // purge oldest log if reached the max buffer size -// if (logLength >= MAX_BUFFER_SIZE) { -// [self purgeOldestLogs]; -// } -// [existingLogs addObject:radarLog]; -// [self writeToFileSystem:existingLogs]; -// } -// } - - - (NSMutableArray *)readFromFileSystem { NSData *fileData = [self.fileHandler readFileAtPath:self.logFilePath]; NSString *fileString = [[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding]; @@ -88,18 +76,18 @@ - (void) writeToFileSystem:(NSMutableArray * )logs { - (void) append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { @synchronized (self) { - RadarLog *log = [[RadarLog alloc] initWithLevel:level type:type message:[self strip:message]]; - NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[log dictionaryValue] options:0 error:nil]; - NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; - NSString *logString = [NSString stringWithFormat:@"%@%@",kdelimiter ,jsonString]; - NSData *logData = [logString dataUsingEncoding:NSUTF8StringEncoding]; - [self.fileHandler appendData:logData toFileAtPath:self.logFilePath]; + RadarLog *log = [[RadarLog alloc] initWithLevel:level type:type message:[self strip:message]]; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[log dictionaryValue] options:0 error:nil]; + NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + NSString *logString = [NSString stringWithFormat:@"%@%@",kDelimiter ,jsonString]; + NSData *logData = [logString dataUsingEncoding:NSUTF8StringEncoding]; + [self.fileHandler appendData:logData toFileAtPath:self.logFilePath]; } } //strip a message of a log of delimiter - (NSString *)strip:(NSString *)message { - return [message stringByReplacingOccurrencesOfString:kdelimiter withString:@""]; + return [message stringByReplacingOccurrencesOfString:kDelimiter withString:@""]; } - (NSString *)logsToJSON:(NSMutableArray *)logs { @@ -109,7 +97,7 @@ - (NSString *)logsToJSON:(NSMutableArray *)logs { NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; [jsonStrings addObject:jsonString]; } - return [jsonStrings componentsJoinedByString:kdelimiter]; + return [jsonStrings componentsJoinedByString:kDelimiter]; } - (NSMutableArray *)jsonToLogs:(NSString *)json { @@ -117,17 +105,17 @@ - (NSString *)logsToJSON:(NSMutableArray *)logs { if([json length] == 0){ return [NSMutableArray array]; } - if([json hasPrefix:kdelimiter]){ + if([json hasPrefix:kDelimiter]){ json = [json substringFromIndex:1]; } NSMutableArray *logs = [NSMutableArray array]; - NSArray *jsonStrings = [json componentsSeparatedByString:kdelimiter]; + NSArray *jsonStrings = [json componentsSeparatedByString:kDelimiter]; for (NSString *jsonString in jsonStrings) { NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil]; RadarLog *log = [[RadarLog alloc] initWithDictionary:jsonDict]; - if(log){ + if(log && log.message){ [logs addObject:log]; } } @@ -136,60 +124,38 @@ - (NSString *)logsToJSON:(NSMutableArray *)logs { - (NSArray *)flushableLogs { @synchronized (self) { - [self flushToPersistentStorage]; - NSArray *existingLogsArray = [self.readFromFileSystem copy]; - - - // NSArray *flushableLogs = [mutableLogBuffer copy]; - // turn both arrays into sets of strings by turning each elem into a json string - // NSMutableSet *existingLogsSet = [NSMutableSet set]; - // NSMutableSet *flushableLogsSet = [NSMutableSet set]; - // for (RadarLog *log in existingLogsArray) { - // [existingLogsSet addObject:[log dictionaryValue]]; - // } - // for (RadarLog *log in flushableLogs) { - // [flushableLogsSet addObject:[log dictionaryValue]]; - // } - // find the difference between the two sets - // [flushableLogsSet minusSet:existingLogsSet]; - // [existingLogsSet minusSet:flushableLogsSet]; - // NSLog(@"mem logs size: %lu, set: %@, ", (unsigned long)[flushableLogsSet count], flushableLogsSet); - // NSLog(@"file system logs size: %lu, set: %@, ", (unsigned long)[existingLogsSet count], existingLogsSet); - - return existingLogsArray; + [self flushToPersistentStorage]; + NSArray *existingLogsArray = [self.readFromFileSystem copy]; + return existingLogsArray; } } - (void)removeLogsFromBuffer:(NSUInteger)numLogs { @synchronized (self) { - // [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, numLogs)]; - // new version - NSMutableArray *existingLogs = [self readFromFileSystem]; - [existingLogs removeObjectsInRange:NSMakeRange(0, numLogs)]; - [self writeToFileSystem:existingLogs]; - } + NSMutableArray *existingLogs = [self readFromFileSystem]; + [existingLogs removeObjectsInRange:NSMakeRange(0, numLogs)]; + [self writeToFileSystem:existingLogs]; + } } - (void)addLogsToBuffer:(NSArray *)logs { @synchronized (self) { - NSMutableArray *existingLogs = [self readFromFileSystem]; - [existingLogs addObjectsFromArray:logs]; - NSUInteger logLength = [existingLogs count]; - if (logLength >= MAX_BUFFER_SIZE) { - [existingLogs removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; - RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; - [existingLogs insertObject:purgeLog atIndex:0]; - } - - [self writeToFileSystem:existingLogs]; + NSMutableArray *existingLogs = [self readFromFileSystem]; + [existingLogs addObjectsFromArray:logs]; + NSUInteger logLength = [existingLogs count]; + if (logLength >= MAX_PERSISTED_BUFFER_SIZE) { + [existingLogs removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; + RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; + [existingLogs insertObject:purgeLog atIndex:0]; + } + [self writeToFileSystem:existingLogs]; } } -(void)clear { @synchronized (self) { - // [mutableLogBuffer removeAllObjects]; - [self.fileHandler deleteFileAtPath:self.logFilePath]; + [self.fileHandler deleteFileAtPath:self.logFilePath]; } } diff --git a/RadarSDK/RadarLogger.h b/RadarSDK/RadarLogger.h index b089e68b7..d8f166ee3 100644 --- a/RadarSDK/RadarLogger.h +++ b/RadarSDK/RadarLogger.h @@ -22,11 +22,9 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)sharedInstance; - (void)logWithLevel:(RadarLogLevel)level message:(NSString *)message; - (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; -- (void)logWithLevelToFileSystem:(RadarLogLevel)level message:(NSString *)message; -- (void)logWithLevelToFileSystem:(RadarLogLevel)level message:(NSString *)message includeDate:(BOOL)includeDate includeBattery:(BOOL)includeBattery; -- (void)logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; -- (void)logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message includeDate:(BOOL)includeDate includeBattery:(BOOL)includeBattery; -- (void)flushLocalLogs; +- (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message includeDate:(BOOL)includeDate includeBattery:(BOOL)includeBattery; +- (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message includeDate:(BOOL)includeDate includeBattery:(BOOL)includeBattery append:(BOOL)append; + @end NS_ASSUME_NONNULL_END diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index 6b8e4c533..4c8916b42 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -13,6 +13,7 @@ #import #import "RadarFileSystem.h" #import "RadarLog.h" +#import "RadarLogBuffer.h" @implementation RadarLogger @@ -46,34 +47,15 @@ - (void)logWithLevel:(RadarLogLevel)level message:(NSString *)message { } - (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { - dispatch_async(dispatch_get_main_queue(), ^{ - [Radar sendLog:level type:type message:message]; - - RadarLogLevel logLevel = [RadarSettings logLevel]; - if (logLevel >= level) { - NSString *log = [NSString stringWithFormat:@"%@ | backgroundTimeRemaining = %g", message, [RadarUtils backgroundTimeRemaining]]; - - os_log(OS_LOG_DEFAULT, "%@", log); - - [[RadarDelegateHolder sharedInstance] didLogMessage:log]; - } - }); -} - -- (void) logWithLevelToFileSystem:(RadarLogLevel)level message:(NSString *)message { - [self logWithLevelToFileSystem:level type:RadarLogTypeNone message:message includeDate:NO includeBattery:NO]; + [self logWithLevel:level type:type message:message includeDate:NO includeBattery:NO]; } -- (void)logWithLevelToFileSystem:(RadarLogLevel)level message:(NSString *)message includeDate:(BOOL)includeDate includeBattery:(BOOL)includeBattery{ - [self logWithLevelToFileSystem:level type:RadarLogTypeNone message:message includeDate:includeDate includeBattery:includeBattery]; +- (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message includeDate:(BOOL)includeDate includeBattery:(BOOL)includeBattery{ + [self logWithLevel:level type:type message:message includeDate:includeDate includeBattery:includeBattery append:NO]; } -- (void)logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message{ - [self logWithLevelToFileSystem:level type:type message:message includeDate:NO includeBattery:NO]; -} - -- (void) logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message includeDate:(BOOL)includeDate includeBattery:(BOOL)includeBattery{ - NSString *dateString = [self.dateFormatter stringFromDate:[NSDate date]]; +- (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message includeDate:(BOOL)includeDate includeBattery:(BOOL)includeBattery append:(BOOL)append{ + NSString *dateString = [self.dateFormatter stringFromDate:[NSDate date]]; float batteryLevel = [self.device batteryLevel]; if (includeDate && includeBattery) { message = [NSString stringWithFormat:@"%@ | at %@ | with %2.f%% battery", message, dateString, batteryLevel*100]; @@ -82,12 +64,22 @@ - (void) logWithLevelToFileSystem:(RadarLogLevel)level type:(RadarLogType)type m } else if (includeBattery) { message = [NSString stringWithFormat:@"%@ | with %2.f%% battery", message, batteryLevel*100]; } + if (append) { + [[RadarLogBuffer sharedInstance] append:level type:type message:message]; + } else { + dispatch_async(dispatch_get_main_queue(), ^{ + [Radar sendLog:level type:type message:message]; + + RadarLogLevel logLevel = [RadarSettings logLevel]; + if (logLevel >= level) { + NSString *log = [NSString stringWithFormat:@"%@ | backgroundTimeRemaining = %g", message, [RadarUtils backgroundTimeRemaining]]; - [self logWithLevel:level type:type message:message]; + os_log(OS_LOG_DEFAULT, "%@", log); - + [[RadarDelegateHolder sharedInstance] didLogMessage:log]; + } + }); + } } - - @end diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index d963638ce..0c453c6dc 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -1435,7 +1435,7 @@ - (void)test_RadarFileSystem_DeleteFile { XCTAssertNil(readData, @"Data read from file should be nil after file is deleted"); } -- (void)testRadarLogBufferWriteAndFlushableLogs { +- (void)test_RadarLogBuffer_WriteAndFlushableLogs { RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; @@ -1451,7 +1451,7 @@ - (void)testRadarLogBufferWriteAndFlushableLogs { XCTAssertEqualObjects(newLogs.lastObject.message, @"Test message 3"); } -- (void)testRadarLogBufferRemoveLogsFromBuffer { +- (void)test_RadarLogBuffer_RemoveLogsFromBuffer { RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; @@ -1461,16 +1461,36 @@ - (void)testRadarLogBufferRemoveLogsFromBuffer { XCTAssertEqual(logs.count, 0); } -- (void)testRadarLogBufferAddLogsToBuffrer { +- (void)test_RadarLogBuffer_AddLogsToBuffrer { RadarLog *log1 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; RadarLog *log2 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; + RadarLog *log3 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 3"]; + RadarLog *log4 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 4"]; + [self.logBuffer addLogsToBuffer:@[log1, log2]]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer flushToPersistentStorage]; + [self.logBuffer addLogsToBuffer:@[log3, log4]]; + NSArray *logs = [self.logBuffer flushableLogs]; + XCTAssertEqual(logs.count, 6); + XCTAssertEqualObjects(logs.lastObject.message, @"Test message 4"); +} + +- (void)test_RadarLogBuffer_addAndRemove{ + RadarLog *log1 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; + RadarLog *log2 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; + RadarLog *log3 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 3"]; + RadarLog *log4 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 4"]; [self.logBuffer addLogsToBuffer:@[log1, log2]]; + [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; + [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; + [self.logBuffer flushToPersistentStorage]; + [self.logBuffer addLogsToBuffer:@[log3, log4]]; NSArray *logs = [self.logBuffer flushableLogs]; - XCTAssertEqual(logs.count, 4); - XCTAssertEqualObjects(logs.lastObject.message, @"Test message 2"); + [self.logBuffer removeLogsFromBuffer:6]; + [self.logBuffer addLogsToBuffer:logs]; + NSArray *logs1 = [self.logBuffer flushableLogs]; + XCTAssertEqual(logs1.count, 6); } - (void)test_RadarLogBuffer_append { From 4e6febec34130f7437d6c362d1ccc54f807e572f Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Fri, 1 Dec 2023 13:57:55 -0500 Subject: [PATCH 20/72] formatting --- RadarSDK/Include/Radar.h | 2 +- RadarSDK/Radar.m | 7 +------ RadarSDK/RadarLogBuffer.m | 3 --- RadarSDK/RadarLogger.m | 10 +++++----- RadarSDKTests/RadarSDKTests.m | 3 --- 5 files changed, 7 insertions(+), 18 deletions(-) diff --git a/RadarSDK/Include/Radar.h b/RadarSDK/Include/Radar.h index 6410e010b..b1e68405e 100644 --- a/RadarSDK/Include/Radar.h +++ b/RadarSDK/Include/Radar.h @@ -1017,7 +1017,7 @@ logConversionWithNotification + (void)logTermination; /** - Log application entering background. + Log application entering background and flush logs in memory buffer into persistent buffer. */ + (void)logEnteringBackground; diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index e8010220b..8a5b45996 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1046,17 +1046,12 @@ + (void)writeLocalLog:(NSString *)message { } -+ (void) logTermination { - ++ (void) logTermination { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminated" includeDate:YES includeBattery:YES append:YES]; - //[[RadarLogBuffer sharedInstance] append:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminated" ]; - NSLog(@"logTermination"); } + (void) logEnteringBackground { - NSLog(@"logEnteringBackground"); [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background" includeDate:YES includeBattery:YES append:YES]; - //[[RadarLogBuffer sharedInstance] append:RadarLogLevelInfo type:RadarLogTypeNone message:@"App backgrounded" ]; [[RadarLogBuffer sharedInstance] flushToPersistentStorage ]; } diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 08b95d721..8a6364fea 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -33,7 +33,6 @@ - (instancetype)init { return self; } - + (instancetype)sharedInstance { static dispatch_once_t once; static id sharedInstance; @@ -52,7 +51,6 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m } } - - (void)flushToPersistentStorage { @synchronized (self) { NSArray *flushableLogs = [mutableLogBuffer copy]; @@ -61,7 +59,6 @@ - (void)flushToPersistentStorage { } } - - (NSMutableArray *)readFromFileSystem { NSData *fileData = [self.fileHandler readFileAtPath:self.logFilePath]; NSString *fileString = [[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding]; diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index 4c8916b42..ab482f9d9 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -72,13 +72,13 @@ - (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSStr RadarLogLevel logLevel = [RadarSettings logLevel]; if (logLevel >= level) { - NSString *log = [NSString stringWithFormat:@"%@ | backgroundTimeRemaining = %g", message, [RadarUtils backgroundTimeRemaining]]; + NSString *log = [NSString stringWithFormat:@"%@ | backgroundTimeRemaining = %g", message, [RadarUtils backgroundTimeRemaining]]; - os_log(OS_LOG_DEFAULT, "%@", log); + os_log(OS_LOG_DEFAULT, "%@", log); - [[RadarDelegateHolder sharedInstance] didLogMessage:log]; - } - }); + [[RadarDelegateHolder sharedInstance] didLogMessage:log]; + } + }); } } diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 0c453c6dc..734f5259c 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -1500,9 +1500,6 @@ - (void)test_RadarLogBuffer_append { XCTAssertEqual(logs.count, 2); XCTAssertEqualObjects(logs.firstObject.message, @"Test message 1"); XCTAssertEqualObjects(logs.lastObject.message, @"Test message 2"); - } - - @end From 1187e87041e3d5b5ef84fd46c7c4dd9b73f430fc Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 6 Dec 2023 10:31:00 -0500 Subject: [PATCH 21/72] renamed method --- RadarSDK/Radar.m | 2 +- RadarSDK/RadarLogBuffer.h | 2 +- RadarSDK/RadarLogBuffer.m | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index 8a5b45996..2b3b3239f 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1052,7 +1052,7 @@ + (void) logTermination { + (void) logEnteringBackground { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background" includeDate:YES includeBattery:YES append:YES]; - [[RadarLogBuffer sharedInstance] flushToPersistentStorage ]; + [[RadarLogBuffer sharedInstance] persist ]; } + (void) logResignActive { diff --git a/RadarSDK/RadarLogBuffer.h b/RadarSDK/RadarLogBuffer.h index dd06a492c..a141a083d 100644 --- a/RadarSDK/RadarLogBuffer.h +++ b/RadarSDK/RadarLogBuffer.h @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; -- (void)flushToPersistentStorage; +- (void)persist; - (void)clear; diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 8a6364fea..78668bc94 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -28,7 +28,7 @@ - (instancetype)init { NSString *logFileName = @"RadarLogs.txt"; self.logFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; self.fileHandler = [[RadarFileSystem alloc] init]; - _timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(flushToPersistentStorage) userInfo:nil repeats:YES]; + _timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(persist) userInfo:nil repeats:YES]; } return self; } @@ -47,11 +47,11 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m [mutableLogBuffer addObject:radarLog]; NSUInteger logLength = [mutableLogBuffer count]; if (logLength >= MAX_MEMORY_BUFFER_SIZE) { - [self flushToPersistentStorage]; + [self persist]; } } -- (void)flushToPersistentStorage { +- (void)persist { @synchronized (self) { NSArray *flushableLogs = [mutableLogBuffer copy]; [self addLogsToBuffer:flushableLogs]; @@ -121,7 +121,7 @@ - (NSString *)logsToJSON:(NSMutableArray *)logs { - (NSArray *)flushableLogs { @synchronized (self) { - [self flushToPersistentStorage]; + [self persist]; NSArray *existingLogsArray = [self.readFromFileSystem copy]; return existingLogsArray; } From 3be3e0c3b655fc1c06b5691170b94b998a6a7e7e Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 6 Dec 2023 13:19:44 -0500 Subject: [PATCH 22/72] commit changes in test file --- RadarSDKTests/RadarSDKTests.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 734f5259c..a89d2f827 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -1439,7 +1439,7 @@ - (void)test_RadarLogBuffer_WriteAndFlushableLogs { RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; - [self.logBuffer flushToPersistentStorage]; + [self.logBuffer persist]; NSArray *logs = [self.logBuffer flushableLogs]; XCTAssertEqual(logs.count, 2); XCTAssertEqualObjects(logs.firstObject.message, @"Test message 1"); @@ -1455,7 +1455,7 @@ - (void)test_RadarLogBuffer_RemoveLogsFromBuffer { RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; - [self.logBuffer flushToPersistentStorage]; + [self.logBuffer persist]; [self.logBuffer removeLogsFromBuffer:2]; NSArray *logs = [self.logBuffer flushableLogs]; XCTAssertEqual(logs.count, 0); @@ -1469,7 +1469,7 @@ - (void)test_RadarLogBuffer_AddLogsToBuffrer { [self.logBuffer addLogsToBuffer:@[log1, log2]]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; - [self.logBuffer flushToPersistentStorage]; + [self.logBuffer persist]; [self.logBuffer addLogsToBuffer:@[log3, log4]]; NSArray *logs = [self.logBuffer flushableLogs]; XCTAssertEqual(logs.count, 6); @@ -1484,7 +1484,7 @@ - (void)test_RadarLogBuffer_addAndRemove{ [self.logBuffer addLogsToBuffer:@[log1, log2]]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; - [self.logBuffer flushToPersistentStorage]; + [self.logBuffer persist]; [self.logBuffer addLogsToBuffer:@[log3, log4]]; NSArray *logs = [self.logBuffer flushableLogs]; [self.logBuffer removeLogsFromBuffer:6]; From 7354d8fff69492d75d348277d8f8362ec43a736f Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 6 Dec 2023 13:23:50 -0500 Subject: [PATCH 23/72] rename persist func name --- RadarSDK/Radar.m | 2 +- RadarSDK/RadarLogBuffer.h | 2 +- RadarSDK/RadarLogBuffer.m | 6 +++--- RadarSDKTests/RadarSDKTests.m | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index 2b3b3239f..f29589b08 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1052,7 +1052,7 @@ + (void) logTermination { + (void) logEnteringBackground { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background" includeDate:YES includeBattery:YES append:YES]; - [[RadarLogBuffer sharedInstance] persist ]; + [[RadarLogBuffer sharedInstance] persistLogs ]; } + (void) logResignActive { diff --git a/RadarSDK/RadarLogBuffer.h b/RadarSDK/RadarLogBuffer.h index a141a083d..ab4f2c5f3 100644 --- a/RadarSDK/RadarLogBuffer.h +++ b/RadarSDK/RadarLogBuffer.h @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; -- (void)persist; +- (void)persistLogs; - (void)clear; diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 78668bc94..6a35639eb 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -47,11 +47,11 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m [mutableLogBuffer addObject:radarLog]; NSUInteger logLength = [mutableLogBuffer count]; if (logLength >= MAX_MEMORY_BUFFER_SIZE) { - [self persist]; + [self persistLogs]; } } -- (void)persist { +- (void)persistLogs { @synchronized (self) { NSArray *flushableLogs = [mutableLogBuffer copy]; [self addLogsToBuffer:flushableLogs]; @@ -121,7 +121,7 @@ - (NSString *)logsToJSON:(NSMutableArray *)logs { - (NSArray *)flushableLogs { @synchronized (self) { - [self persist]; + [self persistLogs]; NSArray *existingLogsArray = [self.readFromFileSystem copy]; return existingLogsArray; } diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index a89d2f827..9f9d7fb80 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -1439,7 +1439,7 @@ - (void)test_RadarLogBuffer_WriteAndFlushableLogs { RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; - [self.logBuffer persist]; + [self.logBuffer persistLogs]; NSArray *logs = [self.logBuffer flushableLogs]; XCTAssertEqual(logs.count, 2); XCTAssertEqualObjects(logs.firstObject.message, @"Test message 1"); @@ -1455,7 +1455,7 @@ - (void)test_RadarLogBuffer_RemoveLogsFromBuffer { RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; - [self.logBuffer persist]; + [self.logBuffer persistLogs]; [self.logBuffer removeLogsFromBuffer:2]; NSArray *logs = [self.logBuffer flushableLogs]; XCTAssertEqual(logs.count, 0); @@ -1469,7 +1469,7 @@ - (void)test_RadarLogBuffer_AddLogsToBuffrer { [self.logBuffer addLogsToBuffer:@[log1, log2]]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; - [self.logBuffer persist]; + [self.logBuffer persistLogs]; [self.logBuffer addLogsToBuffer:@[log3, log4]]; NSArray *logs = [self.logBuffer flushableLogs]; XCTAssertEqual(logs.count, 6); @@ -1484,7 +1484,7 @@ - (void)test_RadarLogBuffer_addAndRemove{ [self.logBuffer addLogsToBuffer:@[log1, log2]]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; - [self.logBuffer persist]; + [self.logBuffer persistLogs]; [self.logBuffer addLogsToBuffer:@[log3, log4]]; NSArray *logs = [self.logBuffer flushableLogs]; [self.logBuffer removeLogsFromBuffer:6]; From 8fdafaf74f9c034f2511954421300ab3871b971a Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 6 Dec 2023 13:32:33 -0500 Subject: [PATCH 24/72] change name to radarFileStorage --- RadarSDK/RadarFileStorage.h | 13 ++++++++ RadarSDK/RadarFileStorage.m | 9 ++++++ RadarSDK/RadarFileSystem.h | 22 ------------- RadarSDK/RadarFileSystem.m | 59 ----------------------------------- RadarSDKTests/RadarSDKTests.m | 12 +++---- 5 files changed, 28 insertions(+), 87 deletions(-) create mode 100644 RadarSDK/RadarFileStorage.h create mode 100644 RadarSDK/RadarFileStorage.m delete mode 100644 RadarSDK/RadarFileSystem.h delete mode 100644 RadarSDK/RadarFileSystem.m diff --git a/RadarSDK/RadarFileStorage.h b/RadarSDK/RadarFileStorage.h new file mode 100644 index 000000000..1cd6c59a5 --- /dev/null +++ b/RadarSDK/RadarFileStorage.h @@ -0,0 +1,13 @@ +// +// RadarFileStorage.h +// RadarSDK +// +// Created by Kenny Hu on 12/6/23. +// Copyright © 2023 Radar Labs, Inc. All rights reserved. +// + +#ifndef RadarFileStorage_h +#define RadarFileStorage_h + + +#endif /* RadarFileStorage_h */ diff --git a/RadarSDK/RadarFileStorage.m b/RadarSDK/RadarFileStorage.m new file mode 100644 index 000000000..d4d569406 --- /dev/null +++ b/RadarSDK/RadarFileStorage.m @@ -0,0 +1,9 @@ +// +// RadarFileStorage.m +// RadarSDK +// +// Created by Kenny Hu on 12/6/23. +// Copyright © 2023 Radar Labs, Inc. All rights reserved. +// + +#import diff --git a/RadarSDK/RadarFileSystem.h b/RadarSDK/RadarFileSystem.h deleted file mode 100644 index 784ae695a..000000000 --- a/RadarSDK/RadarFileSystem.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// RadarFileSystem.h -// RadarSDK -// -// Created by Kenny Hu on 11/20/23. -// Copyright © 2023 Radar Labs, Inc. All rights reserved. -// - -#import - -@interface RadarFileSystem : NSObject - - -- (NSData *)readFileAtPath:(NSString *)filePath; - -- (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath; - -- (void)deleteFileAtPath:(NSString *)filePath; - -- (void)appendData:(NSData *)data toFileAtPath:(NSString *)filePath ; - -@end diff --git a/RadarSDK/RadarFileSystem.m b/RadarSDK/RadarFileSystem.m deleted file mode 100644 index 0a31b3ebc..000000000 --- a/RadarSDK/RadarFileSystem.m +++ /dev/null @@ -1,59 +0,0 @@ -// -// RadarFileSystem.m -// RadarSDK -// -// Created by Kenny Hu on 11/20/23. -// Copyright © 2023 Radar Labs, Inc. All rights reserved. -// - -#import -#import "RadarFileSystem.h" - -@implementation RadarFileSystem - - - -- (NSData *)readFileAtPath:(NSString *)filePath { - __block NSData *fileData = nil; - - NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; - [fileCoordinator coordinateReadingItemAtURL:[NSURL fileURLWithPath:filePath] options:0 error:nil byAccessor:^(NSURL *newURL) { - fileData = [NSData dataWithContentsOfURL:newURL]; - }]; - - return fileData; -} - -- (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath { - - NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; - [fileCoordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:filePath] options:NSFileCoordinatorWritingForReplacing error:nil byAccessor:^(NSURL *newURL) { - [data writeToURL:newURL options:NSDataWritingAtomic error:nil]; - }]; -} - -- (void)appendData:(NSData *)data toFileAtPath:(NSString *)filePath { - NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; - //TODO: not very sure if the option is correct, need to check - [fileCoordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:filePath] options:NSFileCoordinatorWritingForReplacing error:nil byAccessor:^(NSURL *newURL) { - NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingToURL:newURL error:nil]; - if (!fileHandle) { - [[NSFileManager defaultManager] createFileAtPath:[newURL path] contents:nil attributes:nil]; - fileHandle = [NSFileHandle fileHandleForWritingToURL:newURL error:nil]; - } - [fileHandle seekToEndOfFile]; - [fileHandle writeData:data]; - [fileHandle closeFile]; - }]; -} - - -- (void)deleteFileAtPath:(NSString *)filePath { - NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; - [fileCoordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:filePath] options:NSFileCoordinatorWritingForDeleting error:nil byAccessor:^(NSURL *newURL) { - [[NSFileManager defaultManager] removeItemAtURL:newURL error:nil]; - }]; -} - -@end - diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 9f9d7fb80..2ec02bc61 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -18,7 +18,7 @@ #import "RadarPermissionsHelperMock.h" #import "RadarTestUtils.h" #import "RadarTripOptions.h" -#import "RadarFileSystem.h" +#import "RadarFileStorage.h" #import "../RadarSDK/RadarLogBuffer.h" @@ -27,7 +27,7 @@ @interface RadarSDKTests : XCTestCase @property (nonnull, strong, nonatomic) RadarAPIHelperMock *apiHelperMock; @property (nonnull, strong, nonatomic) CLLocationManagerMock *locationManagerMock; @property (nonnull, strong, nonatomic) RadarPermissionsHelperMock *permissionsHelperMock; -@property (nonatomic, strong) RadarFileSystem *fileSystem; +@property (nonatomic, strong) RadarFileStorage *fileSystem; @property (nonatomic, strong) NSString *testFilePath; @property (nonatomic, strong) RadarLogBuffer *logBuffer; @end @@ -296,7 +296,7 @@ - (void)setUp { self.locationManagerMock.delegate = [RadarLocationManager sharedInstance]; [RadarLocationManager sharedInstance].lowPowerLocationManager = self.locationManagerMock; [RadarLocationManager sharedInstance].permissionsHelper = self.permissionsHelperMock; - self.fileSystem = [[RadarFileSystem alloc] init]; + self.fileSystem = [[RadarFileStorage alloc] init]; self.testFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"testfile"]; self.logBuffer = [RadarLogBuffer sharedInstance]; [self.logBuffer clear]; @@ -1407,7 +1407,7 @@ - (void)test_RadarTrackingOptions_isEqual { XCTAssertNotEqualObjects(options, @"foo"); } -- (void)test_RadarFileSystem_WriteAndRead { +- (void)test_RadarFileStorage_WriteAndRead { NSData *originalData = [@"Test data" dataUsingEncoding:NSUTF8StringEncoding]; [self.fileSystem writeData:originalData toFileAtPath:self.testFilePath]; NSData *originalData2 = [@"Newer Test data" dataUsingEncoding:NSUTF8StringEncoding]; @@ -1416,7 +1416,7 @@ - (void)test_RadarFileSystem_WriteAndRead { XCTAssertEqualObjects(originalData2, readData, @"Data read from file should be equal to original data"); } -- (void)test_RadarFileSystem_Append { +- (void)test_RadarFileStorage_Append { NSData *originalData = [@"Test data" dataUsingEncoding:NSUTF8StringEncoding]; [self.fileSystem writeData:originalData toFileAtPath:self.testFilePath]; NSData *appendData = [@"Newer Test data" dataUsingEncoding:NSUTF8StringEncoding]; @@ -1427,7 +1427,7 @@ - (void)test_RadarFileSystem_Append { XCTAssertEqualObjects(readString, expectedString, @"Data read from file should be equal to original data"); } -- (void)test_RadarFileSystem_DeleteFile { +- (void)test_RadarFileStorage_DeleteFile { NSData *originalData = [@"Test data" dataUsingEncoding:NSUTF8StringEncoding]; [self.fileSystem writeData:originalData toFileAtPath:self.testFilePath]; [self.fileSystem deleteFileAtPath:self.testFilePath]; From 96016824abca55050bef7cebef38586fb8e34807 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 6 Dec 2023 13:32:58 -0500 Subject: [PATCH 25/72] change name to radarFileStorage --- RadarSDK/RadarFileStorage.h | 15 ++++++++--- RadarSDK/RadarFileStorage.m | 50 +++++++++++++++++++++++++++++++++++++ RadarSDK/RadarLogBuffer.h | 4 +-- RadarSDK/RadarLogBuffer.m | 18 ++++++------- 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/RadarSDK/RadarFileStorage.h b/RadarSDK/RadarFileStorage.h index 1cd6c59a5..e741a8d0c 100644 --- a/RadarSDK/RadarFileStorage.h +++ b/RadarSDK/RadarFileStorage.h @@ -6,8 +6,17 @@ // Copyright © 2023 Radar Labs, Inc. All rights reserved. // -#ifndef RadarFileStorage_h -#define RadarFileStorage_h +#import +@interface RadarFileStorage : NSObject -#endif /* RadarFileStorage_h */ + +- (NSData *)readFileAtPath:(NSString *)filePath; + +- (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath; + +- (void)deleteFileAtPath:(NSString *)filePath; + +- (void)appendData:(NSData *)data toFileAtPath:(NSString *)filePath ; + +@end diff --git a/RadarSDK/RadarFileStorage.m b/RadarSDK/RadarFileStorage.m index d4d569406..e8ebeb191 100644 --- a/RadarSDK/RadarFileStorage.m +++ b/RadarSDK/RadarFileStorage.m @@ -7,3 +7,53 @@ // #import +#import "RadarFileStorage.h" + +@implementation RadarFileStorage + + + +- (NSData *)readFileAtPath:(NSString *)filePath { + __block NSData *fileData = nil; + + NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; + [fileCoordinator coordinateReadingItemAtURL:[NSURL fileURLWithPath:filePath] options:0 error:nil byAccessor:^(NSURL *newURL) { + fileData = [NSData dataWithContentsOfURL:newURL]; + }]; + + return fileData; +} + +- (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath { + + NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; + [fileCoordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:filePath] options:NSFileCoordinatorWritingForReplacing error:nil byAccessor:^(NSURL *newURL) { + [data writeToURL:newURL options:NSDataWritingAtomic error:nil]; + }]; +} + +- (void)appendData:(NSData *)data toFileAtPath:(NSString *)filePath { + NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; + //TODO: not very sure if the option is correct, need to check + [fileCoordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:filePath] options:NSFileCoordinatorWritingForReplacing error:nil byAccessor:^(NSURL *newURL) { + NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingToURL:newURL error:nil]; + if (!fileHandle) { + [[NSFileManager defaultManager] createFileAtPath:[newURL path] contents:nil attributes:nil]; + fileHandle = [NSFileHandle fileHandleForWritingToURL:newURL error:nil]; + } + [fileHandle seekToEndOfFile]; + [fileHandle writeData:data]; + [fileHandle closeFile]; + }]; +} + + +- (void)deleteFileAtPath:(NSString *)filePath { + NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; + [fileCoordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:filePath] options:NSFileCoordinatorWritingForDeleting error:nil byAccessor:^(NSURL *newURL) { + [[NSFileManager defaultManager] removeItemAtURL:newURL error:nil]; + }]; +} + +@end + diff --git a/RadarSDK/RadarLogBuffer.h b/RadarSDK/RadarLogBuffer.h index ab4f2c5f3..8b094959a 100644 --- a/RadarSDK/RadarLogBuffer.h +++ b/RadarSDK/RadarLogBuffer.h @@ -8,7 +8,7 @@ #import #import "RadarLog.h" -#import "RadarFileSystem.h" +#import "RadarFileStorage.h" NS_ASSUME_NONNULL_BEGIN @@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN @property (assign, nonatomic, readonly) NSArray *flushableLogs; @property (strong, nonatomic) NSString *logFilePath; -@property (strong, nonatomic) RadarFileSystem *fileHandler; +@property (strong, nonatomic) RadarFileStorage *fileHandler; @property (nonatomic, strong) NSTimer *timer; + (instancetype)sharedInstance; diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 6a35639eb..cb1958add 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -7,7 +7,7 @@ #import "RadarLogBuffer.h" #import "RadarLog.h" -#import "RadarFileSystem.h" +#import "RadarFileStorage.h" static const int MAX_PERSISTED_BUFFER_SIZE = 500; static const int MAX_MEMORY_BUFFER_SIZE = 200; @@ -27,7 +27,7 @@ - (instancetype)init { NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; NSString *logFileName = @"RadarLogs.txt"; self.logFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; - self.fileHandler = [[RadarFileSystem alloc] init]; + self.fileHandler = [[RadarFileStorage alloc] init]; _timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(persist) userInfo:nil repeats:YES]; } return self; @@ -59,13 +59,13 @@ - (void)persistLogs { } } -- (NSMutableArray *)readFromFileSystem { +- (NSMutableArray *)readFromFileStorage { NSData *fileData = [self.fileHandler readFileAtPath:self.logFilePath]; NSString *fileString = [[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding]; return [self jsonToLogs:fileString]; } -- (void) writeToFileSystem:(NSMutableArray * )logs { +- (void) writeToFileStorage:(NSMutableArray * )logs { NSString *updatedLogString = [self logsToJSON:logs]; NSData *updatedLogData = [updatedLogString dataUsingEncoding:NSUTF8StringEncoding]; [self.fileHandler writeData:updatedLogData toFileAtPath:self.logFilePath]; @@ -122,7 +122,7 @@ - (NSString *)logsToJSON:(NSMutableArray *)logs { - (NSArray *)flushableLogs { @synchronized (self) { [self persistLogs]; - NSArray *existingLogsArray = [self.readFromFileSystem copy]; + NSArray *existingLogsArray = [self.readFromFileStorage copy]; return existingLogsArray; } } @@ -130,15 +130,15 @@ - (NSString *)logsToJSON:(NSMutableArray *)logs { - (void)removeLogsFromBuffer:(NSUInteger)numLogs { @synchronized (self) { - NSMutableArray *existingLogs = [self readFromFileSystem]; + NSMutableArray *existingLogs = [self readFromFileStorage]; [existingLogs removeObjectsInRange:NSMakeRange(0, numLogs)]; - [self writeToFileSystem:existingLogs]; + [self writeToFileStorage:existingLogs]; } } - (void)addLogsToBuffer:(NSArray *)logs { @synchronized (self) { - NSMutableArray *existingLogs = [self readFromFileSystem]; + NSMutableArray *existingLogs = [self readFromFileStorage]; [existingLogs addObjectsFromArray:logs]; NSUInteger logLength = [existingLogs count]; if (logLength >= MAX_PERSISTED_BUFFER_SIZE) { @@ -146,7 +146,7 @@ - (void)addLogsToBuffer:(NSArray *)logs { RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; [existingLogs insertObject:purgeLog atIndex:0]; } - [self writeToFileSystem:existingLogs]; + [self writeToFileStorage:existingLogs]; } } From 2f8ad4981d8563adb190cd4f23967ae4ad9a5bd9 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 6 Dec 2023 13:33:15 -0500 Subject: [PATCH 26/72] change name to radarFileStorage --- RadarSDK.xcodeproj/project.pbxproj | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/RadarSDK.xcodeproj/project.pbxproj b/RadarSDK.xcodeproj/project.pbxproj index c89510389..f5fda5203 100644 --- a/RadarSDK.xcodeproj/project.pbxproj +++ b/RadarSDK.xcodeproj/project.pbxproj @@ -159,8 +159,8 @@ DD8E2F7A24018C37002D51AB /* CLLocationManagerMock.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8E2F7924018C37002D51AB /* CLLocationManagerMock.m */; }; DD8E2F7D24018C54002D51AB /* CLVisitMock.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8E2F7C24018C54002D51AB /* CLVisitMock.m */; }; DE1E7644239724FD006F34A1 /* search_geofences.json in Resources */ = {isa = PBXBuildFile; fileRef = DE1E7643239724FD006F34A1 /* search_geofences.json */; }; - E619D29D2B0BF4CE00C88578 /* RadarFileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = E619D29C2B0BF4CE00C88578 /* RadarFileSystem.h */; }; - E619D29F2B0BF50D00C88578 /* RadarFileSystem.m in Sources */ = {isa = PBXBuildFile; fileRef = E619D29E2B0BF50D00C88578 /* RadarFileSystem.m */; }; + E6EEC56E2B20F41A00DD096B /* RadarFileStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = E6EEC56D2B20F41A00DD096B /* RadarFileStorage.h */; }; + E6EEC5702B20F45D00DD096B /* RadarFileStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = E6EEC56F2B20F45D00DD096B /* RadarFileStorage.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -317,8 +317,8 @@ DDD7BD0325EC3015002473B3 /* RadarRouteMatrix.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RadarRouteMatrix.m; sourceTree = ""; }; DDF1157C2524E18100D575C4 /* RadarTrip.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RadarTrip.m; sourceTree = ""; }; DE1E7643239724FD006F34A1 /* search_geofences.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = search_geofences.json; sourceTree = ""; }; - E619D29C2B0BF4CE00C88578 /* RadarFileSystem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RadarFileSystem.h; sourceTree = ""; }; - E619D29E2B0BF50D00C88578 /* RadarFileSystem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RadarFileSystem.m; sourceTree = ""; }; + E6EEC56D2B20F41A00DD096B /* RadarFileStorage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RadarFileStorage.h; sourceTree = ""; }; + E6EEC56F2B20F45D00DD096B /* RadarFileStorage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RadarFileStorage.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -451,8 +451,8 @@ 58F950CF2407038300364B15 /* RadarCollectionAdditions.m */, 01F99CFA2965C182004E8CF3 /* RadarConfig.h */, 01F99CFC2965C1C4004E8CF3 /* RadarConfig.m */, - E619D29C2B0BF4CE00C88578 /* RadarFileSystem.h */, - E619D29E2B0BF50D00C88578 /* RadarFileSystem.m */, + E6EEC56D2B20F41A00DD096B /* RadarFileStorage.h */, + E6EEC56F2B20F45D00DD096B /* RadarFileStorage.m */, 96A5A11727ADA02E007B960B /* RadarDelegateHolder.h */, DD4C104925D87E3E009C2E36 /* RadarDelegateHolder.m */, DD236CF723088F8400EB88F9 /* RadarLocationManager.h */, @@ -610,6 +610,7 @@ 96A5A10527AD9F7F007B960B /* RadarTrackingOptions.h in Headers */, 96A5A10927AD9F7F007B960B /* RadarContext.h in Headers */, 0107AA1226220049008AB52F /* RadarCollectionAdditions.h in Headers */, + E6EEC56E2B20F41A00DD096B /* RadarFileStorage.h in Headers */, 015C53AD29B8E8BA004F53A6 /* (null) in Headers */, 0107AA1C26220055008AB52F /* RadarPermissionsHelper.h in Headers */, 96A5A11227AD9F7F007B960B /* Radar.h in Headers */, @@ -634,7 +635,6 @@ 96A5A0C427AD9F41007B960B /* RadarCircleGeometry+Internal.h in Headers */, 0114F058284EFDB700ADA4E4 /* RadarRouteMode.h in Headers */, 96A5A0D527AD9F41007B960B /* RadarRouteDuration+Internal.h in Headers */, - E619D29D2B0BF4CE00C88578 /* RadarFileSystem.h in Headers */, 96A5A0CE27AD9F41007B960B /* RadarCoordinate+Internal.h in Headers */, 96A5A11927ADA02F007B960B /* RadarLog.h in Headers */, 96A5A10A27AD9F7F007B960B /* RadarAddress.h in Headers */, @@ -792,12 +792,12 @@ 0107AA9B26220153008AB52F /* RadarContext.m in Sources */, 015C53AE29B8E8BA004F53A6 /* (null) in Sources */, 0107AB23262201EC008AB52F /* RadarSettings.m in Sources */, - E619D29F2B0BF50D00C88578 /* RadarFileSystem.m in Sources */, 0107AAAA26220165008AB52F /* RadarGeofenceGeometry.m in Sources */, 0107AAEC262201A6008AB52F /* RadarTrip.m in Sources */, 9679F4A327CD8DE200800797 /* CLLocation+Radar.m in Sources */, 0107AB08262201CE008AB52F /* RadarAPIClient.m in Sources */, 0107AB05262201CB008AB52F /* Radar.m in Sources */, + E6EEC5702B20F45D00DD096B /* RadarFileStorage.m in Sources */, 0107AB29262201F4008AB52F /* RadarTrackingOptions.m in Sources */, 0107AB2F262201FB008AB52F /* RadarUtils.m in Sources */, 0107AA8926220140008AB52F /* RadarChain.m in Sources */, From 324bf47a2da9de5bc5f42105e8184012b61161ee Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 6 Dec 2023 14:08:55 -0500 Subject: [PATCH 27/72] missed name change for radarFileStorage --- RadarSDK/RadarLogger.h | 4 ++-- RadarSDK/RadarLogger.m | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/RadarSDK/RadarLogger.h b/RadarSDK/RadarLogger.h index d8f166ee3..34bb645bc 100644 --- a/RadarSDK/RadarLogger.h +++ b/RadarSDK/RadarLogger.h @@ -8,14 +8,14 @@ #import #import "RadarDelegate.h" -#import "RadarFileSystem.h" +#import "RadarFileStorage.h" NS_ASSUME_NONNULL_BEGIN @interface RadarLogger : NSObject @property (strong, nonatomic) NSString *logFilePath; -@property (strong, nonatomic) RadarFileSystem *fileHandler; +@property (strong, nonatomic) RadarFileStorage *fileHandler; @property (strong, nonatomic) NSDateFormatter *dateFormatter; @property (strong, nonatomic) UIDevice *device; diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index ab482f9d9..739840c5e 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -11,7 +11,7 @@ #import "RadarSettings.h" #import "RadarUtils.h" #import -#import "RadarFileSystem.h" +#import "RadarFileStorage.h" #import "RadarLog.h" #import "RadarLogBuffer.h" @@ -33,7 +33,7 @@ - (instancetype)init { NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; NSString *logFileName = @"RadarLogs.txt"; self.logFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; - self.fileHandler = [[RadarFileSystem alloc] init]; + self.fileHandler = [[RadarFileStorage alloc] init]; self.dateFormatter = [[NSDateFormatter alloc] init]; [self.dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; self.device = [UIDevice currentDevice]; From 2fa4205e53afc815532db39bd7e0b686900337e0 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 6 Dec 2023 14:42:51 -0500 Subject: [PATCH 28/72] change name --- RadarSDK/RadarLogBuffer.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index cb1958add..5547d4881 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -28,7 +28,7 @@ - (instancetype)init { NSString *logFileName = @"RadarLogs.txt"; self.logFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; self.fileHandler = [[RadarFileStorage alloc] init]; - _timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(persist) userInfo:nil repeats:YES]; + _timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(persistLogs) userInfo:nil repeats:YES]; } return self; } From 07df4e754a0c9002ec0db30fdf122c3f3e181aa0 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 7 Dec 2023 10:36:30 -0500 Subject: [PATCH 29/72] implemented individual file logging --- RadarSDK/Radar.m | 6 +- RadarSDK/RadarFileStorage.h | 3 +- RadarSDK/RadarFileStorage.m | 29 ++++---- RadarSDK/RadarLog.h | 2 +- RadarSDK/RadarLog.m | 21 ++++++ RadarSDK/RadarLogBuffer.h | 2 +- RadarSDK/RadarLogBuffer.m | 123 ++++++++++++++++------------------ RadarSDKTests/RadarSDKTests.m | 23 ++++--- 8 files changed, 110 insertions(+), 99 deletions(-) diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index f29589b08..4d0e25446 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -43,11 +43,6 @@ + (id)sharedInstance { + (void)initializeWithPublishableKey:(NSString *)publishableKey { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeSDKCall message:@"initialize()"]; - - [self flushLogs]; - - [[RadarLogBuffer sharedInstance] clear]; - [[NSNotificationCenter defaultCenter] addObserver:[self sharedInstance] selector:@selector(applicationWillEnterForeground) @@ -72,6 +67,7 @@ + (void)initializeWithPublishableKey:(NSString *)publishableKey { [[RadarLocationManager sharedInstance] updateTrackingFromMeta:config.meta]; [RadarSettings setFeatureSettings:config.meta.featureSettings]; }]; + [self flushLogs]; } #pragma mark - Properties diff --git a/RadarSDK/RadarFileStorage.h b/RadarSDK/RadarFileStorage.h index e741a8d0c..2ef705b01 100644 --- a/RadarSDK/RadarFileStorage.h +++ b/RadarSDK/RadarFileStorage.h @@ -17,6 +17,5 @@ - (void)deleteFileAtPath:(NSString *)filePath; -- (void)appendData:(NSData *)data toFileAtPath:(NSString *)filePath ; - +- (NSArray *)allFilesInDirectory:(NSString *)directoryPath; @end diff --git a/RadarSDK/RadarFileStorage.m b/RadarSDK/RadarFileStorage.m index e8ebeb191..1df71a050 100644 --- a/RadarSDK/RadarFileStorage.m +++ b/RadarSDK/RadarFileStorage.m @@ -32,22 +32,6 @@ - (void)writeData:(NSData *)data toFileAtPath:(NSString *)filePath { }]; } -- (void)appendData:(NSData *)data toFileAtPath:(NSString *)filePath { - NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; - //TODO: not very sure if the option is correct, need to check - [fileCoordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:filePath] options:NSFileCoordinatorWritingForReplacing error:nil byAccessor:^(NSURL *newURL) { - NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingToURL:newURL error:nil]; - if (!fileHandle) { - [[NSFileManager defaultManager] createFileAtPath:[newURL path] contents:nil attributes:nil]; - fileHandle = [NSFileHandle fileHandleForWritingToURL:newURL error:nil]; - } - [fileHandle seekToEndOfFile]; - [fileHandle writeData:data]; - [fileHandle closeFile]; - }]; -} - - - (void)deleteFileAtPath:(NSString *)filePath { NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; [fileCoordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:filePath] options:NSFileCoordinatorWritingForDeleting error:nil byAccessor:^(NSURL *newURL) { @@ -55,5 +39,18 @@ - (void)deleteFileAtPath:(NSString *)filePath { }]; } +- (NSArray *)allFilesInDirectory:(NSString *)directoryPath { + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *error = nil; + NSArray *files = [fileManager contentsOfDirectoryAtPath:directoryPath error:&error]; + + if (error) { + NSLog(@"Failed to get files in directory: %@", [error localizedDescription]); + return nil; + } + + return [files sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];; +} + @end diff --git a/RadarSDK/RadarLog.h b/RadarSDK/RadarLog.h index 5af75c233..4a162e04d 100644 --- a/RadarSDK/RadarLog.h +++ b/RadarSDK/RadarLog.h @@ -10,7 +10,7 @@ /** Represents a debug log. */ -@interface RadarLog : NSObject +@interface RadarLog : NSObject /** The levels for debug logs. diff --git a/RadarSDK/RadarLog.m b/RadarSDK/RadarLog.m index 68559bacc..2b55e8f39 100644 --- a/RadarSDK/RadarLog.m +++ b/RadarSDK/RadarLog.m @@ -128,4 +128,25 @@ - (instancetype)initWithDictionary:(NSDictionary *)dictionary { return arr; } +#pragma mark - NSCoding + +- (instancetype)initWithCoder:(NSCoder *)coder { + self = [super init]; + if (self) { + _level = [coder decodeIntegerForKey:@"level"]; + _type = [coder decodeIntegerForKey:@"type"]; + _message = [coder decodeObjectForKey:@"message"]; + _createdAt = [coder decodeObjectForKey:@"createdAt"]; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeInteger:_level forKey:@"level"]; + [coder encodeInteger:_type forKey:@"type"]; + [coder encodeObject:_message forKey:@"message"]; + [coder encodeObject:_createdAt forKey:@"createdAt"]; +} + + @end diff --git a/RadarSDK/RadarLogBuffer.h b/RadarSDK/RadarLogBuffer.h index 8b094959a..f6de4a48f 100644 --- a/RadarSDK/RadarLogBuffer.h +++ b/RadarSDK/RadarLogBuffer.h @@ -15,7 +15,7 @@ NS_ASSUME_NONNULL_BEGIN @interface RadarLogBuffer : NSObject @property (assign, nonatomic, readonly) NSArray *flushableLogs; -@property (strong, nonatomic) NSString *logFilePath; +@property (strong, nonatomic) NSString *logFileDir; @property (strong, nonatomic) RadarFileStorage *fileHandler; @property (nonatomic, strong) NSTimer *timer; diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 5547d4881..125f6305c 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -16,6 +16,8 @@ static NSString *const kPurgedLogLine = @"----- purged oldest logs -----"; static NSString *const kDelimiter = @"\?"; +static int counter = 0; + @implementation RadarLogBuffer { NSMutableArray *mutableLogBuffer; } @@ -25,8 +27,10 @@ - (instancetype)init { if (self) { mutableLogBuffer = [NSMutableArray new]; NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; - NSString *logFileName = @"RadarLogs.txt"; - self.logFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; + self.logFileDir = [documentsDirectory stringByAppendingPathComponent:@"radar_logs"]; + if (![[NSFileManager defaultManager] fileExistsAtPath:self.logFileDir isDirectory:nil]) { + [[NSFileManager defaultManager] createDirectoryAtPath:self.logFileDir withIntermediateDirectories:YES attributes:nil error:nil]; + } self.fileHandler = [[RadarFileStorage alloc] init]; _timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(persistLogs) userInfo:nil repeats:YES]; } @@ -43,7 +47,7 @@ + (instancetype)sharedInstance { } - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { - RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:[self strip:message]]; + RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; [mutableLogBuffer addObject:radarLog]; NSUInteger logLength = [mutableLogBuffer count]; if (logLength >= MAX_MEMORY_BUFFER_SIZE) { @@ -60,63 +64,42 @@ - (void)persistLogs { } - (NSMutableArray *)readFromFileStorage { - NSData *fileData = [self.fileHandler readFileAtPath:self.logFilePath]; - NSString *fileString = [[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding]; - return [self jsonToLogs:fileString]; -} - -- (void) writeToFileStorage:(NSMutableArray * )logs { - NSString *updatedLogString = [self logsToJSON:logs]; - NSData *updatedLogData = [updatedLogString dataUsingEncoding:NSUTF8StringEncoding]; - [self.fileHandler writeData:updatedLogData toFileAtPath:self.logFilePath]; -} -- (void) append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { - @synchronized (self) { - RadarLog *log = [[RadarLog alloc] initWithLevel:level type:type message:[self strip:message]]; - NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[log dictionaryValue] options:0 error:nil]; - NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; - NSString *logString = [NSString stringWithFormat:@"%@%@",kDelimiter ,jsonString]; - NSData *logData = [logString dataUsingEncoding:NSUTF8StringEncoding]; - [self.fileHandler appendData:logData toFileAtPath:self.logFilePath]; - } -} - -//strip a message of a log of delimiter -- (NSString *)strip:(NSString *)message { - return [message stringByReplacingOccurrencesOfString:kDelimiter withString:@""]; -} - -- (NSString *)logsToJSON:(NSMutableArray *)logs { - NSMutableArray *jsonStrings = [NSMutableArray array]; - for (RadarLog *log in logs) { - NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[log dictionaryValue] options:0 error:nil]; - NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; - [jsonStrings addObject:jsonString]; - } - return [jsonStrings componentsJoinedByString:kDelimiter]; -} - -- (NSMutableArray *)jsonToLogs:(NSString *)json { - - if([json length] == 0){ - return [NSMutableArray array]; - } - if([json hasPrefix:kDelimiter]){ - json = [json substringFromIndex:1]; - } - + NSLog(@"read from file storage"); + NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; NSMutableArray *logs = [NSMutableArray array]; - NSArray *jsonStrings = [json componentsSeparatedByString:kDelimiter]; - for (NSString *jsonString in jsonStrings) { - NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; - NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil]; - RadarLog *log = [[RadarLog alloc] initWithDictionary:jsonDict]; + if(!files){ + return logs; + } + for (NSString *file in files) { + NSString *filePath = [self.logFileDir stringByAppendingPathComponent:file]; + NSData *fileData = [self.fileHandler readFileAtPath:filePath]; + RadarLog *log = [NSKeyedUnarchiver unarchiveObjectWithData:fileData]; if(log && log.message){ [logs addObject:log]; + NSLog(@"log message: %@", log.message); } } + return logs; + +} + + - (void) writeToFileStorage:(NSArray *)logs { + for(RadarLog *log in logs){ + NSData *logData = [NSKeyedArchiver archivedDataWithRootObject:log]; + NSTimeInterval unixTimestamp = [log.createdAt timeIntervalSince1970]; + NSString *unixTimestampString = [NSString stringWithFormat:@"%lld_%d", (long long)unixTimestamp,counter++]; + NSString *filePath = [self.logFileDir stringByAppendingPathComponent:unixTimestampString]; + NSLog(@"writing log message: %@", log.message); + [self.fileHandler writeData:logData toFileAtPath:filePath]; + } + } + +- (void) append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { + @synchronized (self) { + [self writeToFileStorage:@[[[RadarLog alloc] initWithLevel:level type:type message:message]]]; + } } - (NSArray *)flushableLogs { @@ -127,32 +110,40 @@ - (NSString *)logsToJSON:(NSMutableArray *)logs { } } - - (void)removeLogsFromBuffer:(NSUInteger)numLogs { - @synchronized (self) { - NSMutableArray *existingLogs = [self readFromFileStorage]; - [existingLogs removeObjectsInRange:NSMakeRange(0, numLogs)]; - [self writeToFileStorage:existingLogs]; + @synchronized (self) { + NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; + for (NSUInteger i = 0; i < numLogs; i++) { + NSString *file = [files objectAtIndex:i]; + NSString *filePath = [self.logFileDir stringByAppendingPathComponent:file]; + [self.fileHandler deleteFileAtPath:filePath]; + } } } - (void)addLogsToBuffer:(NSArray *)logs { @synchronized (self) { - NSMutableArray *existingLogs = [self readFromFileStorage]; - [existingLogs addObjectsFromArray:logs]; - NSUInteger logLength = [existingLogs count]; - if (logLength >= MAX_PERSISTED_BUFFER_SIZE) { - [existingLogs removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; + NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; + NSUInteger bufferSize = [files count]; + NSUInteger logLength = [logs count]; + if (bufferSize+logLength >= MAX_PERSISTED_BUFFER_SIZE) { + [self removeLogsFromBuffer:PURGE_AMOUNT]; RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; - [existingLogs insertObject:purgeLog atIndex:0]; + [self writeToFileStorage:@[purgeLog]]; } - [self writeToFileStorage:existingLogs]; + [self writeToFileStorage:logs]; } } -(void)clear { @synchronized (self) { - [self.fileHandler deleteFileAtPath:self.logFilePath]; + NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; + if(files){ + for (NSString *file in files) { + NSString *filePath = [self.logFileDir stringByAppendingPathComponent:file]; + [self.fileHandler deleteFileAtPath:filePath]; + } + } } } diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 2ec02bc61..b21156520 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -1416,15 +1416,21 @@ - (void)test_RadarFileStorage_WriteAndRead { XCTAssertEqualObjects(originalData2, readData, @"Data read from file should be equal to original data"); } -- (void)test_RadarFileStorage_Append { +- (void)test_RadarFileStorage_AllFilesInDirectory { + NSString *testDir = [NSTemporaryDirectory() stringByAppendingPathComponent:@"newDir"]; + if ([[NSFileManager defaultManager] fileExistsAtPath:testDir isDirectory:nil]) { + [[NSFileManager defaultManager] removeItemAtPath:testDir error:nil]; + } + [[NSFileManager defaultManager] createDirectoryAtPath:testDir withIntermediateDirectories:YES attributes:nil error:nil]; + + NSArray *files = [self.fileSystem allFilesInDirectory: testDir]; + XCTAssertEqual(files.count, 0); NSData *originalData = [@"Test data" dataUsingEncoding:NSUTF8StringEncoding]; - [self.fileSystem writeData:originalData toFileAtPath:self.testFilePath]; - NSData *appendData = [@"Newer Test data" dataUsingEncoding:NSUTF8StringEncoding]; - [self.fileSystem appendData:appendData toFileAtPath:self.testFilePath]; - NSData *readData = [self.fileSystem readFileAtPath:self.testFilePath]; - NSString *readString = [[NSString alloc] initWithData:readData encoding:NSUTF8StringEncoding]; - NSString *expectedString = @"Test dataNewer Test data"; - XCTAssertEqualObjects(readString, expectedString, @"Data read from file should be equal to original data"); + [self.fileSystem writeData:originalData toFileAtPath: [testDir stringByAppendingPathComponent: @"file1"]]; + [self.fileSystem writeData:originalData toFileAtPath: [testDir stringByAppendingPathComponent: @"file2"]]; + NSArray *newFiles = [self.fileSystem allFilesInDirectory: testDir]; + XCTAssertEqual(newFiles.count, 2); + } - (void)test_RadarFileStorage_DeleteFile { @@ -1436,6 +1442,7 @@ - (void)test_RadarFileStorage_DeleteFile { } - (void)test_RadarLogBuffer_WriteAndFlushableLogs { + [self.logBuffer clear]; RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; From b8038206c35332d357d24a3c89d527a261b823ff Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 7 Dec 2023 11:29:00 -0500 Subject: [PATCH 30/72] fixed pruging --- RadarSDK/RadarFileStorage.m | 6 +++++- RadarSDK/RadarLogBuffer.m | 22 +++++++++++----------- RadarSDKTests/RadarSDKTests.m | 11 +++++++++++ 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/RadarSDK/RadarFileStorage.m b/RadarSDK/RadarFileStorage.m index 1df71a050..20824acb5 100644 --- a/RadarSDK/RadarFileStorage.m +++ b/RadarSDK/RadarFileStorage.m @@ -49,7 +49,11 @@ - (void)deleteFileAtPath:(NSString *)filePath { return nil; } - return [files sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];; + //return [files sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];; + + return [files sortedArrayUsingComparator:^NSComparisonResult(NSString *str1, NSString *str2) { + return [@([str1 integerValue]) compare:@([str2 integerValue])]; + }]; } @end diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 125f6305c..a7b37a906 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -11,10 +11,9 @@ static const int MAX_PERSISTED_BUFFER_SIZE = 500; static const int MAX_MEMORY_BUFFER_SIZE = 200; -static const int PURGE_AMOUNT = 200; +static const int PURGE_AMOUNT = 250; static NSString *const kPurgedLogLine = @"----- purged oldest logs -----"; -static NSString *const kDelimiter = @"\?"; static int counter = 0; @@ -47,11 +46,13 @@ + (instancetype)sharedInstance { } - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { - RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; - [mutableLogBuffer addObject:radarLog]; - NSUInteger logLength = [mutableLogBuffer count]; - if (logLength >= MAX_MEMORY_BUFFER_SIZE) { - [self persistLogs]; + @synchronized (self) { + RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; + [mutableLogBuffer addObject:radarLog]; + NSUInteger logLength = [mutableLogBuffer count]; + if (logLength >= MAX_MEMORY_BUFFER_SIZE) { + [self persistLogs]; + } } } @@ -65,7 +66,6 @@ - (void)persistLogs { - (NSMutableArray *)readFromFileStorage { - NSLog(@"read from file storage"); NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; NSMutableArray *logs = [NSMutableArray array]; if(!files){ @@ -77,7 +77,6 @@ - (void)persistLogs { RadarLog *log = [NSKeyedUnarchiver unarchiveObjectWithData:fileData]; if(log && log.message){ [logs addObject:log]; - NSLog(@"log message: %@", log.message); } } @@ -89,9 +88,8 @@ - (void) writeToFileStorage:(NSArray *)logs { for(RadarLog *log in logs){ NSData *logData = [NSKeyedArchiver archivedDataWithRootObject:log]; NSTimeInterval unixTimestamp = [log.createdAt timeIntervalSince1970]; - NSString *unixTimestampString = [NSString stringWithFormat:@"%lld_%d", (long long)unixTimestamp,counter++]; + NSString *unixTimestampString = [NSString stringWithFormat:@"%lld%04d", (long long)unixTimestamp, counter++]; NSString *filePath = [self.logFileDir stringByAppendingPathComponent:unixTimestampString]; - NSLog(@"writing log message: %@", log.message); [self.fileHandler writeData:logData toFileAtPath:filePath]; } } @@ -135,8 +133,10 @@ - (void)addLogsToBuffer:(NSArray *)logs { } } +//for use in testing -(void)clear { @synchronized (self) { + [mutableLogBuffer removeAllObjects]; NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; if(files){ for (NSString *file in files) { diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index b21156520..50360ca82 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -1509,4 +1509,15 @@ - (void)test_RadarLogBuffer_append { XCTAssertEqualObjects(logs.lastObject.message, @"Test message 2"); } +- (void)test_purge { + [self.logBuffer clear]; + for (NSUInteger i = 0; i < 600; i++) { + [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:[NSString stringWithFormat:@"message_%d", i]]; + } + NSArray *logs = [self.logBuffer flushableLogs]; + XCTAssertEqual(logs.count, 351); + XCTAssertEqualObjects(logs.lastObject.message, @"----- purged oldest logs -----"); + XCTAssertEqualObjects(logs.firstObject.message, @"message_250"); +} + @end From 9696e9d79768889ad01b3c97ddf98563c0242e77 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 7 Dec 2023 11:40:40 -0500 Subject: [PATCH 31/72] cleanup --- RadarSDKTests/RadarSDKTests.m | 1 - 1 file changed, 1 deletion(-) diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 50360ca82..350a7f6a4 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -1510,7 +1510,6 @@ - (void)test_RadarLogBuffer_append { } - (void)test_purge { - [self.logBuffer clear]; for (NSUInteger i = 0; i < 600; i++) { [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:[NSString stringWithFormat:@"message_%d", i]]; } From 1e5853c3f23ea902e7d189ad5e6fa887f9871326 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 7 Dec 2023 11:42:32 -0500 Subject: [PATCH 32/72] rename clear --- RadarSDK/RadarLogBuffer.h | 2 +- RadarSDK/RadarLogBuffer.m | 2 +- RadarSDKTests/RadarSDKTests.m | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.h b/RadarSDK/RadarLogBuffer.h index f6de4a48f..5c632dfd0 100644 --- a/RadarSDK/RadarLogBuffer.h +++ b/RadarSDK/RadarLogBuffer.h @@ -27,7 +27,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)persistLogs; -- (void)clear; +- (void)clearBuffer; - (void)removeLogsFromBuffer:(NSUInteger)numLogs; diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index a7b37a906..39d99f272 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -134,7 +134,7 @@ - (void)addLogsToBuffer:(NSArray *)logs { } //for use in testing --(void)clear { +-(void)clearBuffer { @synchronized (self) { [mutableLogBuffer removeAllObjects]; NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 350a7f6a4..7e69a9f93 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -299,12 +299,12 @@ - (void)setUp { self.fileSystem = [[RadarFileStorage alloc] init]; self.testFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"testfile"]; self.logBuffer = [RadarLogBuffer sharedInstance]; - [self.logBuffer clear]; + [self.logBuffer clearBuffer]; } - (void)tearDown { [[NSFileManager defaultManager] removeItemAtPath:self.testFilePath error:nil]; - [self.logBuffer clear]; + [self.logBuffer clearBuffer]; [super tearDown]; } @@ -1442,7 +1442,6 @@ - (void)test_RadarFileStorage_DeleteFile { } - (void)test_RadarLogBuffer_WriteAndFlushableLogs { - [self.logBuffer clear]; RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; @@ -1515,8 +1514,9 @@ - (void)test_purge { } NSArray *logs = [self.logBuffer flushableLogs]; XCTAssertEqual(logs.count, 351); - XCTAssertEqualObjects(logs.lastObject.message, @"----- purged oldest logs -----"); XCTAssertEqualObjects(logs.firstObject.message, @"message_250"); + + XCTAssertEqualObjects(logs.lastObject.message, @"message_599"); } @end From a88c7cae9a74161bbcc3fb4cf75df0093fa6d662 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 7 Dec 2023 11:45:20 -0500 Subject: [PATCH 33/72] rename enterbackground --- RadarSDK/Include/Radar.h | 2 +- RadarSDK/Radar.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/RadarSDK/Include/Radar.h b/RadarSDK/Include/Radar.h index b1e68405e..67dfcbef6 100644 --- a/RadarSDK/Include/Radar.h +++ b/RadarSDK/Include/Radar.h @@ -1020,7 +1020,7 @@ logConversionWithNotification Log application entering background and flush logs in memory buffer into persistent buffer. */ -+ (void)logEnteringBackground; ++ (void)logEnterBackground; /** Log application resigning active. diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index 4d0e25446..6ea19055f 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1046,7 +1046,7 @@ + (void) logTermination { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminated" includeDate:YES includeBattery:YES append:YES]; } -+ (void) logEnteringBackground { ++ (void) logEnterBackground { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background" includeDate:YES includeBattery:YES append:YES]; [[RadarLogBuffer sharedInstance] persistLogs ]; } From 4ad675176e9c311ef0cb810913a428b0dcef695d Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 7 Dec 2023 12:03:12 -0500 Subject: [PATCH 34/72] update testing --- RadarSDKTests/RadarSDKTests.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 7e69a9f93..21db99fd3 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -1515,8 +1515,7 @@ - (void)test_purge { NSArray *logs = [self.logBuffer flushableLogs]; XCTAssertEqual(logs.count, 351); XCTAssertEqualObjects(logs.firstObject.message, @"message_250"); - - XCTAssertEqualObjects(logs.lastObject.message, @"message_599"); + XCTAssertEqualObjects(logs.lastObject.message, @"----- purged oldest logs -----"); } @end From 05d81c2006d43b192f2c92e38127f9188d428340 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 7 Dec 2023 12:09:09 -0500 Subject: [PATCH 35/72] remove write local log --- RadarSDK/Include/Radar.h | 7 ------- RadarSDK/Radar.m | 5 ----- 2 files changed, 12 deletions(-) diff --git a/RadarSDK/Include/Radar.h b/RadarSDK/Include/Radar.h index 67dfcbef6..e6992e12e 100644 --- a/RadarSDK/Include/Radar.h +++ b/RadarSDK/Include/Radar.h @@ -1003,13 +1003,6 @@ logConversionWithNotification */ + (void)setLogLevel:(RadarLogLevel)level; -/** - Writes to local logs. - - @param message The message to be logged. - */ -+ (void)writeLocalLog:(NSString *_Nonnull)message; - /** Log application termination. diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index 6ea19055f..55745bf7d 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1037,11 +1037,6 @@ + (void)setLogLevel:(RadarLogLevel)level { [RadarSettings setLogLevel:level]; } -+ (void)writeLocalLog:(NSString *)message { - [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:message]; - -} - + (void) logTermination { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminated" includeDate:YES includeBattery:YES append:YES]; } From 6445fd075c02fd3ca58fcf57911f8375565f3932 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 7 Dec 2023 12:14:46 -0500 Subject: [PATCH 36/72] foramtting --- RadarSDK/Radar.m | 6 +++--- RadarSDK/RadarFileStorage.m | 2 -- RadarSDK/RadarLogBuffer.m | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index 55745bf7d..d68a891c4 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1037,16 +1037,16 @@ + (void)setLogLevel:(RadarLogLevel)level { [RadarSettings setLogLevel:level]; } -+ (void) logTermination { ++ (void)logTermination { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminated" includeDate:YES includeBattery:YES append:YES]; } -+ (void) logEnterBackground { ++ (void)logEnterBackground { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background" includeDate:YES includeBattery:YES append:YES]; [[RadarLogBuffer sharedInstance] persistLogs ]; } -+ (void) logResignActive { ++ (void)logResignActive { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App resigning active" includeDate:YES includeBattery:YES]; } diff --git a/RadarSDK/RadarFileStorage.m b/RadarSDK/RadarFileStorage.m index 20824acb5..2ae31dd38 100644 --- a/RadarSDK/RadarFileStorage.m +++ b/RadarSDK/RadarFileStorage.m @@ -49,8 +49,6 @@ - (void)deleteFileAtPath:(NSString *)filePath { return nil; } - //return [files sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];; - return [files sortedArrayUsingComparator:^NSComparisonResult(NSString *str1, NSString *str2) { return [@([str1 integerValue]) compare:@([str2 integerValue])]; }]; diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 39d99f272..18967e69a 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -84,7 +84,7 @@ - (void)persistLogs { } - - (void) writeToFileStorage:(NSArray *)logs { + - (void)writeToFileStorage:(NSArray *)logs { for(RadarLog *log in logs){ NSData *logData = [NSKeyedArchiver archivedDataWithRootObject:log]; NSTimeInterval unixTimestamp = [log.createdAt timeIntervalSince1970]; @@ -94,7 +94,7 @@ - (void) writeToFileStorage:(NSArray *)logs { } } -- (void) append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { +- (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { @synchronized (self) { [self writeToFileStorage:@[[[RadarLog alloc] initWithLevel:level type:type message:message]]]; } From c62d1b59881c0e671d5d3904390531e30c9639fc Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 7 Dec 2023 12:20:15 -0500 Subject: [PATCH 37/72] remove dead code --- RadarSDK/Radar.m | 2 -- RadarSDK/RadarLog.h | 2 -- RadarSDK/RadarLog.m | 54 --------------------------------------------- 3 files changed, 58 deletions(-) diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index d68a891c4..d671beb8f 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1273,7 +1273,6 @@ + (void)flushLogs { NSArray *flushableLogs = [[RadarLogBuffer sharedInstance] flushableLogs]; - NSUInteger pendingLogCount = [flushableLogs count]; if (pendingLogCount == 0) { return; @@ -1289,7 +1288,6 @@ + (void)flushLogs { } }; - [[RadarAPIClient sharedInstance] syncLogs:flushableLogs completionHandler:^(RadarStatus status) { if (onComplete) { diff --git a/RadarSDK/RadarLog.h b/RadarSDK/RadarLog.h index 4a162e04d..c066e2e77 100644 --- a/RadarSDK/RadarLog.h +++ b/RadarSDK/RadarLog.h @@ -36,8 +36,6 @@ - (NSDictionary *_Nonnull)dictionaryValue; -- (instancetype _Nullable)initWithDictionary:(NSDictionary *_Nonnull)dictionary; - + (NSArray *_Nullable)arrayForLogs:(NSArray *_Nullable)logs; /** diff --git a/RadarSDK/RadarLog.m b/RadarSDK/RadarLog.m index 2b55e8f39..7defdf166 100644 --- a/RadarSDK/RadarLog.m +++ b/RadarSDK/RadarLog.m @@ -68,29 +68,6 @@ + (NSString *)stringForLogType:(RadarLogType)type { return str; } -+ (RadarLogLevel)logLevelForString:(NSString *)string { - NSDictionary *logLevelMap = @{ - @"none" : @(RadarLogLevelNone), - @"error" : @(RadarLogLevelError), - @"warning" : @(RadarLogLevelWarning), - @"info" : @(RadarLogLevelInfo), - @"debug" : @(RadarLogLevelDebug) - }; - return logLevelMap[string].integerValue; -} - -+ (RadarLogType)logTypeForString:(NSString *)string { - NSDictionary *logTypeMap = @{ - @"NONE" : @(RadarLogTypeNone), - @"SDK_CALL" : @(RadarLogTypeSDKCall), - @"SDK_ERROR" : @(RadarLogTypeSDKError), - @"SDK_EXCEPTION" : @(RadarLogTypeSDKException), - @"APP_LIFECYCLE_EVENT" : @(RadarLogTypeAppLifecycleEvent), - @"PERMISSION_EVENT" : @(RadarLogTypePermissionEvent) - }; - return logTypeMap[string].integerValue; -} - - (NSDictionary *)dictionaryValue { NSMutableDictionary *dict = [NSMutableDictionary new]; dict[@"level"] = [RadarLog stringForLogLevel:self.level]; @@ -104,17 +81,6 @@ - (NSDictionary *)dictionaryValue { return dict; } -- (instancetype)initWithDictionary:(NSDictionary *)dictionary { - self = [super init]; - if (self) { - _level = [RadarLog logLevelForString:dictionary[@"level"]]; - _type = [RadarLog logTypeForString:dictionary[@"type"]]; - _message = dictionary[@"message"]; - _createdAt = [RadarUtils.isoDateFormatter dateFromString:dictionary[@"createdAt"]]; - } - return self; -} - + (NSArray *)arrayForLogs:(NSArray *)logs { if (!logs) { return nil; @@ -128,25 +94,5 @@ - (instancetype)initWithDictionary:(NSDictionary *)dictionary { return arr; } -#pragma mark - NSCoding - -- (instancetype)initWithCoder:(NSCoder *)coder { - self = [super init]; - if (self) { - _level = [coder decodeIntegerForKey:@"level"]; - _type = [coder decodeIntegerForKey:@"type"]; - _message = [coder decodeObjectForKey:@"message"]; - _createdAt = [coder decodeObjectForKey:@"createdAt"]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)coder { - [coder encodeInteger:_level forKey:@"level"]; - [coder encodeInteger:_type forKey:@"type"]; - [coder encodeObject:_message forKey:@"message"]; - [coder encodeObject:_createdAt forKey:@"createdAt"]; -} - @end From f58291b49e1e04c55d8f3c5b7656d998795be802 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 7 Dec 2023 12:21:41 -0500 Subject: [PATCH 38/72] add nscoding back --- RadarSDK/RadarLog.m | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/RadarSDK/RadarLog.m b/RadarSDK/RadarLog.m index 7defdf166..c747dcd50 100644 --- a/RadarSDK/RadarLog.m +++ b/RadarSDK/RadarLog.m @@ -94,5 +94,24 @@ - (NSDictionary *)dictionaryValue { return arr; } +#pragma mark - NSCoding + +- (instancetype)initWithCoder:(NSCoder *)coder { + self = [super init]; + if (self) { + _level = [coder decodeIntegerForKey:@"level"]; + _type = [coder decodeIntegerForKey:@"type"]; + _message = [coder decodeObjectForKey:@"message"]; + _createdAt = [coder decodeObjectForKey:@"createdAt"]; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeInteger:_level forKey:@"level"]; + [coder encodeInteger:_type forKey:@"type"]; + [coder encodeObject:_message forKey:@"message"]; + [coder encodeObject:_createdAt forKey:@"createdAt"]; +} @end From 9f4bff5ebfeb85349aa02f2b36683a8c80e9e3fe Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 7 Dec 2023 12:25:12 -0500 Subject: [PATCH 39/72] remove dead code --- RadarSDK/RadarLogger.h | 3 --- RadarSDK/RadarLogger.m | 6 ------ 2 files changed, 9 deletions(-) diff --git a/RadarSDK/RadarLogger.h b/RadarSDK/RadarLogger.h index 34bb645bc..d334e6540 100644 --- a/RadarSDK/RadarLogger.h +++ b/RadarSDK/RadarLogger.h @@ -8,14 +8,11 @@ #import #import "RadarDelegate.h" -#import "RadarFileStorage.h" NS_ASSUME_NONNULL_BEGIN @interface RadarLogger : NSObject -@property (strong, nonatomic) NSString *logFilePath; -@property (strong, nonatomic) RadarFileStorage *fileHandler; @property (strong, nonatomic) NSDateFormatter *dateFormatter; @property (strong, nonatomic) UIDevice *device; diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index 739840c5e..c022fea46 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -11,7 +11,6 @@ #import "RadarSettings.h" #import "RadarUtils.h" #import -#import "RadarFileStorage.h" #import "RadarLog.h" #import "RadarLogBuffer.h" @@ -29,11 +28,6 @@ + (instancetype)sharedInstance { - (instancetype)init { self = [super init]; if (self) { - // Set the default log file path - NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; - NSString *logFileName = @"RadarLogs.txt"; - self.logFilePath = [documentsDirectory stringByAppendingPathComponent:logFileName]; - self.fileHandler = [[RadarFileStorage alloc] init]; self.dateFormatter = [[NSDateFormatter alloc] init]; [self.dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; self.device = [UIDevice currentDevice]; From f67115eaf37ccc304676fcaffd8cdd910c0e9807 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 7 Dec 2023 12:29:41 -0500 Subject: [PATCH 40/72] spacing --- RadarSDK/RadarLogBuffer.m | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 18967e69a..efa26b3c3 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -81,11 +81,10 @@ - (void)persistLogs { } return logs; - } - (void)writeToFileStorage:(NSArray *)logs { - for(RadarLog *log in logs){ + for (RadarLog *log in logs) { NSData *logData = [NSKeyedArchiver archivedDataWithRootObject:log]; NSTimeInterval unixTimestamp = [log.createdAt timeIntervalSince1970]; NSString *unixTimestampString = [NSString stringWithFormat:@"%lld%04d", (long long)unixTimestamp, counter++]; @@ -127,7 +126,7 @@ - (void)addLogsToBuffer:(NSArray *)logs { if (bufferSize+logLength >= MAX_PERSISTED_BUFFER_SIZE) { [self removeLogsFromBuffer:PURGE_AMOUNT]; RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; - [self writeToFileStorage:@[purgeLog]]; + [self writeToFileStorage:@[purgeLog]]; } [self writeToFileStorage:logs]; } @@ -138,7 +137,7 @@ -(void)clearBuffer { @synchronized (self) { [mutableLogBuffer removeAllObjects]; NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; - if(files){ + if (files) { for (NSString *file in files) { NSString *filePath = [self.logFileDir stringByAppendingPathComponent:file]; [self.fileHandler deleteFileAtPath:filePath]; From 8120e63cf552e84029c90801209949f1840abfe0 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 7 Dec 2023 13:10:07 -0500 Subject: [PATCH 41/72] spacing --- RadarSDK/RadarLogBuffer.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index efa26b3c3..f0b314d86 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -84,13 +84,13 @@ - (void)persistLogs { } - (void)writeToFileStorage:(NSArray *)logs { - for (RadarLog *log in logs) { + for (RadarLog *log in logs) { NSData *logData = [NSKeyedArchiver archivedDataWithRootObject:log]; NSTimeInterval unixTimestamp = [log.createdAt timeIntervalSince1970]; NSString *unixTimestampString = [NSString stringWithFormat:@"%lld%04d", (long long)unixTimestamp, counter++]; NSString *filePath = [self.logFileDir stringByAppendingPathComponent:unixTimestampString]; [self.fileHandler writeData:logData toFileAtPath:filePath]; - } + } } - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { From daaea6e73bdea3f5b7c9b4438398f101195a8c9c Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Fri, 8 Dec 2023 09:35:37 -0500 Subject: [PATCH 42/72] add array iteration safety --- RadarSDK/RadarLogBuffer.m | 8 ++++++-- RadarSDKTests/RadarSDKTests.m | 14 +++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index f0b314d86..8796e5cf7 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -110,7 +110,8 @@ - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *) - (void)removeLogsFromBuffer:(NSUInteger)numLogs { @synchronized (self) { NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; - for (NSUInteger i = 0; i < numLogs; i++) { + numLogs = MIN(numLogs, [files count]); + for (NSUInteger i = 0; i < (numLogs); i++) { NSString *file = [files objectAtIndex:i]; NSString *filePath = [self.logFileDir stringByAppendingPathComponent:file]; [self.fileHandler deleteFileAtPath:filePath]; @@ -123,8 +124,11 @@ - (void)addLogsToBuffer:(NSArray *)logs { NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; NSUInteger bufferSize = [files count]; NSUInteger logLength = [logs count]; - if (bufferSize+logLength >= MAX_PERSISTED_BUFFER_SIZE) { + while (bufferSize+logLength >= MAX_PERSISTED_BUFFER_SIZE) { [self removeLogsFromBuffer:PURGE_AMOUNT]; + files = [self.fileHandler allFilesInDirectory:self.logFileDir]; + bufferSize = [files count]; + logLength = [logs count]; RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; [self writeToFileStorage:@[purgeLog]]; } diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 21db99fd3..ca5429303 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -1407,7 +1407,7 @@ - (void)test_RadarTrackingOptions_isEqual { XCTAssertNotEqualObjects(options, @"foo"); } -- (void)test_RadarFileStorage_WriteAndRead { +- (void)test_RadarFileStorage_writeAndRead { NSData *originalData = [@"Test data" dataUsingEncoding:NSUTF8StringEncoding]; [self.fileSystem writeData:originalData toFileAtPath:self.testFilePath]; NSData *originalData2 = [@"Newer Test data" dataUsingEncoding:NSUTF8StringEncoding]; @@ -1416,7 +1416,7 @@ - (void)test_RadarFileStorage_WriteAndRead { XCTAssertEqualObjects(originalData2, readData, @"Data read from file should be equal to original data"); } -- (void)test_RadarFileStorage_AllFilesInDirectory { +- (void)test_RadarFileStorage_allFilesInDirectory { NSString *testDir = [NSTemporaryDirectory() stringByAppendingPathComponent:@"newDir"]; if ([[NSFileManager defaultManager] fileExistsAtPath:testDir isDirectory:nil]) { [[NSFileManager defaultManager] removeItemAtPath:testDir error:nil]; @@ -1433,7 +1433,7 @@ - (void)test_RadarFileStorage_AllFilesInDirectory { } -- (void)test_RadarFileStorage_DeleteFile { +- (void)test_RadarFileStorage_deleteFile { NSData *originalData = [@"Test data" dataUsingEncoding:NSUTF8StringEncoding]; [self.fileSystem writeData:originalData toFileAtPath:self.testFilePath]; [self.fileSystem deleteFileAtPath:self.testFilePath]; @@ -1441,7 +1441,7 @@ - (void)test_RadarFileStorage_DeleteFile { XCTAssertNil(readData, @"Data read from file should be nil after file is deleted"); } -- (void)test_RadarLogBuffer_WriteAndFlushableLogs { +- (void)test_RadarLogBuffer_writeAndFlushableLogs { RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; @@ -1457,7 +1457,7 @@ - (void)test_RadarLogBuffer_WriteAndFlushableLogs { XCTAssertEqualObjects(newLogs.lastObject.message, @"Test message 3"); } -- (void)test_RadarLogBuffer_RemoveLogsFromBuffer { +- (void)test_RadarLogBuffer_removeLogsFromBuffer { RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; @@ -1467,7 +1467,7 @@ - (void)test_RadarLogBuffer_RemoveLogsFromBuffer { XCTAssertEqual(logs.count, 0); } -- (void)test_RadarLogBuffer_AddLogsToBuffrer { +- (void)test_RadarLogBuffer_addLogsToBuffrer { RadarLog *log1 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; RadarLog *log2 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; RadarLog *log3 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 3"]; @@ -1508,7 +1508,7 @@ - (void)test_RadarLogBuffer_append { XCTAssertEqualObjects(logs.lastObject.message, @"Test message 2"); } -- (void)test_purge { +- (void)test_RadarLogBuffer_purge { for (NSUInteger i = 0; i < 600; i++) { [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:[NSString stringWithFormat:@"message_%d", i]]; } From 15c4eae9eaf963f558f715e3512295ee51c81769 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Mon, 11 Dec 2023 11:51:24 -0500 Subject: [PATCH 43/72] added feature flag --- RadarSDK/RadarFeatureSettings.h | 4 +- RadarSDK/RadarFeatureSettings.m | 16 ++++- RadarSDK/RadarLogBuffer.m | 114 ++++++++++++++++++++++---------- RadarSDKTests/RadarSDKTests.m | 5 +- 4 files changed, 99 insertions(+), 40 deletions(-) diff --git a/RadarSDK/RadarFeatureSettings.h b/RadarSDK/RadarFeatureSettings.h index ddc3659b4..141dd7256 100644 --- a/RadarSDK/RadarFeatureSettings.h +++ b/RadarSDK/RadarFeatureSettings.h @@ -21,6 +21,7 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, assign) BOOL usePersistence; @property (nonatomic, assign) BOOL extendFlushReplays; +@property (nonatomic, assign) BOOL useLogPersistence; /** Initializes a new RadarFeatureSettings object with given value. @@ -28,7 +29,8 @@ NS_ASSUME_NONNULL_BEGIN @param usePersistence A flag indicating whether to use persistence. */ - (instancetype)initWithUsePersistence:(BOOL)usePersistence - extendFlushReplays:(BOOL)extendFlushReplays; + extendFlushReplays:(BOOL)extendFlushReplays + useLogPersistence:(BOOL)useLogPersistence; /** Creates a RadarFeatureSettings object from the provided dictionary. diff --git a/RadarSDK/RadarFeatureSettings.m b/RadarSDK/RadarFeatureSettings.m index cdb759462..9455a312f 100644 --- a/RadarSDK/RadarFeatureSettings.m +++ b/RadarSDK/RadarFeatureSettings.m @@ -10,17 +10,19 @@ @implementation RadarFeatureSettings - (instancetype)initWithUsePersistence:(BOOL)usePersistence - extendFlushReplays:(BOOL)extendFlushReplays { + extendFlushReplays:(BOOL)extendFlushReplays + useLogPersistence:(BOOL)useLogPersistence { if (self = [super init]) { _usePersistence = usePersistence; _extendFlushReplays = extendFlushReplays; + _useLogPersistence = useLogPersistence; } return self; } + (RadarFeatureSettings *_Nullable)featureSettingsFromDictionary:(NSDictionary *)dict { if (!dict) { - return [[RadarFeatureSettings alloc] initWithUsePersistence:NO extendFlushReplays:NO]; + return [[RadarFeatureSettings alloc] initWithUsePersistence:NO extendFlushReplays:NO useLogPersistence:NO]; } NSObject *usePersistenceObj = dict[@"usePersistence"]; @@ -34,13 +36,21 @@ + (RadarFeatureSettings *_Nullable)featureSettingsFromDictionary:(NSDictionary * if (extendFlushReplaysObj && [extendFlushReplaysObj isKindOfClass:[NSNumber class]]) { extendFlushReplays = [(NSNumber *)extendFlushReplaysObj boolValue]; } - return [[RadarFeatureSettings alloc] initWithUsePersistence:usePersistence extendFlushReplays:extendFlushReplays]; + + NSObject *useLogPersistenceObj = dict[@"useLogPersistence"]; + BOOL useLogPersistence = NO; + if (useLogPersistenceObj && [useLogPersistenceObj isKindOfClass:[NSNumber class]]) { + useLogPersistence = [(NSNumber *)useLogPersistenceObj boolValue]; + } + + return [[RadarFeatureSettings alloc] initWithUsePersistence:usePersistence extendFlushReplays:extendFlushReplays useLogPersistence:useLogPersistence]; } - (NSDictionary *)dictionaryValue { NSMutableDictionary *dict = [NSMutableDictionary new]; [dict setValue:@(self.usePersistence) forKey:@"usePersistence"]; [dict setValue:@(self.extendFlushReplays) forKey:@"extendFlushReplays"]; + [dict setValue:@(self.useLogPersistence) forKey:@"useLogPersistence"]; return dict; } diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 8796e5cf7..fc267d32f 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -8,10 +8,12 @@ #import "RadarLogBuffer.h" #import "RadarLog.h" #import "RadarFileStorage.h" +#import "RadarSettings.h" static const int MAX_PERSISTED_BUFFER_SIZE = 500; static const int MAX_MEMORY_BUFFER_SIZE = 200; static const int PURGE_AMOUNT = 250; +static const int MAX_BUFFER_SIZE = 500; static NSString *const kPurgedLogLine = @"----- purged oldest logs -----"; @@ -19,19 +21,24 @@ @implementation RadarLogBuffer { NSMutableArray *mutableLogBuffer; + BOOL useLogPersistence; } - (instancetype)init { self = [super init]; if (self) { + RadarFeatureSettings *featureSettings = [RadarSettings featureSettings]; + useLogPersistence = featureSettings.useLogPersistence; mutableLogBuffer = [NSMutableArray new]; - NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; - self.logFileDir = [documentsDirectory stringByAppendingPathComponent:@"radar_logs"]; - if (![[NSFileManager defaultManager] fileExistsAtPath:self.logFileDir isDirectory:nil]) { + if (useLogPersistence) { + NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; + self.logFileDir = [documentsDirectory stringByAppendingPathComponent:@"radar_logs"]; + if (![[NSFileManager defaultManager] fileExistsAtPath:self.logFileDir isDirectory:nil]) { [[NSFileManager defaultManager] createDirectoryAtPath:self.logFileDir withIntermediateDirectories:YES attributes:nil error:nil]; } - self.fileHandler = [[RadarFileStorage alloc] init]; - _timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(persistLogs) userInfo:nil repeats:YES]; + self.fileHandler = [[RadarFileStorage alloc] init]; + _timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(persistLogs) userInfo:nil repeats:YES]; + } } return self; } @@ -46,21 +53,34 @@ + (instancetype)sharedInstance { } - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { - @synchronized (self) { - RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; - [mutableLogBuffer addObject:radarLog]; - NSUInteger logLength = [mutableLogBuffer count]; - if (logLength >= MAX_MEMORY_BUFFER_SIZE) { - [self persistLogs]; + @synchronized (self) { + if (useLogPersistence) { + RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; + [mutableLogBuffer addObject:radarLog]; + NSUInteger logLength = [mutableLogBuffer count]; + if (logLength >= MAX_MEMORY_BUFFER_SIZE) { + [self persistLogs]; + } } + else { + NSUInteger logLength = [mutableLogBuffer count]; + if (logLength >= MAX_BUFFER_SIZE) { + [self purgeOldestLogs]; + } + // add new log to buffer + RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; + [mutableLogBuffer addObject:radarLog]; + } } } - (void)persistLogs { - @synchronized (self) { - NSArray *flushableLogs = [mutableLogBuffer copy]; - [self addLogsToBuffer:flushableLogs]; - [mutableLogBuffer removeAllObjects]; + @synchronized (self) { + if (useLogPersistence) { + NSArray *flushableLogs = [mutableLogBuffer copy]; + [self addLogsToBuffer:flushableLogs]; + [mutableLogBuffer removeAllObjects]; + } } } @@ -95,44 +115,70 @@ - (void)writeToFileStorage:(NSArray *)logs { - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { @synchronized (self) { - [self writeToFileStorage:@[[[RadarLog alloc] initWithLevel:level type:type message:message]]]; + if (useLogPersistence){ + [self writeToFileStorage:@[[[RadarLog alloc] initWithLevel:level type:type message:message]]]; + } + else { + [self write:level type:type message:message]; + } } } - (NSArray *)flushableLogs { @synchronized (self) { - [self persistLogs]; - NSArray *existingLogsArray = [self.readFromFileStorage copy]; - return existingLogsArray; + if (useLogPersistence) { + [self persistLogs]; + NSArray *existingLogsArray = [self.readFromFileStorage copy]; + return existingLogsArray; + } else { + NSArray *flushableLogs = [mutableLogBuffer copy]; + return flushableLogs; + } } } +- (void)purgeOldestLogs { + // drop the oldest N logs from the buffer + [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; + RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; + [mutableLogBuffer insertObject:purgeLog atIndex:0]; +} + + - (void)removeLogsFromBuffer:(NSUInteger)numLogs { - @synchronized (self) { - NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; - numLogs = MIN(numLogs, [files count]); - for (NSUInteger i = 0; i < (numLogs); i++) { + @synchronized (self) { + if (useLogPersistence) { + NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; + numLogs = MIN(numLogs, [files count]); + for (NSUInteger i = 0; i < (numLogs); i++) { NSString *file = [files objectAtIndex:i]; NSString *filePath = [self.logFileDir stringByAppendingPathComponent:file]; [self.fileHandler deleteFileAtPath:filePath]; + } + } else { + [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, numLogs)]; } } } - (void)addLogsToBuffer:(NSArray *)logs { @synchronized (self) { - NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; - NSUInteger bufferSize = [files count]; - NSUInteger logLength = [logs count]; - while (bufferSize+logLength >= MAX_PERSISTED_BUFFER_SIZE) { - [self removeLogsFromBuffer:PURGE_AMOUNT]; - files = [self.fileHandler allFilesInDirectory:self.logFileDir]; - bufferSize = [files count]; - logLength = [logs count]; - RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; - [self writeToFileStorage:@[purgeLog]]; + if (useLogPersistence) { + NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; + NSUInteger bufferSize = [files count]; + NSUInteger logLength = [logs count]; + while (bufferSize+logLength >= MAX_PERSISTED_BUFFER_SIZE) { + [self removeLogsFromBuffer:PURGE_AMOUNT]; + files = [self.fileHandler allFilesInDirectory:self.logFileDir]; + bufferSize = [files count]; + logLength = [logs count]; + RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; + [self writeToFileStorage:@[purgeLog]]; + } + [self writeToFileStorage:logs]; + } else { + [mutableLogBuffer addObjectsFromArray:logs]; } - [self writeToFileStorage:logs]; } } diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index ca5429303..566217b51 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -300,6 +300,7 @@ - (void)setUp { self.testFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"testfile"]; self.logBuffer = [RadarLogBuffer sharedInstance]; [self.logBuffer clearBuffer]; + [RadarSettings setFeatureSettings: [[RadarFeatureSettings alloc] initWithUsePersistence:YES extendFlushReplays:YES useLogPersistence:YES]]; } - (void)tearDown { @@ -1442,7 +1443,6 @@ - (void)test_RadarFileStorage_deleteFile { } - (void)test_RadarLogBuffer_writeAndFlushableLogs { - RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; [self.logBuffer persistLogs]; @@ -1458,7 +1458,6 @@ - (void)test_RadarLogBuffer_writeAndFlushableLogs { } - (void)test_RadarLogBuffer_removeLogsFromBuffer { - RadarLog *log = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; [self.logBuffer persistLogs]; @@ -1509,6 +1508,7 @@ - (void)test_RadarLogBuffer_append { } - (void)test_RadarLogBuffer_purge { + [self.logBuffer clearBuffer]; for (NSUInteger i = 0; i < 600; i++) { [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:[NSString stringWithFormat:@"message_%d", i]]; } @@ -1516,6 +1516,7 @@ - (void)test_RadarLogBuffer_purge { XCTAssertEqual(logs.count, 351); XCTAssertEqualObjects(logs.firstObject.message, @"message_250"); XCTAssertEqualObjects(logs.lastObject.message, @"----- purged oldest logs -----"); + [self.logBuffer clearBuffer]; } @end From 81e1404cfe8649a9a5c363dd830882740f3939c1 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Mon, 11 Dec 2023 13:02:26 -0500 Subject: [PATCH 44/72] fixed tests --- RadarSDK/RadarLogBuffer.m | 4 ++-- RadarSDKTests/RadarSDKTests.m | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index fc267d32f..1b803bf67 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -38,7 +38,7 @@ - (instancetype)init { } self.fileHandler = [[RadarFileStorage alloc] init]; _timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(persistLogs) userInfo:nil repeats:YES]; - } + } } return self; } @@ -185,7 +185,7 @@ - (void)addLogsToBuffer:(NSArray *)logs { //for use in testing -(void)clearBuffer { @synchronized (self) { - [mutableLogBuffer removeAllObjects]; + [mutableLogBuffer removeAllObjects]; NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; if (files) { for (NSString *file in files) { diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 566217b51..e4875ba9c 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -283,7 +283,7 @@ - (void)assertRoutesOk:(RadarRoutes *)routes { - (void)setUp { [super setUp]; - + [RadarSettings setFeatureSettings: [[RadarFeatureSettings alloc] initWithUsePersistence:YES extendFlushReplays:YES useLogPersistence:YES]]; [Radar initializeWithPublishableKey:kPublishableKey]; [Radar setLogLevel:RadarLogLevelDebug]; @@ -300,7 +300,7 @@ - (void)setUp { self.testFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"testfile"]; self.logBuffer = [RadarLogBuffer sharedInstance]; [self.logBuffer clearBuffer]; - [RadarSettings setFeatureSettings: [[RadarFeatureSettings alloc] initWithUsePersistence:YES extendFlushReplays:YES useLogPersistence:YES]]; + } - (void)tearDown { From 40ecb97bd39e7df6f4c92131b48e2837cff532e4 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Mon, 11 Dec 2023 13:18:24 -0500 Subject: [PATCH 45/72] changed way feature flag worked --- RadarSDK/RadarLogBuffer.m | 43 ++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 1b803bf67..9bafd6c02 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -21,6 +21,7 @@ @implementation RadarLogBuffer { NSMutableArray *mutableLogBuffer; + NSMutableArray *inMemoryLogBuffer; BOOL useLogPersistence; } @@ -30,6 +31,7 @@ - (instancetype)init { RadarFeatureSettings *featureSettings = [RadarSettings featureSettings]; useLogPersistence = featureSettings.useLogPersistence; mutableLogBuffer = [NSMutableArray new]; + inMemoryLogBuffer = [NSMutableArray new]; if (useLogPersistence) { NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; self.logFileDir = [documentsDirectory stringByAppendingPathComponent:@"radar_logs"]; @@ -54,32 +56,31 @@ + (instancetype)sharedInstance { - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { @synchronized (self) { + NSUInteger logLength = [mutableLogBuffer count]; + if (logLength >= MAX_BUFFER_SIZE) { + [self purgeOldestLogs]; + } + // add new log to buffer + RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; + [mutableLogBuffer addObject:radarLog]; + if (useLogPersistence) { RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; - [mutableLogBuffer addObject:radarLog]; - NSUInteger logLength = [mutableLogBuffer count]; + [inMemoryLogBuffer addObject:radarLog]; + NSUInteger logLength = [inMemoryLogBuffer count]; if (logLength >= MAX_MEMORY_BUFFER_SIZE) { [self persistLogs]; } - } - else { - NSUInteger logLength = [mutableLogBuffer count]; - if (logLength >= MAX_BUFFER_SIZE) { - [self purgeOldestLogs]; - } - // add new log to buffer - RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; - [mutableLogBuffer addObject:radarLog]; - } + } } } - (void)persistLogs { @synchronized (self) { if (useLogPersistence) { - NSArray *flushableLogs = [mutableLogBuffer copy]; + NSArray *flushableLogs = [inMemoryLogBuffer copy]; [self addLogsToBuffer:flushableLogs]; - [mutableLogBuffer removeAllObjects]; + [inMemoryLogBuffer removeAllObjects]; } } } @@ -115,12 +116,10 @@ - (void)writeToFileStorage:(NSArray *)logs { - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { @synchronized (self) { + [self write:level type:type message:message]; if (useLogPersistence){ [self writeToFileStorage:@[[[RadarLog alloc] initWithLevel:level type:type message:message]]]; } - else { - [self write:level type:type message:message]; - } } } @@ -147,6 +146,7 @@ - (void)purgeOldestLogs { - (void)removeLogsFromBuffer:(NSUInteger)numLogs { @synchronized (self) { + [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, numLogs)]; if (useLogPersistence) { NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; numLogs = MIN(numLogs, [files count]); @@ -155,14 +155,13 @@ - (void)removeLogsFromBuffer:(NSUInteger)numLogs { NSString *filePath = [self.logFileDir stringByAppendingPathComponent:file]; [self.fileHandler deleteFileAtPath:filePath]; } - } else { - [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, numLogs)]; } } } - (void)addLogsToBuffer:(NSArray *)logs { @synchronized (self) { + [mutableLogBuffer addObjectsFromArray:logs]; if (useLogPersistence) { NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; NSUInteger bufferSize = [files count]; @@ -176,16 +175,14 @@ - (void)addLogsToBuffer:(NSArray *)logs { [self writeToFileStorage:@[purgeLog]]; } [self writeToFileStorage:logs]; - } else { - [mutableLogBuffer addObjectsFromArray:logs]; - } + } } } //for use in testing -(void)clearBuffer { @synchronized (self) { - [mutableLogBuffer removeAllObjects]; + [inMemoryLogBuffer removeAllObjects]; NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; if (files) { for (NSString *file in files) { From 7d09273604fa92dcb0bc019e8d6eafd74a670d63 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Mon, 11 Dec 2023 13:26:21 -0500 Subject: [PATCH 46/72] changed to default true --- RadarSDK/RadarFeatureSettings.m | 2 +- RadarSDK/RadarLogBuffer.m | 33 +++++++++++++++------------------ 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/RadarSDK/RadarFeatureSettings.m b/RadarSDK/RadarFeatureSettings.m index 9455a312f..78a50aedc 100644 --- a/RadarSDK/RadarFeatureSettings.m +++ b/RadarSDK/RadarFeatureSettings.m @@ -38,7 +38,7 @@ + (RadarFeatureSettings *_Nullable)featureSettingsFromDictionary:(NSDictionary * } NSObject *useLogPersistenceObj = dict[@"useLogPersistence"]; - BOOL useLogPersistence = NO; + BOOL useLogPersistence = YES; if (useLogPersistenceObj && [useLogPersistenceObj isKindOfClass:[NSNumber class]]) { useLogPersistence = [(NSNumber *)useLogPersistenceObj boolValue]; } diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 9bafd6c02..a896a5467 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -22,25 +22,22 @@ @implementation RadarLogBuffer { NSMutableArray *mutableLogBuffer; NSMutableArray *inMemoryLogBuffer; - BOOL useLogPersistence; } - (instancetype)init { self = [super init]; if (self) { - RadarFeatureSettings *featureSettings = [RadarSettings featureSettings]; - useLogPersistence = featureSettings.useLogPersistence; mutableLogBuffer = [NSMutableArray new]; inMemoryLogBuffer = [NSMutableArray new]; - if (useLogPersistence) { - NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; - self.logFileDir = [documentsDirectory stringByAppendingPathComponent:@"radar_logs"]; - if (![[NSFileManager defaultManager] fileExistsAtPath:self.logFileDir isDirectory:nil]) { - [[NSFileManager defaultManager] createDirectoryAtPath:self.logFileDir withIntermediateDirectories:YES attributes:nil error:nil]; - } - self.fileHandler = [[RadarFileStorage alloc] init]; - _timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(persistLogs) userInfo:nil repeats:YES]; - } + + NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; + self.logFileDir = [documentsDirectory stringByAppendingPathComponent:@"radar_logs"]; + if (![[NSFileManager defaultManager] fileExistsAtPath:self.logFileDir isDirectory:nil]) { + [[NSFileManager defaultManager] createDirectoryAtPath:self.logFileDir withIntermediateDirectories:YES attributes:nil error:nil]; + } + self.fileHandler = [[RadarFileStorage alloc] init]; + _timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(persistLogs) userInfo:nil repeats:YES]; + } return self; } @@ -64,7 +61,7 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; [mutableLogBuffer addObject:radarLog]; - if (useLogPersistence) { + if ([RadarSettings featureSettings].useLogPersistence) { RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; [inMemoryLogBuffer addObject:radarLog]; NSUInteger logLength = [inMemoryLogBuffer count]; @@ -77,7 +74,7 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m - (void)persistLogs { @synchronized (self) { - if (useLogPersistence) { + if ([RadarSettings featureSettings].useLogPersistence) { NSArray *flushableLogs = [inMemoryLogBuffer copy]; [self addLogsToBuffer:flushableLogs]; [inMemoryLogBuffer removeAllObjects]; @@ -117,7 +114,7 @@ - (void)writeToFileStorage:(NSArray *)logs { - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { @synchronized (self) { [self write:level type:type message:message]; - if (useLogPersistence){ + if ([RadarSettings featureSettings].useLogPersistence) { [self writeToFileStorage:@[[[RadarLog alloc] initWithLevel:level type:type message:message]]]; } } @@ -125,7 +122,7 @@ - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *) - (NSArray *)flushableLogs { @synchronized (self) { - if (useLogPersistence) { + if ([RadarSettings featureSettings].useLogPersistence) { [self persistLogs]; NSArray *existingLogsArray = [self.readFromFileStorage copy]; return existingLogsArray; @@ -147,7 +144,7 @@ - (void)purgeOldestLogs { - (void)removeLogsFromBuffer:(NSUInteger)numLogs { @synchronized (self) { [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, numLogs)]; - if (useLogPersistence) { + if ([RadarSettings featureSettings].useLogPersistence) { NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; numLogs = MIN(numLogs, [files count]); for (NSUInteger i = 0; i < (numLogs); i++) { @@ -162,7 +159,7 @@ - (void)removeLogsFromBuffer:(NSUInteger)numLogs { - (void)addLogsToBuffer:(NSArray *)logs { @synchronized (self) { [mutableLogBuffer addObjectsFromArray:logs]; - if (useLogPersistence) { + if ([RadarSettings featureSettings].useLogPersistence) { NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; NSUInteger bufferSize = [files count]; NSUInteger logLength = [logs count]; From aa8f0c10c58b5aae6ed1b33e73e44770b2a11079 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Mon, 11 Dec 2023 13:32:55 -0500 Subject: [PATCH 47/72] set deafult back to 0 --- RadarSDK/RadarFeatureSettings.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RadarSDK/RadarFeatureSettings.m b/RadarSDK/RadarFeatureSettings.m index 78a50aedc..9455a312f 100644 --- a/RadarSDK/RadarFeatureSettings.m +++ b/RadarSDK/RadarFeatureSettings.m @@ -38,7 +38,7 @@ + (RadarFeatureSettings *_Nullable)featureSettingsFromDictionary:(NSDictionary * } NSObject *useLogPersistenceObj = dict[@"useLogPersistence"]; - BOOL useLogPersistence = YES; + BOOL useLogPersistence = NO; if (useLogPersistenceObj && [useLogPersistenceObj isKindOfClass:[NSNumber class]]) { useLogPersistence = [(NSNumber *)useLogPersistenceObj boolValue]; } From 81028e67e75227575f4cb1df3902fdc4396efb6c Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Mon, 11 Dec 2023 13:45:39 -0500 Subject: [PATCH 48/72] fix tests --- RadarSDK/RadarLogBuffer.m | 5 ++++- RadarSDKTests/RadarSDKTests.m | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index a896a5467..de27cde78 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -113,10 +113,13 @@ - (void)writeToFileStorage:(NSArray *)logs { - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { @synchronized (self) { - [self write:level type:type message:message]; if ([RadarSettings featureSettings].useLogPersistence) { + NSLog(@"writing to file storage"); [self writeToFileStorage:@[[[RadarLog alloc] initWithLevel:level type:type message:message]]]; } + else{ + [self write:level type:type message:message]; + } } } diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index e4875ba9c..523e1e681 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -283,7 +283,6 @@ - (void)assertRoutesOk:(RadarRoutes *)routes { - (void)setUp { [super setUp]; - [RadarSettings setFeatureSettings: [[RadarFeatureSettings alloc] initWithUsePersistence:YES extendFlushReplays:YES useLogPersistence:YES]]; [Radar initializeWithPublishableKey:kPublishableKey]; [Radar setLogLevel:RadarLogLevelDebug]; @@ -300,6 +299,7 @@ - (void)setUp { self.testFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"testfile"]; self.logBuffer = [RadarLogBuffer sharedInstance]; [self.logBuffer clearBuffer]; + [RadarSettings setFeatureSettings: [[RadarFeatureSettings alloc] initWithUsePersistence:YES extendFlushReplays:YES useLogPersistence:YES]]; } From c459603cf9504375ed96e59f13d37abea6a014b6 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Mon, 11 Dec 2023 14:14:36 -0500 Subject: [PATCH 49/72] condition on if in test env --- RadarSDK/RadarLogBuffer.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index de27cde78..d59a6fc5f 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -61,7 +61,7 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; [mutableLogBuffer addObject:radarLog]; - if ([RadarSettings featureSettings].useLogPersistence) { + if ([RadarSettings featureSettings].useLogPersistence || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; [inMemoryLogBuffer addObject:radarLog]; NSUInteger logLength = [inMemoryLogBuffer count]; @@ -113,7 +113,7 @@ - (void)writeToFileStorage:(NSArray *)logs { - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { @synchronized (self) { - if ([RadarSettings featureSettings].useLogPersistence) { + if ([RadarSettings featureSettings].useLogPersistence || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { NSLog(@"writing to file storage"); [self writeToFileStorage:@[[[RadarLog alloc] initWithLevel:level type:type message:message]]]; } @@ -125,7 +125,7 @@ - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *) - (NSArray *)flushableLogs { @synchronized (self) { - if ([RadarSettings featureSettings].useLogPersistence) { + if ([RadarSettings featureSettings].useLogPersistence || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { [self persistLogs]; NSArray *existingLogsArray = [self.readFromFileStorage copy]; return existingLogsArray; @@ -147,7 +147,7 @@ - (void)purgeOldestLogs { - (void)removeLogsFromBuffer:(NSUInteger)numLogs { @synchronized (self) { [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, numLogs)]; - if ([RadarSettings featureSettings].useLogPersistence) { + if ([RadarSettings featureSettings].useLogPersistence || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; numLogs = MIN(numLogs, [files count]); for (NSUInteger i = 0; i < (numLogs); i++) { @@ -162,7 +162,7 @@ - (void)removeLogsFromBuffer:(NSUInteger)numLogs { - (void)addLogsToBuffer:(NSArray *)logs { @synchronized (self) { [mutableLogBuffer addObjectsFromArray:logs]; - if ([RadarSettings featureSettings].useLogPersistence) { + if ([RadarSettings featureSettings].useLogPersistence || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; NSUInteger bufferSize = [files count]; NSUInteger logLength = [logs count]; From 3f95bc91eaffdc0711cea16857a999ed2f701e49 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Mon, 11 Dec 2023 17:52:44 -0500 Subject: [PATCH 50/72] working on local --- RadarSDK/Radar.m | 3 ++- RadarSDK/RadarLogBuffer.m | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index d671beb8f..d4cf13376 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -66,8 +66,9 @@ + (void)initializeWithPublishableKey:(NSString *)publishableKey { completionHandler:^(RadarStatus status, RadarConfig *config) { [[RadarLocationManager sharedInstance] updateTrackingFromMeta:config.meta]; [RadarSettings setFeatureSettings:config.meta.featureSettings]; + [self flushLogs]; }]; - [self flushLogs]; + } #pragma mark - Properties diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index d59a6fc5f..c9295a806 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -68,7 +68,7 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m if (logLength >= MAX_MEMORY_BUFFER_SIZE) { [self persistLogs]; } - } + } } } @@ -114,7 +114,6 @@ - (void)writeToFileStorage:(NSArray *)logs { - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { @synchronized (self) { if ([RadarSettings featureSettings].useLogPersistence || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { - NSLog(@"writing to file storage"); [self writeToFileStorage:@[[[RadarLog alloc] initWithLevel:level type:type message:message]]]; } else{ @@ -146,7 +145,8 @@ - (void)purgeOldestLogs { - (void)removeLogsFromBuffer:(NSUInteger)numLogs { @synchronized (self) { - [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, numLogs)]; + + [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, MIN(numLogs, [mutableLogBuffer count]))]; if ([RadarSettings featureSettings].useLogPersistence || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; numLogs = MIN(numLogs, [files count]); From 5b394c363a811b9a5ef8bed95ca17a8ca44576af Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 12 Dec 2023 11:32:31 -0500 Subject: [PATCH 51/72] dynamically update feature flag to be read at runtime --- RadarSDK/RadarLogBuffer.h | 4 ++++ RadarSDK/RadarLogBuffer.m | 17 +++++++++++------ RadarSDK/RadarSettings.m | 5 +++++ RadarSDKTests/RadarSDKTests.m | 3 ++- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.h b/RadarSDK/RadarLogBuffer.h index 5c632dfd0..955bb0930 100644 --- a/RadarSDK/RadarLogBuffer.h +++ b/RadarSDK/RadarLogBuffer.h @@ -18,6 +18,8 @@ NS_ASSUME_NONNULL_BEGIN @property (strong, nonatomic) NSString *logFileDir; @property (strong, nonatomic) RadarFileStorage *fileHandler; @property (nonatomic, strong) NSTimer *timer; +//add a property that can be modified +@property (nonatomic, assign) BOOL featureFlag; + (instancetype)sharedInstance; @@ -33,6 +35,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)addLogsToBuffer:(NSArray *)logs; +- (void)setFeatureFlag:(BOOL)featureFlag; + @end NS_ASSUME_NONNULL_END diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index c9295a806..712002e24 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -27,6 +27,7 @@ @implementation RadarLogBuffer { - (instancetype)init { self = [super init]; if (self) { + _featureFlag = [RadarSettings featureSettings].useLogPersistence; mutableLogBuffer = [NSMutableArray new]; inMemoryLogBuffer = [NSMutableArray new]; @@ -42,6 +43,10 @@ - (instancetype)init { return self; } +- (void)setFeatureFlag:(BOOL)featureFlag { + _featureFlag = featureFlag; +} + + (instancetype)sharedInstance { static dispatch_once_t once; static id sharedInstance; @@ -61,7 +66,7 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; [mutableLogBuffer addObject:radarLog]; - if ([RadarSettings featureSettings].useLogPersistence || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { + if (_featureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; [inMemoryLogBuffer addObject:radarLog]; NSUInteger logLength = [inMemoryLogBuffer count]; @@ -74,7 +79,7 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m - (void)persistLogs { @synchronized (self) { - if ([RadarSettings featureSettings].useLogPersistence) { + if (_featureFlag) { NSArray *flushableLogs = [inMemoryLogBuffer copy]; [self addLogsToBuffer:flushableLogs]; [inMemoryLogBuffer removeAllObjects]; @@ -113,7 +118,7 @@ - (void)writeToFileStorage:(NSArray *)logs { - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { @synchronized (self) { - if ([RadarSettings featureSettings].useLogPersistence || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { + if (_featureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { [self writeToFileStorage:@[[[RadarLog alloc] initWithLevel:level type:type message:message]]]; } else{ @@ -124,7 +129,7 @@ - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *) - (NSArray *)flushableLogs { @synchronized (self) { - if ([RadarSettings featureSettings].useLogPersistence || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { + if (_featureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { [self persistLogs]; NSArray *existingLogsArray = [self.readFromFileStorage copy]; return existingLogsArray; @@ -147,7 +152,7 @@ - (void)removeLogsFromBuffer:(NSUInteger)numLogs { @synchronized (self) { [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, MIN(numLogs, [mutableLogBuffer count]))]; - if ([RadarSettings featureSettings].useLogPersistence || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { + if (_featureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; numLogs = MIN(numLogs, [files count]); for (NSUInteger i = 0; i < (numLogs); i++) { @@ -162,7 +167,7 @@ - (void)removeLogsFromBuffer:(NSUInteger)numLogs { - (void)addLogsToBuffer:(NSArray *)logs { @synchronized (self) { [mutableLogBuffer addObjectsFromArray:logs]; - if ([RadarSettings featureSettings].useLogPersistence || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { + if (_featureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; NSUInteger bufferSize = [files count]; NSUInteger logLength = [logs count]; diff --git a/RadarSDK/RadarSettings.m b/RadarSDK/RadarSettings.m index 865df780e..150e4563e 100644 --- a/RadarSDK/RadarSettings.m +++ b/RadarSDK/RadarSettings.m @@ -12,6 +12,7 @@ #import "RadarTripOptions.h" #import "RadarFeatureSettings.h" #import "RadarReplayBuffer.h" +#import "RadarLogBuffer.h" @implementation RadarSettings @@ -214,9 +215,13 @@ + (RadarFeatureSettings *)featureSettings { + (void)setFeatureSettings:(RadarFeatureSettings *)featureSettings { if (featureSettings) { + //This is added as reading from NSUserdefaults is too slow for this feature flag. To be removed when throttling is done. + [[RadarLogBuffer sharedInstance] setFeatureFlag:featureSettings.useLogPersistence]; NSDictionary *featureSettingsDict = [featureSettings dictionaryValue]; [[NSUserDefaults standardUserDefaults] setObject:featureSettingsDict forKey:kFeatureSettings]; } else { + //This is added as reading from NSUserdefaults is too slow for this feature flag. To be removed when throttling is done. + [[RadarLogBuffer sharedInstance] setFeatureFlag:NO]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:kFeatureSettings]; } } diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 523e1e681..f672cdd31 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -299,7 +299,8 @@ - (void)setUp { self.testFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"testfile"]; self.logBuffer = [RadarLogBuffer sharedInstance]; [self.logBuffer clearBuffer]; - [RadarSettings setFeatureSettings: [[RadarFeatureSettings alloc] initWithUsePersistence:YES extendFlushReplays:YES useLogPersistence:YES]]; + //[RadarSettings setFeatureSettings: [[RadarFeatureSettings alloc] initWithUsePersistence:YES extendFlushReplays:YES useLogPersistence:YES]]; + [self.logBuffer setFeatureFlag:YES]; } From 58a26e1e2f2a1182882ac2688eeb07cb3a2c2dd5 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 12 Dec 2023 11:39:34 -0500 Subject: [PATCH 52/72] cleanup --- RadarSDK/Radar.m | 6 ++---- RadarSDK/RadarLogBuffer.h | 1 - RadarSDK/RadarLogBuffer.m | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index d4cf13376..0bb0f86be 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1044,7 +1044,7 @@ + (void)logTermination { + (void)logEnterBackground { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background" includeDate:YES includeBattery:YES append:YES]; - [[RadarLogBuffer sharedInstance] persistLogs ]; + [[RadarLogBuffer sharedInstance] persistLogs]; } + (void)logResignActive { @@ -1272,8 +1272,7 @@ + (void)flushLogs { return; } - NSArray *flushableLogs = [[RadarLogBuffer sharedInstance] flushableLogs]; - + NSArray *flushableLogs = [[RadarLogBuffer sharedInstance] flushableLogs]; NSUInteger pendingLogCount = [flushableLogs count]; if (pendingLogCount == 0) { return; @@ -1288,7 +1287,6 @@ + (void)flushLogs { [[RadarLogBuffer sharedInstance] addLogsToBuffer:flushableLogs]; } }; - [[RadarAPIClient sharedInstance] syncLogs:flushableLogs completionHandler:^(RadarStatus status) { if (onComplete) { diff --git a/RadarSDK/RadarLogBuffer.h b/RadarSDK/RadarLogBuffer.h index 955bb0930..a67ed5daf 100644 --- a/RadarSDK/RadarLogBuffer.h +++ b/RadarSDK/RadarLogBuffer.h @@ -18,7 +18,6 @@ NS_ASSUME_NONNULL_BEGIN @property (strong, nonatomic) NSString *logFileDir; @property (strong, nonatomic) RadarFileStorage *fileHandler; @property (nonatomic, strong) NSTimer *timer; -//add a property that can be modified @property (nonatomic, assign) BOOL featureFlag; + (instancetype)sharedInstance; diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 712002e24..0943675b2 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -91,14 +91,14 @@ - (void)persistLogs { NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; NSMutableArray *logs = [NSMutableArray array]; - if(!files){ + if (!files) { return logs; } for (NSString *file in files) { NSString *filePath = [self.logFileDir stringByAppendingPathComponent:file]; NSData *fileData = [self.fileHandler readFileAtPath:filePath]; RadarLog *log = [NSKeyedUnarchiver unarchiveObjectWithData:fileData]; - if(log && log.message){ + if (log && log.message) { [logs addObject:log]; } } From 8c28a0416d01484308ac4beab1f672383209f7d4 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 14 Dec 2023 10:55:14 -0500 Subject: [PATCH 53/72] remove dead code --- RadarSDKTests/RadarSDKTests.m | 1 - 1 file changed, 1 deletion(-) diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index f672cdd31..592e5087c 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -299,7 +299,6 @@ - (void)setUp { self.testFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"testfile"]; self.logBuffer = [RadarLogBuffer sharedInstance]; [self.logBuffer clearBuffer]; - //[RadarSettings setFeatureSettings: [[RadarFeatureSettings alloc] initWithUsePersistence:YES extendFlushReplays:YES useLogPersistence:YES]]; [self.logBuffer setFeatureFlag:YES]; } From 890009138237d18704b66dc4f7c83b8fd8a009f7 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 14 Dec 2023 11:17:02 -0500 Subject: [PATCH 54/72] clean-up --- RadarSDK/Include/Radar.h | 4 +- RadarSDK/Radar.m | 7 ++-- RadarSDKTests/RadarSDKTests.m | 73 +++++++++++++++++------------------ 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/RadarSDK/Include/Radar.h b/RadarSDK/Include/Radar.h index e6992e12e..4932b9a44 100644 --- a/RadarSDK/Include/Radar.h +++ b/RadarSDK/Include/Radar.h @@ -1004,13 +1004,13 @@ logConversionWithNotification + (void)setLogLevel:(RadarLogLevel)level; /** - Log application termination. + Log application terminating. */ + (void)logTermination; /** - Log application entering background and flush logs in memory buffer into persistent buffer. + Log application entering background and flush logs from memory buffer into persistent buffer. */ + (void)logEnterBackground; diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index 0bb0f86be..08e6b691d 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1039,16 +1039,16 @@ + (void)setLogLevel:(RadarLogLevel)level { } + (void)logTermination { - [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminated" includeDate:YES includeBattery:YES append:YES]; + [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminating." includeDate:YES includeBattery:YES append:YES]; } + (void)logEnterBackground { - [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background" includeDate:YES includeBattery:YES append:YES]; + [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background." includeDate:YES includeBattery:YES append:YES]; [[RadarLogBuffer sharedInstance] persistLogs]; } + (void)logResignActive { - [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App resigning active" includeDate:YES includeBattery:YES]; + [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App resigning active." includeDate:YES includeBattery:YES]; } @@ -1287,6 +1287,7 @@ + (void)flushLogs { [[RadarLogBuffer sharedInstance] addLogsToBuffer:flushableLogs]; } }; + [[RadarAPIClient sharedInstance] syncLogs:flushableLogs completionHandler:^(RadarStatus status) { if (onComplete) { diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 592e5087c..255fcaa6d 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -297,15 +297,14 @@ - (void)setUp { [RadarLocationManager sharedInstance].permissionsHelper = self.permissionsHelperMock; self.fileSystem = [[RadarFileStorage alloc] init]; self.testFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"testfile"]; - self.logBuffer = [RadarLogBuffer sharedInstance]; - [self.logBuffer clearBuffer]; - [self.logBuffer setFeatureFlag:YES]; + [[RadarLogBuffer sharedInstance]clearBuffer]; + [[RadarLogBuffer sharedInstance]setFeatureFlag:YES]; } - (void)tearDown { [[NSFileManager defaultManager] removeItemAtPath:self.testFilePath error:nil]; - [self.logBuffer clearBuffer]; + [[RadarLogBuffer sharedInstance]clearBuffer]; [super tearDown]; } @@ -1443,26 +1442,26 @@ - (void)test_RadarFileStorage_deleteFile { } - (void)test_RadarLogBuffer_writeAndFlushableLogs { - [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; - [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; - [self.logBuffer persistLogs]; - NSArray *logs = [self.logBuffer flushableLogs]; + [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; + [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; + [[RadarLogBuffer sharedInstance]persistLogs]; + NSArray *logs = [[RadarLogBuffer sharedInstance]flushableLogs]; XCTAssertEqual(logs.count, 2); XCTAssertEqualObjects(logs.firstObject.message, @"Test message 1"); XCTAssertEqualObjects(logs.lastObject.message, @"Test message 2"); - [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 3"]; - NSArray *newLogs = [self.logBuffer flushableLogs]; + [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 3"]; + NSArray *newLogs = [[RadarLogBuffer sharedInstance]flushableLogs]; XCTAssertEqual(newLogs.count, 3); XCTAssertEqualObjects(newLogs.firstObject.message, @"Test message 1"); XCTAssertEqualObjects(newLogs.lastObject.message, @"Test message 3"); } - (void)test_RadarLogBuffer_removeLogsFromBuffer { - [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; - [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; - [self.logBuffer persistLogs]; - [self.logBuffer removeLogsFromBuffer:2]; - NSArray *logs = [self.logBuffer flushableLogs]; + [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; + [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; + [[RadarLogBuffer sharedInstance]persistLogs]; + [[RadarLogBuffer sharedInstance]removeLogsFromBuffer:2]; + NSArray *logs = [[RadarLogBuffer sharedInstance]flushableLogs]; XCTAssertEqual(logs.count, 0); } @@ -1471,12 +1470,12 @@ - (void)test_RadarLogBuffer_addLogsToBuffrer { RadarLog *log2 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; RadarLog *log3 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 3"]; RadarLog *log4 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 4"]; - [self.logBuffer addLogsToBuffer:@[log1, log2]]; - [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; - [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; - [self.logBuffer persistLogs]; - [self.logBuffer addLogsToBuffer:@[log3, log4]]; - NSArray *logs = [self.logBuffer flushableLogs]; + [[RadarLogBuffer sharedInstance]addLogsToBuffer:@[log1, log2]]; + [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; + [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; + [[RadarLogBuffer sharedInstance]persistLogs]; + [[RadarLogBuffer sharedInstance]addLogsToBuffer:@[log3, log4]]; + NSArray *logs = [[RadarLogBuffer sharedInstance]flushableLogs]; XCTAssertEqual(logs.count, 6); XCTAssertEqualObjects(logs.lastObject.message, @"Test message 4"); } @@ -1486,37 +1485,37 @@ - (void)test_RadarLogBuffer_addAndRemove{ RadarLog *log2 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; RadarLog *log3 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 3"]; RadarLog *log4 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 4"]; - [self.logBuffer addLogsToBuffer:@[log1, log2]]; - [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; - [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; - [self.logBuffer persistLogs]; - [self.logBuffer addLogsToBuffer:@[log3, log4]]; - NSArray *logs = [self.logBuffer flushableLogs]; - [self.logBuffer removeLogsFromBuffer:6]; - [self.logBuffer addLogsToBuffer:logs]; - NSArray *logs1 = [self.logBuffer flushableLogs]; + [[RadarLogBuffer sharedInstance]addLogsToBuffer:@[log1, log2]]; + [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; + [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; + [[RadarLogBuffer sharedInstance]persistLogs]; + [[RadarLogBuffer sharedInstance]addLogsToBuffer:@[log3, log4]]; + NSArray *logs = [[RadarLogBuffer sharedInstance]flushableLogs]; + [[RadarLogBuffer sharedInstance]removeLogsFromBuffer:6]; + [[RadarLogBuffer sharedInstance]addLogsToBuffer:logs]; + NSArray *logs1 = [[RadarLogBuffer sharedInstance]flushableLogs]; XCTAssertEqual(logs1.count, 6); } - (void)test_RadarLogBuffer_append { - [self.logBuffer append:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; - [self.logBuffer append:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; - NSArray *logs = [self.logBuffer flushableLogs]; + [[RadarLogBuffer sharedInstance]append:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; + [[RadarLogBuffer sharedInstance]append:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; + NSArray *logs = [[RadarLogBuffer sharedInstance]flushableLogs]; XCTAssertEqual(logs.count, 2); XCTAssertEqualObjects(logs.firstObject.message, @"Test message 1"); XCTAssertEqualObjects(logs.lastObject.message, @"Test message 2"); } - (void)test_RadarLogBuffer_purge { - [self.logBuffer clearBuffer]; + [[RadarLogBuffer sharedInstance]clearBuffer]; for (NSUInteger i = 0; i < 600; i++) { - [self.logBuffer write:RadarLogLevelDebug type:RadarLogTypeNone message:[NSString stringWithFormat:@"message_%d", i]]; + [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:[NSString stringWithFormat:@"message_%d", i]]; } - NSArray *logs = [self.logBuffer flushableLogs]; + NSArray *logs = [[RadarLogBuffer sharedInstance]flushableLogs]; XCTAssertEqual(logs.count, 351); XCTAssertEqualObjects(logs.firstObject.message, @"message_250"); XCTAssertEqualObjects(logs.lastObject.message, @"----- purged oldest logs -----"); - [self.logBuffer clearBuffer]; + [[RadarLogBuffer sharedInstance]clearBuffer]; } @end From c510409696797b46f1e0b0686121b81394804202 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 14 Dec 2023 11:36:02 -0500 Subject: [PATCH 55/72] cleanup --- RadarSDK/RadarLogBuffer.m | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 0943675b2..129ac0898 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -79,7 +79,7 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m - (void)persistLogs { @synchronized (self) { - if (_featureFlag) { + if (_featureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { NSArray *flushableLogs = [inMemoryLogBuffer copy]; [self addLogsToBuffer:flushableLogs]; [inMemoryLogBuffer removeAllObjects]; @@ -110,6 +110,7 @@ - (void)writeToFileStorage:(NSArray *)logs { for (RadarLog *log in logs) { NSData *logData = [NSKeyedArchiver archivedDataWithRootObject:log]; NSTimeInterval unixTimestamp = [log.createdAt timeIntervalSince1970]; + //logs may be created in the same millisecond, so we append a counter to the end of the timestamp to "tiebreak" NSString *unixTimestampString = [NSString stringWithFormat:@"%lld%04d", (long long)unixTimestamp, counter++]; NSString *filePath = [self.logFileDir stringByAppendingPathComponent:unixTimestampString]; [self.fileHandler writeData:logData toFileAtPath:filePath]; @@ -153,9 +154,8 @@ - (void)removeLogsFromBuffer:(NSUInteger)numLogs { [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, MIN(numLogs, [mutableLogBuffer count]))]; if (_featureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { - NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; - numLogs = MIN(numLogs, [files count]); - for (NSUInteger i = 0; i < (numLogs); i++) { + NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; + for (NSUInteger i = 0; i < MIN(numLogs, [files count]); i++) { NSString *file = [files objectAtIndex:i]; NSString *filePath = [self.logFileDir stringByAppendingPathComponent:file]; [self.fileHandler deleteFileAtPath:filePath]; @@ -171,11 +171,9 @@ - (void)addLogsToBuffer:(NSArray *)logs { NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; NSUInteger bufferSize = [files count]; NSUInteger logLength = [logs count]; - while (bufferSize+logLength >= MAX_PERSISTED_BUFFER_SIZE) { + while (bufferSize + logLength >= MAX_PERSISTED_BUFFER_SIZE) { [self removeLogsFromBuffer:PURGE_AMOUNT]; - files = [self.fileHandler allFilesInDirectory:self.logFileDir]; - bufferSize = [files count]; - logLength = [logs count]; + bufferSize = [[self.fileHandler allFilesInDirectory:self.logFileDir] count]; RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; [self writeToFileStorage:@[purgeLog]]; } From 89fc7ac1a79fa4069c3b23e2e5d3256a263fd342 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 14 Dec 2023 13:54:22 -0500 Subject: [PATCH 56/72] remove period from logs --- RadarSDK/Radar.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index 08e6b691d..ef1bfddd2 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1039,16 +1039,16 @@ + (void)setLogLevel:(RadarLogLevel)level { } + (void)logTermination { - [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminating." includeDate:YES includeBattery:YES append:YES]; + [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminating" includeDate:YES includeBattery:YES append:YES]; } + (void)logEnterBackground { - [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background." includeDate:YES includeBattery:YES append:YES]; + [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background" includeDate:YES includeBattery:YES append:YES]; [[RadarLogBuffer sharedInstance] persistLogs]; } + (void)logResignActive { - [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App resigning active." includeDate:YES includeBattery:YES]; + [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App resigning active" includeDate:YES includeBattery:YES]; } @@ -1287,7 +1287,7 @@ + (void)flushLogs { [[RadarLogBuffer sharedInstance] addLogsToBuffer:flushableLogs]; } }; - + [[RadarAPIClient sharedInstance] syncLogs:flushableLogs completionHandler:^(RadarStatus status) { if (onComplete) { From 8f2a8532f70d2855092ca4b79899d0bbd0f941ff Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 14 Dec 2023 13:55:17 -0500 Subject: [PATCH 57/72] add back tab --- RadarSDK/Radar.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index ef1bfddd2..65615aa36 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1287,7 +1287,7 @@ + (void)flushLogs { [[RadarLogBuffer sharedInstance] addLogsToBuffer:flushableLogs]; } }; - + [[RadarAPIClient sharedInstance] syncLogs:flushableLogs completionHandler:^(RadarStatus status) { if (onComplete) { From 0013a83e05873fb567e0c947e7fb62f49b641277 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Fri, 15 Dec 2023 10:03:02 -0500 Subject: [PATCH 58/72] small fixes --- RadarSDK/RadarFileStorage.h | 3 +++ RadarSDK/RadarFileStorage.m | 11 +++++++---- RadarSDK/RadarLogBuffer.h | 4 ++-- RadarSDK/RadarLogBuffer.m | 36 +++++++++++++++++++++-------------- RadarSDK/RadarSettings.m | 5 ++--- RadarSDKTests/RadarSDKTests.m | 2 +- 6 files changed, 37 insertions(+), 24 deletions(-) diff --git a/RadarSDK/RadarFileStorage.h b/RadarSDK/RadarFileStorage.h index 2ef705b01..7302e0ccb 100644 --- a/RadarSDK/RadarFileStorage.h +++ b/RadarSDK/RadarFileStorage.h @@ -18,4 +18,7 @@ - (void)deleteFileAtPath:(NSString *)filePath; - (NSArray *)allFilesInDirectory:(NSString *)directoryPath; + +- (NSArray *)allFilesInDirectory:(NSString *)directoryPath withComparator:(NSComparator)comparator; + @end diff --git a/RadarSDK/RadarFileStorage.m b/RadarSDK/RadarFileStorage.m index 2ae31dd38..8a50d9eac 100644 --- a/RadarSDK/RadarFileStorage.m +++ b/RadarSDK/RadarFileStorage.m @@ -40,6 +40,12 @@ - (void)deleteFileAtPath:(NSString *)filePath { } - (NSArray *)allFilesInDirectory:(NSString *)directoryPath { + return [self allFilesInDirectory:directoryPath withComparator:^NSComparisonResult(NSString *fileName1, NSString *fileName2) { + return [fileName1 compare:fileName2]; + }]; +} + +- (NSArray *)allFilesInDirectory:(NSString *)directoryPath withComparator:(NSComparator)comparator { NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error = nil; NSArray *files = [fileManager contentsOfDirectoryAtPath:directoryPath error:&error]; @@ -49,10 +55,7 @@ - (void)deleteFileAtPath:(NSString *)filePath { return nil; } - return [files sortedArrayUsingComparator:^NSComparisonResult(NSString *str1, NSString *str2) { - return [@([str1 integerValue]) compare:@([str2 integerValue])]; - }]; + return [files sortedArrayUsingComparator: comparator]; } @end - diff --git a/RadarSDK/RadarLogBuffer.h b/RadarSDK/RadarLogBuffer.h index a67ed5daf..5b4e0e663 100644 --- a/RadarSDK/RadarLogBuffer.h +++ b/RadarSDK/RadarLogBuffer.h @@ -18,7 +18,7 @@ NS_ASSUME_NONNULL_BEGIN @property (strong, nonatomic) NSString *logFileDir; @property (strong, nonatomic) RadarFileStorage *fileHandler; @property (nonatomic, strong) NSTimer *timer; -@property (nonatomic, assign) BOOL featureFlag; +@property (nonatomic, assign) BOOL persistentLogFeatureFlag; + (instancetype)sharedInstance; @@ -34,7 +34,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)addLogsToBuffer:(NSArray *)logs; -- (void)setFeatureFlag:(BOOL)featureFlag; +- (void)setPersistentLogFeatureFlag:(BOOL)persistentLogFeatureFlag; @end diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 129ac0898..0475b3ceb 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -27,7 +27,7 @@ @implementation RadarLogBuffer { - (instancetype)init { self = [super init]; if (self) { - _featureFlag = [RadarSettings featureSettings].useLogPersistence; + _persistentLogFeatureFlag = [RadarSettings featureSettings].useLogPersistence; mutableLogBuffer = [NSMutableArray new]; inMemoryLogBuffer = [NSMutableArray new]; @@ -43,8 +43,8 @@ - (instancetype)init { return self; } -- (void)setFeatureFlag:(BOOL)featureFlag { - _featureFlag = featureFlag; +- (void)setPersistentLogFeatureFlag:(BOOL)persistentLogFeatureFlag { + _persistentLogFeatureFlag = persistentLogFeatureFlag; } + (instancetype)sharedInstance { @@ -66,7 +66,7 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; [mutableLogBuffer addObject:radarLog]; - if (_featureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { + if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; [inMemoryLogBuffer addObject:radarLog]; NSUInteger logLength = [inMemoryLogBuffer count]; @@ -79,7 +79,7 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m - (void)persistLogs { @synchronized (self) { - if (_featureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { + if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { NSArray *flushableLogs = [inMemoryLogBuffer copy]; [self addLogsToBuffer:flushableLogs]; [inMemoryLogBuffer removeAllObjects]; @@ -87,9 +87,17 @@ - (void)persistLogs { } } +- (NSArray *)getLogFilesInTimeOrder { + NSComparator compareTimeStamps = ^NSComparisonResult(NSString *str1, NSString *str2) { + return [@([str1 integerValue]) compare:@([str2 integerValue])]; + }; + + return [self.fileHandler allFilesInDirectory:self.logFileDir withComparator:compareTimeStamps]; +} + - (NSMutableArray *)readFromFileStorage { - NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; + NSArray *files = [self getLogFilesInTimeOrder]; NSMutableArray *logs = [NSMutableArray array]; if (!files) { return logs; @@ -119,7 +127,7 @@ - (void)writeToFileStorage:(NSArray *)logs { - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { @synchronized (self) { - if (_featureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { + if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { [self writeToFileStorage:@[[[RadarLog alloc] initWithLevel:level type:type message:message]]]; } else{ @@ -130,7 +138,7 @@ - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *) - (NSArray *)flushableLogs { @synchronized (self) { - if (_featureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { + if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { [self persistLogs]; NSArray *existingLogsArray = [self.readFromFileStorage copy]; return existingLogsArray; @@ -153,8 +161,8 @@ - (void)removeLogsFromBuffer:(NSUInteger)numLogs { @synchronized (self) { [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, MIN(numLogs, [mutableLogBuffer count]))]; - if (_featureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { - NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; + if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { + NSArray *files = [self getLogFilesInTimeOrder]; for (NSUInteger i = 0; i < MIN(numLogs, [files count]); i++) { NSString *file = [files objectAtIndex:i]; NSString *filePath = [self.logFileDir stringByAppendingPathComponent:file]; @@ -167,13 +175,13 @@ - (void)removeLogsFromBuffer:(NSUInteger)numLogs { - (void)addLogsToBuffer:(NSArray *)logs { @synchronized (self) { [mutableLogBuffer addObjectsFromArray:logs]; - if (_featureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { - NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; + if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { + NSArray *files = [self getLogFilesInTimeOrder]; NSUInteger bufferSize = [files count]; NSUInteger logLength = [logs count]; while (bufferSize + logLength >= MAX_PERSISTED_BUFFER_SIZE) { [self removeLogsFromBuffer:PURGE_AMOUNT]; - bufferSize = [[self.fileHandler allFilesInDirectory:self.logFileDir] count]; + bufferSize = [[self getLogFilesInTimeOrder] count]; RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; [self writeToFileStorage:@[purgeLog]]; } @@ -186,7 +194,7 @@ - (void)addLogsToBuffer:(NSArray *)logs { -(void)clearBuffer { @synchronized (self) { [inMemoryLogBuffer removeAllObjects]; - NSArray *files = [self.fileHandler allFilesInDirectory:self.logFileDir]; + NSArray *files = [self getLogFilesInTimeOrder]; if (files) { for (NSString *file in files) { NSString *filePath = [self.logFileDir stringByAppendingPathComponent:file]; diff --git a/RadarSDK/RadarSettings.m b/RadarSDK/RadarSettings.m index 150e4563e..3b8c57931 100644 --- a/RadarSDK/RadarSettings.m +++ b/RadarSDK/RadarSettings.m @@ -216,12 +216,11 @@ + (RadarFeatureSettings *)featureSettings { + (void)setFeatureSettings:(RadarFeatureSettings *)featureSettings { if (featureSettings) { //This is added as reading from NSUserdefaults is too slow for this feature flag. To be removed when throttling is done. - [[RadarLogBuffer sharedInstance] setFeatureFlag:featureSettings.useLogPersistence]; + [[RadarLogBuffer sharedInstance] setPersistentLogFeatureFlag:featureSettings.useLogPersistence]; NSDictionary *featureSettingsDict = [featureSettings dictionaryValue]; [[NSUserDefaults standardUserDefaults] setObject:featureSettingsDict forKey:kFeatureSettings]; } else { - //This is added as reading from NSUserdefaults is too slow for this feature flag. To be removed when throttling is done. - [[RadarLogBuffer sharedInstance] setFeatureFlag:NO]; + [[RadarLogBuffer sharedInstance] setPersistentLogFeatureFlag:NO]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:kFeatureSettings]; } } diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 255fcaa6d..5d5e2331a 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -298,7 +298,7 @@ - (void)setUp { self.fileSystem = [[RadarFileStorage alloc] init]; self.testFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"testfile"]; [[RadarLogBuffer sharedInstance]clearBuffer]; - [[RadarLogBuffer sharedInstance]setFeatureFlag:YES]; + [[RadarLogBuffer sharedInstance]setPersistentLogFeatureFlag:YES]; } From e6134b500f50687e6e421a7cad065f13b1211bfe Mon Sep 17 00:00:00 2001 From: Liam Meier Date: Mon, 18 Dec 2023 16:43:32 -0500 Subject: [PATCH 59/72] Styling nits --- RadarSDK/Include/Radar.h | 8 +++----- RadarSDK/RadarLogBuffer.m | 5 ++--- RadarSDKTests/RadarSDKTests.m | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/RadarSDK/Include/Radar.h b/RadarSDK/Include/Radar.h index 4932b9a44..b89d44610 100644 --- a/RadarSDK/Include/Radar.h +++ b/RadarSDK/Include/Radar.h @@ -1004,25 +1004,23 @@ logConversionWithNotification + (void)setLogLevel:(RadarLogLevel)level; /** - Log application terminating. + Log application terminating. Include this in your application delegate's applicationWillTerminate: method. */ + (void)logTermination; /** - Log application entering background and flush logs from memory buffer into persistent buffer. - + Log application entering background. Include this in your application delegate's applicationDidEnterBackground: method. */ + (void)logEnterBackground; /** - Log application resigning active. + Log application resigning active. Include this in your application delegate's applicationWillResignActive: method. */ + (void)logResignActive; - #pragma mark - Helpers /** diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 0475b3ceb..ca3fb6fd8 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -118,7 +118,7 @@ - (void)writeToFileStorage:(NSArray *)logs { for (RadarLog *log in logs) { NSData *logData = [NSKeyedArchiver archivedDataWithRootObject:log]; NSTimeInterval unixTimestamp = [log.createdAt timeIntervalSince1970]; - //logs may be created in the same millisecond, so we append a counter to the end of the timestamp to "tiebreak" + // Logs may be created in the same millisecond, so we append a counter to the end of the timestamp to "tiebreak" NSString *unixTimestampString = [NSString stringWithFormat:@"%lld%04d", (long long)unixTimestamp, counter++]; NSString *filePath = [self.logFileDir stringByAppendingPathComponent:unixTimestampString]; [self.fileHandler writeData:logData toFileAtPath:filePath]; @@ -129,8 +129,7 @@ - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *) @synchronized (self) { if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { [self writeToFileStorage:@[[[RadarLog alloc] initWithLevel:level type:type message:message]]]; - } - else{ + } else { [self write:level type:type message:message]; } } diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 5d5e2331a..40aa62a6b 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -12,6 +12,7 @@ #import "../RadarSDK/RadarAPIHelper.h" #import "../RadarSDK/RadarLocationManager.h" #import "../RadarSDK/RadarSettings.h" +#import "../RadarSDK/RadarLogBuffer.h" #import "CLLocationManagerMock.h" #import "CLVisitMock.h" #import "RadarAPIHelperMock.h" @@ -19,7 +20,6 @@ #import "RadarTestUtils.h" #import "RadarTripOptions.h" #import "RadarFileStorage.h" -#import "../RadarSDK/RadarLogBuffer.h" @interface RadarSDKTests : XCTestCase From f3c9c17c9404e28cbc96aee01863f5a757b2b88d Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 19 Dec 2023 15:59:19 -0500 Subject: [PATCH 60/72] code review changes --- RadarSDK/Radar.m | 10 +--- RadarSDK/RadarFileStorage.h | 4 +- RadarSDK/RadarFileStorage.m | 6 +-- RadarSDK/RadarLogBuffer.h | 6 +-- RadarSDK/RadarLogBuffer.m | 93 +++++++++++++++++++++-------------- RadarSDKTests/RadarSDKTests.m | 45 ++++------------- 6 files changed, 74 insertions(+), 90 deletions(-) diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index 65615aa36..b2a4d42c8 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1278,16 +1278,10 @@ + (void)flushLogs { return; } - // remove logs from buffer to handle multiple flushLogs calls - [[RadarLogBuffer sharedInstance] removeLogsFromBuffer:pendingLogCount]; - RadarSyncLogsAPICompletionHandler onComplete = ^(RadarStatus status) { - // if an error occurs in syncing, add the logs back to the buffer - if (status != RadarStatusSuccess) { - [[RadarLogBuffer sharedInstance] addLogsToBuffer:flushableLogs]; - } + [[RadarLogBuffer sharedInstance] onFlush:status == RadarStatusSuccess logs:flushableLogs]; }; - + [[RadarAPIClient sharedInstance] syncLogs:flushableLogs completionHandler:^(RadarStatus status) { if (onComplete) { diff --git a/RadarSDK/RadarFileStorage.h b/RadarSDK/RadarFileStorage.h index 7302e0ccb..b5fe73615 100644 --- a/RadarSDK/RadarFileStorage.h +++ b/RadarSDK/RadarFileStorage.h @@ -17,8 +17,8 @@ - (void)deleteFileAtPath:(NSString *)filePath; -- (NSArray *)allFilesInDirectory:(NSString *)directoryPath; +- (NSArray *)sortedFilesInDirector:(NSString *)directoryPath; -- (NSArray *)allFilesInDirectory:(NSString *)directoryPath withComparator:(NSComparator)comparator; +- (NSArray *)sortedFilesInDirector:(NSString *)directoryPath usingComparator:(NSComparator)comparator; @end diff --git a/RadarSDK/RadarFileStorage.m b/RadarSDK/RadarFileStorage.m index 8a50d9eac..dd021a2f5 100644 --- a/RadarSDK/RadarFileStorage.m +++ b/RadarSDK/RadarFileStorage.m @@ -39,13 +39,13 @@ - (void)deleteFileAtPath:(NSString *)filePath { }]; } -- (NSArray *)allFilesInDirectory:(NSString *)directoryPath { - return [self allFilesInDirectory:directoryPath withComparator:^NSComparisonResult(NSString *fileName1, NSString *fileName2) { +- (NSArray *)sortedFilesInDirector:(NSString *)directoryPath { + return [self sortedFilesInDirector:directoryPath usingComparator:^NSComparisonResult(NSString *fileName1, NSString *fileName2) { return [fileName1 compare:fileName2]; }]; } -- (NSArray *)allFilesInDirectory:(NSString *)directoryPath withComparator:(NSComparator)comparator { +- (NSArray *)sortedFilesInDirector:(NSString *)directoryPath usingComparator:(NSComparator)comparator { NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error = nil; NSArray *files = [fileManager contentsOfDirectoryAtPath:directoryPath error:&error]; diff --git a/RadarSDK/RadarLogBuffer.h b/RadarSDK/RadarLogBuffer.h index 5b4e0e663..c45044c63 100644 --- a/RadarSDK/RadarLogBuffer.h +++ b/RadarSDK/RadarLogBuffer.h @@ -30,12 +30,10 @@ NS_ASSUME_NONNULL_BEGIN - (void)clearBuffer; -- (void)removeLogsFromBuffer:(NSUInteger)numLogs; - -- (void)addLogsToBuffer:(NSArray *)logs; - - (void)setPersistentLogFeatureFlag:(BOOL)persistentLogFeatureFlag; +- (void)onFlush:(BOOL)success logs:(NSArray *)logs; + @end NS_ASSUME_NONNULL_END diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index ca3fb6fd8..38823b322 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -20,7 +20,6 @@ static int counter = 0; @implementation RadarLogBuffer { - NSMutableArray *mutableLogBuffer; NSMutableArray *inMemoryLogBuffer; } @@ -28,7 +27,6 @@ - (instancetype)init { self = [super init]; if (self) { _persistentLogFeatureFlag = [RadarSettings featureSettings].useLogPersistence; - mutableLogBuffer = [NSMutableArray new]; inMemoryLogBuffer = [NSMutableArray new]; NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; @@ -58,22 +56,18 @@ + (instancetype)sharedInstance { - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { @synchronized (self) { - NSUInteger logLength = [mutableLogBuffer count]; - if (logLength >= MAX_BUFFER_SIZE) { - [self purgeOldestLogs]; - } - // add new log to buffer RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; - [mutableLogBuffer addObject:radarLog]; - - if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { - RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; - [inMemoryLogBuffer addObject:radarLog]; - NSUInteger logLength = [inMemoryLogBuffer count]; + [inMemoryLogBuffer addObject:radarLog]; + NSUInteger logLength = [inMemoryLogBuffer count]; + if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { if (logLength >= MAX_MEMORY_BUFFER_SIZE) { [self persistLogs]; } - } + } else { + if (logLength >= MAX_BUFFER_SIZE) { + [self purgeOldestLogs]; + } + } } } @@ -81,18 +75,21 @@ - (void)persistLogs { @synchronized (self) { if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { NSArray *flushableLogs = [inMemoryLogBuffer copy]; - [self addLogsToBuffer:flushableLogs]; + [self writeToFileStorage:flushableLogs]; + [self purgeOldestLogs]; [inMemoryLogBuffer removeAllObjects]; } } } - (NSArray *)getLogFilesInTimeOrder { + NSString *characterToStrip = @"_"; NSComparator compareTimeStamps = ^NSComparisonResult(NSString *str1, NSString *str2) { - return [@([str1 integerValue]) compare:@([str2 integerValue])]; + return [@([[str1 stringByReplacingOccurrencesOfString:characterToStrip withString:@""] integerValue]) + compare:@([[str2 stringByReplacingOccurrencesOfString:characterToStrip withString:@""] integerValue])]; }; - return [self.fileHandler allFilesInDirectory:self.logFileDir withComparator:compareTimeStamps]; + return [self.fileHandler sortedFilesInDirector:self.logFileDir usingComparator:compareTimeStamps]; } - (NSMutableArray *)readFromFileStorage { @@ -119,7 +116,7 @@ - (void)writeToFileStorage:(NSArray *)logs { NSData *logData = [NSKeyedArchiver archivedDataWithRootObject:log]; NSTimeInterval unixTimestamp = [log.createdAt timeIntervalSince1970]; // Logs may be created in the same millisecond, so we append a counter to the end of the timestamp to "tiebreak" - NSString *unixTimestampString = [NSString stringWithFormat:@"%lld%04d", (long long)unixTimestamp, counter++]; + NSString *unixTimestampString = [NSString stringWithFormat:@"%lld_%04d", (long long)unixTimestamp, counter++]; NSString *filePath = [self.logFileDir stringByAppendingPathComponent:unixTimestampString]; [self.fileHandler writeData:logData toFileAtPath:filePath]; } @@ -142,24 +139,40 @@ - (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *) NSArray *existingLogsArray = [self.readFromFileStorage copy]; return existingLogsArray; } else { - NSArray *flushableLogs = [mutableLogBuffer copy]; + NSArray *flushableLogs = [inMemoryLogBuffer copy]; + [inMemoryLogBuffer removeAllObjects]; return flushableLogs; } } } - (void)purgeOldestLogs { - // drop the oldest N logs from the buffer - [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; - RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; - [mutableLogBuffer insertObject:purgeLog atIndex:0]; + if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { + NSArray *files = [self getLogFilesInTimeOrder]; + NSUInteger dirSize = [files count]; + BOOL printedPurgedLogs = NO; + while (dirSize >= MAX_PERSISTED_BUFFER_SIZE) { + [self removeLogs:PURGE_AMOUNT]; + dirSize = [[self getLogFilesInTimeOrder] count]; + if (!printedPurgedLogs) { + printedPurgedLogs = YES; + RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; + [self writeToFileStorage:@[purgeLog]]; + } + } + } else { + // drop the oldest N logs from the buffer + [inMemoryLogBuffer removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; + RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; + [inMemoryLogBuffer insertObject:purgeLog atIndex:0]; + } } + -- (void)removeLogsFromBuffer:(NSUInteger)numLogs { +- (void)removeLogs:(NSUInteger)numLogs { @synchronized (self) { - [mutableLogBuffer removeObjectsInRange:NSMakeRange(0, MIN(numLogs, [mutableLogBuffer count]))]; if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { NSArray *files = [self getLogFilesInTimeOrder]; for (NSUInteger i = 0; i < MIN(numLogs, [files count]); i++) { @@ -167,25 +180,31 @@ - (void)removeLogsFromBuffer:(NSUInteger)numLogs { NSString *filePath = [self.logFileDir stringByAppendingPathComponent:file]; [self.fileHandler deleteFileAtPath:filePath]; } + } else { + [inMemoryLogBuffer removeObjectsInRange:NSMakeRange(0, MIN(numLogs, [inMemoryLogBuffer count]))]; } } } -- (void)addLogsToBuffer:(NSArray *)logs { + +- (void)onFlush:(BOOL)success logs:(NSArray *)logs{ @synchronized (self) { - [mutableLogBuffer addObjectsFromArray:logs]; if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { - NSArray *files = [self getLogFilesInTimeOrder]; - NSUInteger bufferSize = [files count]; - NSUInteger logLength = [logs count]; - while (bufferSize + logLength >= MAX_PERSISTED_BUFFER_SIZE) { - [self removeLogsFromBuffer:PURGE_AMOUNT]; - bufferSize = [[self getLogFilesInTimeOrder] count]; - RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; - [self writeToFileStorage:@[purgeLog]]; + if (success) { + // Remove all logs files from disk + [self removeLogs:[logs count]]; + } else { + // Attempt purge to only remove the oldest logs to reduce payload size of next attempt. + [self purgeOldestLogs]; } - [self writeToFileStorage:logs]; - } + } else { + if (!success) { + [inMemoryLogBuffer addObjectsFromArray:logs]; + if ([inMemoryLogBuffer count] >= MAX_BUFFER_SIZE) { + [self purgeOldestLogs]; + } + } + } } } diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 40aa62a6b..d5c753cbb 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -1423,12 +1423,12 @@ - (void)test_RadarFileStorage_allFilesInDirectory { } [[NSFileManager defaultManager] createDirectoryAtPath:testDir withIntermediateDirectories:YES attributes:nil error:nil]; - NSArray *files = [self.fileSystem allFilesInDirectory: testDir]; + NSArray *files = [self.fileSystem sortedFilesInDirector: testDir]; XCTAssertEqual(files.count, 0); NSData *originalData = [@"Test data" dataUsingEncoding:NSUTF8StringEncoding]; [self.fileSystem writeData:originalData toFileAtPath: [testDir stringByAppendingPathComponent: @"file1"]]; [self.fileSystem writeData:originalData toFileAtPath: [testDir stringByAppendingPathComponent: @"file2"]]; - NSArray *newFiles = [self.fileSystem allFilesInDirectory: testDir]; + NSArray *newFiles = [self.fileSystem sortedFilesInDirector: testDir]; XCTAssertEqual(newFiles.count, 2); } @@ -1456,47 +1456,19 @@ - (void)test_RadarLogBuffer_writeAndFlushableLogs { XCTAssertEqualObjects(newLogs.lastObject.message, @"Test message 3"); } -- (void)test_RadarLogBuffer_removeLogsFromBuffer { +- (void)test_RadarLogBuffer_flush { [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; [[RadarLogBuffer sharedInstance]persistLogs]; - [[RadarLogBuffer sharedInstance]removeLogsFromBuffer:2]; NSArray *logs = [[RadarLogBuffer sharedInstance]flushableLogs]; + [[RadarLogBuffer sharedInstance] onFlush:NO logs:logs]; + logs = [[RadarLogBuffer sharedInstance]flushableLogs]; + XCTAssertEqual(logs.count, 2); + [[RadarLogBuffer sharedInstance] onFlush:YES logs:logs]; + logs = [[RadarLogBuffer sharedInstance]flushableLogs]; XCTAssertEqual(logs.count, 0); } -- (void)test_RadarLogBuffer_addLogsToBuffrer { - RadarLog *log1 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; - RadarLog *log2 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; - RadarLog *log3 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 3"]; - RadarLog *log4 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 4"]; - [[RadarLogBuffer sharedInstance]addLogsToBuffer:@[log1, log2]]; - [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; - [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; - [[RadarLogBuffer sharedInstance]persistLogs]; - [[RadarLogBuffer sharedInstance]addLogsToBuffer:@[log3, log4]]; - NSArray *logs = [[RadarLogBuffer sharedInstance]flushableLogs]; - XCTAssertEqual(logs.count, 6); - XCTAssertEqualObjects(logs.lastObject.message, @"Test message 4"); -} - -- (void)test_RadarLogBuffer_addAndRemove{ - RadarLog *log1 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; - RadarLog *log2 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; - RadarLog *log3 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 3"]; - RadarLog *log4 = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 4"]; - [[RadarLogBuffer sharedInstance]addLogsToBuffer:@[log1, log2]]; - [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; - [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message"]; - [[RadarLogBuffer sharedInstance]persistLogs]; - [[RadarLogBuffer sharedInstance]addLogsToBuffer:@[log3, log4]]; - NSArray *logs = [[RadarLogBuffer sharedInstance]flushableLogs]; - [[RadarLogBuffer sharedInstance]removeLogsFromBuffer:6]; - [[RadarLogBuffer sharedInstance]addLogsToBuffer:logs]; - NSArray *logs1 = [[RadarLogBuffer sharedInstance]flushableLogs]; - XCTAssertEqual(logs1.count, 6); -} - - (void)test_RadarLogBuffer_append { [[RadarLogBuffer sharedInstance]append:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; [[RadarLogBuffer sharedInstance]append:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; @@ -1518,4 +1490,5 @@ - (void)test_RadarLogBuffer_purge { [[RadarLogBuffer sharedInstance]clearBuffer]; } + @end From 53a94aa715957f57e459c8648584c8fdbb5707d4 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 20 Dec 2023 10:27:16 -0500 Subject: [PATCH 61/72] fixed typo --- RadarSDK/RadarFileStorage.h | 4 ++-- RadarSDK/RadarFileStorage.m | 6 +++--- RadarSDK/RadarLogBuffer.m | 2 +- RadarSDKTests/RadarSDKTests.m | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/RadarSDK/RadarFileStorage.h b/RadarSDK/RadarFileStorage.h index b5fe73615..4d8e3602b 100644 --- a/RadarSDK/RadarFileStorage.h +++ b/RadarSDK/RadarFileStorage.h @@ -17,8 +17,8 @@ - (void)deleteFileAtPath:(NSString *)filePath; -- (NSArray *)sortedFilesInDirector:(NSString *)directoryPath; +- (NSArray *)sortedFilesInDirectory:(NSString *)directoryPath; -- (NSArray *)sortedFilesInDirector:(NSString *)directoryPath usingComparator:(NSComparator)comparator; +- (NSArray *)sortedFilesInDirectory:(NSString *)directoryPath usingComparator:(NSComparator)comparator; @end diff --git a/RadarSDK/RadarFileStorage.m b/RadarSDK/RadarFileStorage.m index dd021a2f5..47900065e 100644 --- a/RadarSDK/RadarFileStorage.m +++ b/RadarSDK/RadarFileStorage.m @@ -39,13 +39,13 @@ - (void)deleteFileAtPath:(NSString *)filePath { }]; } -- (NSArray *)sortedFilesInDirector:(NSString *)directoryPath { - return [self sortedFilesInDirector:directoryPath usingComparator:^NSComparisonResult(NSString *fileName1, NSString *fileName2) { +- (NSArray *)sortedFilesInDirectory:(NSString *)directoryPath { + return [self sortedFilesInDirectory:directoryPath usingComparator:^NSComparisonResult(NSString *fileName1, NSString *fileName2) { return [fileName1 compare:fileName2]; }]; } -- (NSArray *)sortedFilesInDirector:(NSString *)directoryPath usingComparator:(NSComparator)comparator { +- (NSArray *)sortedFilesInDirectory:(NSString *)directoryPath usingComparator:(NSComparator)comparator { NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error = nil; NSArray *files = [fileManager contentsOfDirectoryAtPath:directoryPath error:&error]; diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 38823b322..4c963e4e4 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -89,7 +89,7 @@ - (void)persistLogs { compare:@([[str2 stringByReplacingOccurrencesOfString:characterToStrip withString:@""] integerValue])]; }; - return [self.fileHandler sortedFilesInDirector:self.logFileDir usingComparator:compareTimeStamps]; + return [self.fileHandler sortedFilesInDirectory:self.logFileDir usingComparator:compareTimeStamps]; } - (NSMutableArray *)readFromFileStorage { diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index d5c753cbb..eb06a4a33 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -1423,12 +1423,12 @@ - (void)test_RadarFileStorage_allFilesInDirectory { } [[NSFileManager defaultManager] createDirectoryAtPath:testDir withIntermediateDirectories:YES attributes:nil error:nil]; - NSArray *files = [self.fileSystem sortedFilesInDirector: testDir]; + NSArray *files = [self.fileSystem sortedFilesInDirectory: testDir]; XCTAssertEqual(files.count, 0); NSData *originalData = [@"Test data" dataUsingEncoding:NSUTF8StringEncoding]; [self.fileSystem writeData:originalData toFileAtPath: [testDir stringByAppendingPathComponent: @"file1"]]; [self.fileSystem writeData:originalData toFileAtPath: [testDir stringByAppendingPathComponent: @"file2"]]; - NSArray *newFiles = [self.fileSystem sortedFilesInDirector: testDir]; + NSArray *newFiles = [self.fileSystem sortedFilesInDirectory: testDir]; XCTAssertEqual(newFiles.count, 2); } From 3b978bd93a8fa159be95eccc88b4287651182d69 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 20 Dec 2023 12:28:00 -0500 Subject: [PATCH 62/72] remove append --- RadarSDK/RadarLogBuffer.h | 2 +- RadarSDK/RadarLogBuffer.m | 9 ++++++--- RadarSDK/RadarLogger.m | 2 +- RadarSDKTests/RadarSDKTests.m | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.h b/RadarSDK/RadarLogBuffer.h index c45044c63..3385e64a6 100644 --- a/RadarSDK/RadarLogBuffer.h +++ b/RadarSDK/RadarLogBuffer.h @@ -24,7 +24,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; -- (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; +- (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message forceFlush:(BOOL)forceFlush; - (void)persistLogs; diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 4c963e4e4..e8eede9ba 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -55,16 +55,19 @@ + (instancetype)sharedInstance { } - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { + [self write:level type:type message:message forceFlush:NO]; +} + +- (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message forceFlush:(BOOL)forceFlush{ @synchronized (self) { RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; [inMemoryLogBuffer addObject:radarLog]; - NSUInteger logLength = [inMemoryLogBuffer count]; if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { - if (logLength >= MAX_MEMORY_BUFFER_SIZE) { + if (forceFlush || [inMemoryLogBuffer count] >= MAX_MEMORY_BUFFER_SIZE) { [self persistLogs]; } } else { - if (logLength >= MAX_BUFFER_SIZE) { + if ([inMemoryLogBuffer count] >= MAX_BUFFER_SIZE) { [self purgeOldestLogs]; } } diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index c022fea46..33e09f987 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -59,7 +59,7 @@ - (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSStr message = [NSString stringWithFormat:@"%@ | with %2.f%% battery", message, batteryLevel*100]; } if (append) { - [[RadarLogBuffer sharedInstance] append:level type:type message:message]; + [[RadarLogBuffer sharedInstance] write:level type:type message:message forceFlush:YES]; } else { dispatch_async(dispatch_get_main_queue(), ^{ [Radar sendLog:level type:type message:message]; diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index eb06a4a33..7e7cbd0d3 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -1470,8 +1470,8 @@ - (void)test_RadarLogBuffer_flush { } - (void)test_RadarLogBuffer_append { - [[RadarLogBuffer sharedInstance]append:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1"]; - [[RadarLogBuffer sharedInstance]append:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2"]; + [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1" forceFlush:YES]; + [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2" forceFlush:YES]; NSArray *logs = [[RadarLogBuffer sharedInstance]flushableLogs]; XCTAssertEqual(logs.count, 2); XCTAssertEqualObjects(logs.firstObject.message, @"Test message 1"); From 205e8f3d68499208f8df44f08bf70557aa139d5c Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 20 Dec 2023 14:01:57 -0500 Subject: [PATCH 63/72] change-name --- RadarSDK/RadarLogBuffer.h | 2 +- RadarSDK/RadarLogBuffer.m | 16 +++------------- RadarSDK/RadarLogger.m | 2 +- RadarSDKTests/RadarSDKTests.m | 4 ++-- 4 files changed, 7 insertions(+), 17 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.h b/RadarSDK/RadarLogBuffer.h index 3385e64a6..d5fb6366c 100644 --- a/RadarSDK/RadarLogBuffer.h +++ b/RadarSDK/RadarLogBuffer.h @@ -24,7 +24,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message; -- (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message forceFlush:(BOOL)forceFlush; +- (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message forcePersist:(BOOL)forcePersist; - (void)persistLogs; diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index e8eede9ba..06cbba926 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -55,15 +55,15 @@ + (instancetype)sharedInstance { } - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { - [self write:level type:type message:message forceFlush:NO]; + [self write:level type:type message:message forcePersist:NO]; } -- (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message forceFlush:(BOOL)forceFlush{ +- (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message forcePersist:(BOOL)forcePersist{ @synchronized (self) { RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; [inMemoryLogBuffer addObject:radarLog]; if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { - if (forceFlush || [inMemoryLogBuffer count] >= MAX_MEMORY_BUFFER_SIZE) { + if (forcePersist || [inMemoryLogBuffer count] >= MAX_MEMORY_BUFFER_SIZE) { [self persistLogs]; } } else { @@ -125,16 +125,6 @@ - (void)writeToFileStorage:(NSArray *)logs { } } -- (void)append:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message { - @synchronized (self) { - if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { - [self writeToFileStorage:@[[[RadarLog alloc] initWithLevel:level type:type message:message]]]; - } else { - [self write:level type:type message:message]; - } - } -} - - (NSArray *)flushableLogs { @synchronized (self) { if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { diff --git a/RadarSDK/RadarLogger.m b/RadarSDK/RadarLogger.m index 33e09f987..a04751c41 100644 --- a/RadarSDK/RadarLogger.m +++ b/RadarSDK/RadarLogger.m @@ -59,7 +59,7 @@ - (void)logWithLevel:(RadarLogLevel)level type:(RadarLogType)type message:(NSStr message = [NSString stringWithFormat:@"%@ | with %2.f%% battery", message, batteryLevel*100]; } if (append) { - [[RadarLogBuffer sharedInstance] write:level type:type message:message forceFlush:YES]; + [[RadarLogBuffer sharedInstance] write:level type:type message:message forcePersist:YES]; } else { dispatch_async(dispatch_get_main_queue(), ^{ [Radar sendLog:level type:type message:message]; diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 7e7cbd0d3..926ef6251 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -1470,8 +1470,8 @@ - (void)test_RadarLogBuffer_flush { } - (void)test_RadarLogBuffer_append { - [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1" forceFlush:YES]; - [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2" forceFlush:YES]; + [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 1" forcePersist:YES]; + [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 2" forcePersist:YES]; NSArray *logs = [[RadarLogBuffer sharedInstance]flushableLogs]; XCTAssertEqual(logs.count, 2); XCTAssertEqualObjects(logs.firstObject.message, @"Test message 1"); From 6c9b15ab48000333a98481f3f093da3f3ab242ec Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 2 Jan 2024 12:51:20 -0500 Subject: [PATCH 64/72] race condition fix --- RadarSDK/RadarLogBuffer.m | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 06cbba926..5667e8142 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -130,6 +130,7 @@ - (void)writeToFileStorage:(NSArray *)logs { if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { [self persistLogs]; NSArray *existingLogsArray = [self.readFromFileStorage copy]; + [self removeLogs:[existingLogsArray count]]; return existingLogsArray; } else { NSArray *flushableLogs = [inMemoryLogBuffer copy]; @@ -165,7 +166,6 @@ - (void)purgeOldestLogs { - (void)removeLogs:(NSUInteger)numLogs { @synchronized (self) { - if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { NSArray *files = [self getLogFilesInTimeOrder]; for (NSUInteger i = 0; i < MIN(numLogs, [files count]); i++) { @@ -183,11 +183,9 @@ - (void)removeLogs:(NSUInteger)numLogs { - (void)onFlush:(BOOL)success logs:(NSArray *)logs{ @synchronized (self) { if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { - if (success) { - // Remove all logs files from disk - [self removeLogs:[logs count]]; - } else { - // Attempt purge to only remove the oldest logs to reduce payload size of next attempt. + if (!success) { + [self writeToFileStorage:logs]; + // Attempt purge to only remove the oldest logs to reduce payload size of next attempt. [self purgeOldestLogs]; } } else { From e1b07271b855b9f964d4b9bbc072eb1c8f262dff Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 2 Jan 2024 13:01:23 -0500 Subject: [PATCH 65/72] fix test --- RadarSDKTests/RadarSDKTests.m | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/RadarSDKTests/RadarSDKTests.m b/RadarSDKTests/RadarSDKTests.m index 926ef6251..88336d19e 100644 --- a/RadarSDKTests/RadarSDKTests.m +++ b/RadarSDKTests/RadarSDKTests.m @@ -1451,9 +1451,8 @@ - (void)test_RadarLogBuffer_writeAndFlushableLogs { XCTAssertEqualObjects(logs.lastObject.message, @"Test message 2"); [[RadarLogBuffer sharedInstance]write:RadarLogLevelDebug type:RadarLogTypeNone message:@"Test message 3"]; NSArray *newLogs = [[RadarLogBuffer sharedInstance]flushableLogs]; - XCTAssertEqual(newLogs.count, 3); - XCTAssertEqualObjects(newLogs.firstObject.message, @"Test message 1"); - XCTAssertEqualObjects(newLogs.lastObject.message, @"Test message 3"); + XCTAssertEqual(newLogs.count, 1); + XCTAssertEqualObjects(newLogs.firstObject.message, @"Test message 3"); } - (void)test_RadarLogBuffer_flush { From 8eff93ede7c4d82b76151873d3ad61fb54949127 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 2 Jan 2024 15:31:38 -0500 Subject: [PATCH 66/72] added a comment --- RadarSDK/RadarLogBuffer.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 5667e8142..84a294b2f 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -199,7 +199,9 @@ - (void)onFlush:(BOOL)success logs:(NSArray *)logs{ } } -//for use in testing +/** +* Clears the in-memory buffer and deletes all persisted logs. (For use in testing only.) +*/ -(void)clearBuffer { @synchronized (self) { [inMemoryLogBuffer removeAllObjects]; From df3176e4926344d4ff372bae1101800258bb9b20 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 2 Jan 2024 15:41:27 -0500 Subject: [PATCH 67/72] version bump --- RadarSDK.podspec | 2 +- RadarSDK.xcodeproj/project.pbxproj | 8 ++++---- RadarSDK/RadarUtils.m | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/RadarSDK.podspec b/RadarSDK.podspec index ffd0f2607..73fb30c11 100644 --- a/RadarSDK.podspec +++ b/RadarSDK.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'RadarSDK' - s.version = '3.8.12' + s.version = '3.8.13' s.summary = 'iOS SDK for Radar, the leading geofencing and location tracking platform' s.homepage = 'https://radar.com' s.author = { 'Radar Labs, Inc.' => 'support@radar.com' } diff --git a/RadarSDK.xcodeproj/project.pbxproj b/RadarSDK.xcodeproj/project.pbxproj index 1a1b28d17..fbecb6ede 100644 --- a/RadarSDK.xcodeproj/project.pbxproj +++ b/RadarSDK.xcodeproj/project.pbxproj @@ -868,7 +868,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 3.8.12; + MARKETING_VERSION = 3.8.13; PRODUCT_BUNDLE_IDENTIFIER = io.radar.sdk; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -898,7 +898,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 3.8.12; + MARKETING_VERSION = 3.8.13; PRODUCT_BUNDLE_IDENTIFIER = io.radar.sdk; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -981,7 +981,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MARKETING_VERSION = 3.8.12; + MARKETING_VERSION = 3.8.13; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -1039,7 +1039,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MARKETING_VERSION = 3.8.12; + MARKETING_VERSION = 3.8.13; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; OTHER_CFLAGS = "-fembed-bitcode"; diff --git a/RadarSDK/RadarUtils.m b/RadarSDK/RadarUtils.m index 1ac4561b6..17e2cf75d 100644 --- a/RadarSDK/RadarUtils.m +++ b/RadarSDK/RadarUtils.m @@ -45,7 +45,7 @@ + (NSNumber *)timeZoneOffset { } + (NSString *)sdkVersion { - return @"3.8.12"; + return @"3.8.13"; } + (NSString *)deviceId { From a89cb6687cc56c2a6c816707cf0e2edb5368f385 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 3 Jan 2024 10:25:12 -0500 Subject: [PATCH 68/72] refactor and fix format --- RadarSDK/RadarLogBuffer.m | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index 84a294b2f..cb6e3296c 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -17,7 +17,7 @@ static NSString *const kPurgedLogLine = @"----- purged oldest logs -----"; -static int counter = 0; +static int fileCounter = 0; @implementation RadarLogBuffer { NSMutableArray *inMemoryLogBuffer; @@ -58,7 +58,7 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m [self write:level type:type message:message forcePersist:NO]; } -- (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message forcePersist:(BOOL)forcePersist{ +- (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message forcePersist:(BOOL)forcePersist { @synchronized (self) { RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; [inMemoryLogBuffer addObject:radarLog]; @@ -77,10 +77,12 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m - (void)persistLogs { @synchronized (self) { if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { - NSArray *flushableLogs = [inMemoryLogBuffer copy]; - [self writeToFileStorage:flushableLogs]; - [self purgeOldestLogs]; - [inMemoryLogBuffer removeAllObjects]; + if([inMemoryLogBuffer count] > 0) { + [self writeToFileStorage:inMemoryLogBuffer]; + [self purgeOldestLogs]; + [inMemoryLogBuffer removeAllObjects]; + } + } } } @@ -119,7 +121,7 @@ - (void)writeToFileStorage:(NSArray *)logs { NSData *logData = [NSKeyedArchiver archivedDataWithRootObject:log]; NSTimeInterval unixTimestamp = [log.createdAt timeIntervalSince1970]; // Logs may be created in the same millisecond, so we append a counter to the end of the timestamp to "tiebreak" - NSString *unixTimestampString = [NSString stringWithFormat:@"%lld_%04d", (long long)unixTimestamp, counter++]; + NSString *unixTimestampString = [NSString stringWithFormat:@"%lld_%04d", (long long)unixTimestamp, fileCounter++]; NSString *filePath = [self.logFileDir stringByAppendingPathComponent:unixTimestampString]; [self.fileHandler writeData:logData toFileAtPath:filePath]; } From 7960e22ac613fef083092db7447b69c8fd1eca6a Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 3 Jan 2024 11:24:33 -0500 Subject: [PATCH 69/72] rename and format --- RadarSDK/RadarLogBuffer.m | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index cb6e3296c..fa6cbe6a2 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -20,14 +20,14 @@ static int fileCounter = 0; @implementation RadarLogBuffer { - NSMutableArray *inMemoryLogBuffer; + NSMutableArray *logBuffer; } - (instancetype)init { self = [super init]; if (self) { _persistentLogFeatureFlag = [RadarSettings featureSettings].useLogPersistence; - inMemoryLogBuffer = [NSMutableArray new]; + logBuffer = [NSMutableArray new]; NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; self.logFileDir = [documentsDirectory stringByAppendingPathComponent:@"radar_logs"]; @@ -61,13 +61,13 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message forcePersist:(BOOL)forcePersist { @synchronized (self) { RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; - [inMemoryLogBuffer addObject:radarLog]; + [logBuffer addObject:radarLog]; if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { - if (forcePersist || [inMemoryLogBuffer count] >= MAX_MEMORY_BUFFER_SIZE) { + if (forcePersist || [logBuffer count] >= MAX_MEMORY_BUFFER_SIZE) { [self persistLogs]; } } else { - if ([inMemoryLogBuffer count] >= MAX_BUFFER_SIZE) { + if ([logBuffer count] >= MAX_BUFFER_SIZE) { [self purgeOldestLogs]; } } @@ -77,10 +77,10 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m - (void)persistLogs { @synchronized (self) { if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { - if([inMemoryLogBuffer count] > 0) { - [self writeToFileStorage:inMemoryLogBuffer]; + if ([logBuffer count] > 0) { + [self writeToFileStorage:logBuffer]; [self purgeOldestLogs]; - [inMemoryLogBuffer removeAllObjects]; + [logBuffer removeAllObjects]; } } @@ -135,8 +135,8 @@ - (void)writeToFileStorage:(NSArray *)logs { [self removeLogs:[existingLogsArray count]]; return existingLogsArray; } else { - NSArray *flushableLogs = [inMemoryLogBuffer copy]; - [inMemoryLogBuffer removeAllObjects]; + NSArray *flushableLogs = [logBuffer copy]; + [logBuffer removeAllObjects]; return flushableLogs; } } @@ -158,9 +158,9 @@ - (void)purgeOldestLogs { } } else { // drop the oldest N logs from the buffer - [inMemoryLogBuffer removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; + [logBuffer removeObjectsInRange:NSMakeRange(0, PURGE_AMOUNT)]; RadarLog *purgeLog = [[RadarLog alloc] initWithLevel:RadarLogLevelDebug type:RadarLogTypeNone message:kPurgedLogLine]; - [inMemoryLogBuffer insertObject:purgeLog atIndex:0]; + [logBuffer insertObject:purgeLog atIndex:0]; } } @@ -176,7 +176,7 @@ - (void)removeLogs:(NSUInteger)numLogs { [self.fileHandler deleteFileAtPath:filePath]; } } else { - [inMemoryLogBuffer removeObjectsInRange:NSMakeRange(0, MIN(numLogs, [inMemoryLogBuffer count]))]; + [logBuffer removeObjectsInRange:NSMakeRange(0, MIN(numLogs, [logBuffer count]))]; } } } @@ -192,8 +192,8 @@ - (void)onFlush:(BOOL)success logs:(NSArray *)logs{ } } else { if (!success) { - [inMemoryLogBuffer addObjectsFromArray:logs]; - if ([inMemoryLogBuffer count] >= MAX_BUFFER_SIZE) { + [logBuffer addObjectsFromArray:logs]; + if ([logBuffer count] >= MAX_BUFFER_SIZE) { [self purgeOldestLogs]; } } @@ -206,7 +206,7 @@ - (void)onFlush:(BOOL)success logs:(NSArray *)logs{ */ -(void)clearBuffer { @synchronized (self) { - [inMemoryLogBuffer removeAllObjects]; + [logBuffer removeAllObjects]; NSArray *files = [self getLogFilesInTimeOrder]; if (files) { for (NSString *file in files) { From fbc619ffc8c178bcb50852a4b37702fc7ece5445 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 3 Jan 2024 13:05:07 -0500 Subject: [PATCH 70/72] update names --- RadarSDK/Include/Radar.h | 4 ++-- RadarSDK/Radar.m | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/RadarSDK/Include/Radar.h b/RadarSDK/Include/Radar.h index b89d44610..89b268851 100644 --- a/RadarSDK/Include/Radar.h +++ b/RadarSDK/Include/Radar.h @@ -1012,13 +1012,13 @@ logConversionWithNotification /** Log application entering background. Include this in your application delegate's applicationDidEnterBackground: method. */ -+ (void)logEnterBackground; ++ (void)logBackgrounding; /** Log application resigning active. Include this in your application delegate's applicationWillResignActive: method. */ -+ (void)logResignActive; ++ (void)logResigningActive; #pragma mark - Helpers diff --git a/RadarSDK/Radar.m b/RadarSDK/Radar.m index b2a4d42c8..63ef9912a 100644 --- a/RadarSDK/Radar.m +++ b/RadarSDK/Radar.m @@ -1042,12 +1042,12 @@ + (void)logTermination { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App terminating" includeDate:YES includeBattery:YES append:YES]; } -+ (void)logEnterBackground { ++ (void)logBackgrounding { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App entering background" includeDate:YES includeBattery:YES append:YES]; [[RadarLogBuffer sharedInstance] persistLogs]; } -+ (void)logResignActive { ++ (void)logResigningActive { [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelInfo type:RadarLogTypeNone message:@"App resigning active" includeDate:YES includeBattery:YES]; } From d6e47852fbc91c25742f605e78510fbf6f8a45f3 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Wed, 3 Jan 2024 16:22:09 -0500 Subject: [PATCH 71/72] increase flush freq --- RadarSDK/RadarLogBuffer.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index fa6cbe6a2..fbaa2cc65 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -35,7 +35,7 @@ - (instancetype)init { [[NSFileManager defaultManager] createDirectoryAtPath:self.logFileDir withIntermediateDirectories:YES attributes:nil error:nil]; } self.fileHandler = [[RadarFileStorage alloc] init]; - _timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(persistLogs) userInfo:nil repeats:YES]; + _timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(persistLogs) userInfo:nil repeats:YES]; } return self; @@ -79,7 +79,6 @@ - (void)persistLogs { if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { if ([logBuffer count] > 0) { [self writeToFileStorage:logBuffer]; - [self purgeOldestLogs]; [logBuffer removeAllObjects]; } @@ -131,6 +130,7 @@ - (void)writeToFileStorage:(NSArray *)logs { @synchronized (self) { if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { [self persistLogs]; + [self purgeOldestLogs]; NSArray *existingLogsArray = [self.readFromFileStorage copy]; [self removeLogs:[existingLogsArray count]]; return existingLogsArray; From 677067f80fcf9e1de27a17fcb679766307be3732 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 4 Jan 2024 13:12:33 -0500 Subject: [PATCH 72/72] remove the force persist writes from the lock --- RadarSDK/RadarLogBuffer.m | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/RadarSDK/RadarLogBuffer.m b/RadarSDK/RadarLogBuffer.m index fbaa2cc65..604612a98 100644 --- a/RadarSDK/RadarLogBuffer.m +++ b/RadarSDK/RadarLogBuffer.m @@ -59,11 +59,16 @@ - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)m } - (void)write:(RadarLogLevel)level type:(RadarLogType)type message:(NSString *)message forcePersist:(BOOL)forcePersist { + RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; + // bypass sync lock here to ensure that other writes or persisting logs don't block the current thread as the app is terminating + if (forcePersist && (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"])) { + [self writeToFileStorage:@[radarLog]]; + return; + } @synchronized (self) { - RadarLog *radarLog = [[RadarLog alloc] initWithLevel:level type:type message:message]; [logBuffer addObject:radarLog]; if (_persistentLogFeatureFlag || [[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"]) { - if (forcePersist || [logBuffer count] >= MAX_MEMORY_BUFFER_SIZE) { + if ([logBuffer count] >= MAX_MEMORY_BUFFER_SIZE) { [self persistLogs]; } } else {