Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

All notable changes to the LaunchDarkly iOS SDK will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org).

## [2.13.9] - 2018-11-05
### Fixed
- Fixed defect causing a crash when unknown data exists in a feature flag cache.
- Renamed function parameters to avoid the use of Objective-C++ reserved words.

## [2.13.8] - 2018-10-23
### Fixed
- Fixed defect preventing feature flags cached prior to version 2.11.0 from restoring correctly and possibly crashing
Expand Down
2 changes: 1 addition & 1 deletion Darkly/DarklyConstants.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#import "DarklyConstants.h"

NSString * const kClientVersion = @"2.13.8";
NSString * const kClientVersion = @"2.13.9";
NSString * const kBaseUrl = @"https://app.launchdarkly.com";
NSString * const kEventsUrl = @"https://mobile.launchdarkly.com";
NSString * const kStreamUrl = @"https://clientstream.launchdarkly.com";
Expand Down
4 changes: 2 additions & 2 deletions Darkly/LDFlagConfig/LDFlagConfigModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
-(nullable id)flagValueForFlagKey:(nonnull NSString*)flagKey;
-(NSInteger)flagModelVersionForFlagKey:(nonnull NSString*)flagKey;

-(void)addOrReplaceFromDictionary:(nullable NSDictionary*)patch;
-(void)deleteFromDictionary:(nullable NSDictionary*)delete;
-(void)addOrReplaceFromDictionary:(nullable NSDictionary*)eventDictionary;
-(void)deleteFromDictionary:(nullable NSDictionary*)eventDictionary;

-(BOOL)isEqualToConfig:(nullable LDFlagConfigModel*)otherConfig;
-(BOOL)hasFeaturesEqualToDictionary:(nullable NSDictionary*)otherDictionary;
Expand Down
23 changes: 15 additions & 8 deletions Darkly/LDFlagConfig/LDFlagConfigModel.m
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,15 @@ -(NSDictionary*)dictionaryValueIncludeNulls:(BOOL)includeNulls {
NSMutableDictionary *flagConfigDictionaryValues = [NSMutableDictionary dictionaryWithCapacity:featuresJsonDictionary.count];
for (NSString *key in featuresJsonDictionary.allKeys) {
LDFlagConfigValue *flagConfigValue = featuresJsonDictionary[key];
if (!includeNulls && [flagConfigValue.value isKindOfClass:[NSNull class]]) { continue; }
flagConfigDictionaryValues[key] = [flagConfigValue dictionaryValue];
if (![flagConfigValue isKindOfClass:[LDFlagConfigValue class]]) {
DEBUG_LOG(@"LDFlagConfigModel dictionaryValueIncludeNulls: found an invalid value for key:%@. Skipping without putting the value into the dictionary.", key);
continue; //The value coming out of the featuresJsonDictionary is not a LDFlagConfigValue. Skip it.
}
if (!includeNulls && [flagConfigValue.value isKindOfClass:[NSNull class]]) {
continue;
}
NSDictionary *flagConfigValueDictionary = [flagConfigValue dictionaryValue];
flagConfigDictionaryValues[key] = flagConfigValueDictionary;
}
if (!includeNulls) {
[flagConfigDictionaryValues removeNullValues]; //Redact nulls out of values that are dictionaries
Expand Down Expand Up @@ -97,9 +104,9 @@ -(NSInteger)flagModelVersionForFlagKey:(NSString*)flagKey {
return featureValue.modelVersion;
}

-(void)addOrReplaceFromDictionary:(NSDictionary*)patch {
NSString *flagKey = patch[kLDFlagConfigModelKeyKey];
LDFlagConfigValue *patchedFlagConfigValue = [LDFlagConfigValue flagConfigValueWithObject:patch];
-(void)addOrReplaceFromDictionary:(NSDictionary*)eventDictionary {
NSString *flagKey = eventDictionary[kLDFlagConfigModelKeyKey];
LDFlagConfigValue *patchedFlagConfigValue = [LDFlagConfigValue flagConfigValueWithObject:eventDictionary];
if (![self shouldApplyPatch:patchedFlagConfigValue forFlagKey:flagKey]) { return; }

NSMutableDictionary *updatedFlagConfig = [NSMutableDictionary dictionaryWithDictionary:self.featuresJsonDictionary];
Expand All @@ -117,11 +124,11 @@ -(BOOL)shouldApplyPatch:(LDFlagConfigValue*)patchedFlagConfigValue forFlagKey:(N
return patchedFlagConfigValue.modelVersion > [self flagModelVersionForFlagKey:flagKey];
}

-(void)deleteFromDictionary:(NSDictionary*)delete {
NSString *flagKey = delete[kLDFlagConfigModelKeyKey];
-(void)deleteFromDictionary:(NSDictionary*)eventDictionary {
NSString *flagKey = eventDictionary[kLDFlagConfigModelKeyKey];
if (flagKey.length == 0) { return; }

id flagVersionObject = delete[kLDFlagConfigValueKeyVersion];
id flagVersionObject = eventDictionary[kLDFlagConfigValueKeyVersion];
if (!flagVersionObject || ![flagVersionObject isKindOfClass:[NSNumber class]]) { return; }
NSInteger flagVersion = [(NSNumber*)flagVersionObject integerValue];
if ([self doesFlagConfigValueExistForFlagKey:flagKey] && flagVersion <= [self flagModelVersionForFlagKey:flagKey]) { return; }
Expand Down
6 changes: 6 additions & 0 deletions DarklyTests/Fixtures/featureFlags-excludeNulls.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,11 @@
"variation": 2,
"version": 2,
"flagVersion": 1
},
"isADouble": {
"value": 2.71828,
"variation": 2,
"version": 2,
"flagVersion": 1
}
}
36 changes: 24 additions & 12 deletions DarklyTests/Models/LDFlagConfig/LDFlagConfigModelTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,25 @@ -(void)testInitWithDictionary {
}
}

-(void)testInitWithDictionary_nonConfigValues {
LDFlagConfigModel *targetFlagConfigModel = [LDFlagConfigModel flagConfigFromJsonFileNamed:@"featureFlags"];
LDFlagConfigModel *flagConfigModel = [LDFlagConfigModel flagConfigWithOnlyFlagValuesFromJsonFileNamed:@"featureFlags"];

LDFlagConfigModel *restoredFlagConfigModel = [[LDFlagConfigModel alloc] initWithDictionary:flagConfigModel.featuresJsonDictionary];

XCTAssertEqualObjects([NSSet setWithArray:restoredFlagConfigModel.featuresJsonDictionary.allKeys], [NSSet setWithArray:targetFlagConfigModel.featuresJsonDictionary.allKeys]);
for (NSString *flagKey in targetFlagConfigModel.featuresJsonDictionary.allKeys) {
LDFlagConfigValue *targetFlagConfigValue = [targetFlagConfigModel flagConfigValueForFlagKey:flagKey];
LDFlagConfigValue *flagConfigValue = [restoredFlagConfigModel flagConfigValueForFlagKey:flagKey];

XCTAssertEqualObjects(flagConfigValue.value, targetFlagConfigValue.value);
XCTAssertEqual(flagConfigValue.variation, kLDFlagConfigValueItemDoesNotExist);
XCTAssertNil(flagConfigValue.flagVersion);
XCTAssertEqual(flagConfigValue.modelVersion, kLDFlagConfigValueItemDoesNotExist);
XCTAssertNil(flagConfigValue.eventTrackingContext);
}
}

-(void)testDictionaryValue_includeNullValues {
LDFlagConfigModel *subject = [LDFlagConfigModel flagConfigFromJsonFileNamed:@"featureFlags"];

Expand All @@ -69,22 +88,15 @@ -(void)testDictionaryValue_excludeNullValues {
}

-(void)testDictionaryValue_nonConfigValues {
LDFlagConfigModel *targetFlagConfigModel = [LDFlagConfigModel flagConfigFromJsonFileNamed:@"featureFlags"];
LDFlagConfigModel *flagConfigModel = [LDFlagConfigModel flagConfigWithOnlyFlagValuesFromJsonFileNamed:@"featureFlags"];

LDFlagConfigModel *restoredFlagConfigModel = [[LDFlagConfigModel alloc] initWithDictionary:flagConfigModel.featuresJsonDictionary];
NSDictionary *flagConfigModelDictionary = [flagConfigModel dictionaryValueIncludeNulls:NO];

XCTAssertEqualObjects([NSSet setWithArray:restoredFlagConfigModel.featuresJsonDictionary.allKeys], [NSSet setWithArray:targetFlagConfigModel.featuresJsonDictionary.allKeys]);
for (NSString *flagKey in targetFlagConfigModel.featuresJsonDictionary.allKeys) {
LDFlagConfigValue *targetFlagConfigValue = [targetFlagConfigModel flagConfigValueForFlagKey:flagKey];
LDFlagConfigValue *flagConfigValue = [restoredFlagConfigModel flagConfigValueForFlagKey:flagKey];

XCTAssertEqualObjects(flagConfigValue.value, targetFlagConfigValue.value);
XCTAssertEqual(flagConfigValue.variation, kLDFlagConfigValueItemDoesNotExist);
XCTAssertNil(flagConfigValue.flagVersion);
XCTAssertEqual(flagConfigValue.modelVersion, kLDFlagConfigValueItemDoesNotExist);
XCTAssertNil(flagConfigValue.eventTrackingContext);
XCTAssertNotNil(flagConfigModelDictionary);
if (flagConfigModelDictionary == nil) {
return;
}
XCTAssertTrue(flagConfigModelDictionary.count == 0);
}

-(void)testFlagConfigValueForFlagKey {
Expand Down
4 changes: 2 additions & 2 deletions LaunchDarkly.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = "LaunchDarkly"
s.version = "2.13.8"
s.version = "2.13.9"
s.summary = "iOS SDK for LaunchDarkly"

s.description = <<-DESC
Expand All @@ -23,7 +23,7 @@ Pod::Spec.new do |s|
s.tvos.deployment_target = "9.0"
s.osx.deployment_target = '10.10'

s.source = { :git => "https://github.com/launchdarkly/ios-client.git", :tag => "2.13.8" }
s.source = { :git => "https://github.com/launchdarkly/ios-client.git", :tag => "2.13.9" }

s.source_files = 'Darkly/**/*.{h,m}'

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ $ brew install carthage
To integrate LaunchDarkly into your Xcode project using Carthage, specify it in your `Cartfile`:

```ogdl
github "launchdarkly/ios-client" "2.13.8"
github "launchdarkly/ios-client" "2.13.9"
```

Run `carthage` to build the framework and drag the built `Darkly.framework` into your Xcode project.
Expand All @@ -61,7 +61,7 @@ Quick setup

1. Add the SDK to your `Podfile`:

pod 'LaunchDarkly', '2.13.8'
pod 'LaunchDarkly', '2.13.9'

2. Import the LaunchDarkly client:

Expand Down