diff --git a/Analytics.xcodeproj/project.pbxproj b/Analytics.xcodeproj/project.pbxproj index a88038d2f..724b881b8 100644 --- a/Analytics.xcodeproj/project.pbxproj +++ b/Analytics.xcodeproj/project.pbxproj @@ -866,7 +866,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.1; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -919,7 +919,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.1; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; diff --git a/Analytics/Classes/Internal/SEGFileStorage.m b/Analytics/Classes/Internal/SEGFileStorage.m index 1123f913b..c25594999 100644 --- a/Analytics/Classes/Internal/SEGFileStorage.m +++ b/Analytics/Classes/Internal/SEGFileStorage.m @@ -51,6 +51,13 @@ - (void)resetAll - (void)setData:(NSData *)data forKey:(NSString *)key { NSURL *url = [self urlForKey:key]; + + // a nil value was supplied, remove the storage for said key. + if (data == nil) { + [[NSFileManager defaultManager] removeItemAtURL:url error:nil]; + return; + } + if (self.crypto) { NSData *encryptedData = [self.crypto encrypt:data]; [encryptedData writeToURL:url atomically:YES]; @@ -80,40 +87,38 @@ - (NSData *)dataForKey:(NSString *)key return data; } -- (NSDictionary *)dictionaryForKey:(NSString *)key +- (nullable NSDictionary *)dictionaryForKey:(NSString *)key { return [self jsonForKey:key]; } -- (void)setDictionary:(NSDictionary *)dictionary forKey:(NSString *)key +- (void)setDictionary:(nullable NSDictionary *)dictionary forKey:(NSString *)key { [self setJSON:dictionary forKey:key]; } -- (NSArray *)arrayForKey:(NSString *)key +- (nullable NSArray *)arrayForKey:(NSString *)key { return [self jsonForKey:key]; } -- (void)setArray:(NSArray *)array forKey:(NSString *)key +- (void)setArray:(nullable NSArray *)array forKey:(NSString *)key { [self setJSON:array forKey:key]; } -- (NSString *)stringForKey:(NSString *)key +- (nullable NSString *)stringForKey:(NSString *)key { - // unlike plists, we can't have stray values, they need to be - // in a dictionary or array container. NSDictionary *data = [self jsonForKey:key]; - return data[key]; + if (data) { + return data[key]; + } + return nil; } -- (void)setString:(NSString *)string forKey:(NSString *)key +- (void)setString:(nullable NSString *)string forKey:(NSString *)key { - // unlike plists, we can't have stray values, they need to be - // in a dictionary or array container. - NSDictionary *data = @{key: string}; - [self setJSON:data forKey:key]; + [self setJSON:string forKey:key]; } @@ -148,31 +153,39 @@ - (id _Nullable)jsonForKey:(NSString *)key result = [self jsonFromData:data needsConversion:&needsConversion]; if (needsConversion) { [self setJSON:result forKey:key]; + // maybe a little repetitive, but we want to recreate the same path it would + // take if it weren't being converted. + data = [self dataForKey:key]; + result = [self jsonFromData:data needsConversion:&needsConversion]; } } return result; } -- (void)setJSON:(id _Nonnull)plist forKey:(NSString *)key +- (void)setJSON:(id _Nonnull)json forKey:(NSString *)key { NSDictionary *dict = nil; // json doesn't allow stand alone values like plist (previous storage format) does so // we need to massage it a little. - if ([plist isKindOfClass:[NSDictionary class]] || [plist isKindOfClass:[NSArray class]]) { - dict = plist; - } else { - dict = @{key: plist}; + if (json) { + if ([json isKindOfClass:[NSDictionary class]] || [json isKindOfClass:[NSArray class]]) { + dict = json; + } else { + dict = @{key: json}; + } } NSData *data = [self dataFromJSON:dict]; - if (data) { - [self setData:data forKey:key]; - } + [self setData:data forKey:key]; } - (NSData *_Nullable)dataFromJSON:(id)json { + if (json == nil) { + return nil; + } + NSError *error = nil; NSData *data = [NSJSONSerialization dataWithJSONObject:json options:0 error:&error]; if (error) { diff --git a/Analytics/Classes/Internal/SEGStorage.h b/Analytics/Classes/Internal/SEGStorage.h index 7ea2f1916..62a3005f9 100644 --- a/Analytics/Classes/Internal/SEGStorage.h +++ b/Analytics/Classes/Internal/SEGStorage.h @@ -15,16 +15,16 @@ - (void)removeKey:(NSString *_Nonnull)key; - (void)resetAll; -- (void)setData:(NSData *_Nonnull)data forKey:(NSString *_Nonnull)key; +- (void)setData:(NSData *_Nullable)data forKey:(NSString *_Nonnull)key; - (NSData *_Nullable)dataForKey:(NSString *_Nonnull)key; -- (void)setDictionary:(NSDictionary *_Nonnull)dictionary forKey:(NSString *_Nonnull)key; +- (void)setDictionary:(NSDictionary *_Nullable)dictionary forKey:(NSString *_Nonnull)key; - (NSDictionary *_Nullable)dictionaryForKey:(NSString *_Nonnull)key; -- (void)setArray:(NSArray *_Nonnull)array forKey:(NSString *_Nonnull)key; +- (void)setArray:(NSArray *_Nullable)array forKey:(NSString *_Nonnull)key; - (NSArray *_Nullable)arrayForKey:(NSString *_Nonnull)key; -- (void)setString:(NSString *_Nonnull)string forKey:(NSString *_Nonnull)key; +- (void)setString:(NSString *_Nullable)string forKey:(NSString *_Nonnull)key; - (NSString *_Nullable)stringForKey:(NSString *_Nonnull)key; // Number and Booleans are intentionally omitted at the moment because they are not needed diff --git a/Analytics/Classes/Internal/SEGUserDefaultsStorage.m b/Analytics/Classes/Internal/SEGUserDefaultsStorage.m index 3d1b6597c..444b4faa0 100644 --- a/Analytics/Classes/Internal/SEGUserDefaultsStorage.m +++ b/Analytics/Classes/Internal/SEGUserDefaultsStorage.m @@ -46,6 +46,16 @@ - (void)resetAll [self.defaults synchronize]; } +- (void)setObject:(id)object forKey:(NSString *)key +{ + // pass through for NSUserDefaults to remove keys if supplied a nil value. + if (object) { + [self.defaults setObject:object forKey:key]; + } else { + [self.defaults removeObjectForKey:key]; + } +} + - (void)setData:(NSData *)data forKey:(NSString *)key { key = [self namespacedKey:key]; @@ -54,7 +64,7 @@ - (void)setData:(NSData *)data forKey:(NSString *)key return; } NSData *encryptedData = [self.crypto encrypt:data]; - [self.defaults setObject:encryptedData forKey:key]; + [self setObject:encryptedData forKey:key]; } - (NSData *)dataForKey:(NSString *)key @@ -84,7 +94,7 @@ - (void)setDictionary:(NSDictionary *)dictionary forKey:(NSString *)key { if (!self.crypto) { key = [self namespacedKey:key]; - [self.defaults setObject:dictionary forKey:key]; + [self setObject:dictionary forKey:key]; return; } [self setPlist:dictionary forKey:key]; @@ -103,7 +113,7 @@ - (void)setArray:(NSArray *)array forKey:(NSString *)key { if (!self.crypto) { key = [self namespacedKey:key]; - [self.defaults setObject:array forKey:key]; + [self setObject:array forKey:key]; return; } [self setPlist:array forKey:key]; @@ -122,7 +132,7 @@ - (void)setString:(NSString *)string forKey:(NSString *)key { if (!self.crypto) { key = [self namespacedKey:key]; - [self.defaults setObject:string forKey:key]; + [self setObject:string forKey:key]; return; } [self setPlist:string forKey:key];