Skip to content

Commit 6ff2290

Browse files
fix(nullattributes): Accepting null attributes and eventTags (#335)
* null support for attributes & eventTags Notification Center PR. * Nullable attribute and eventTags activate listener and track listener * Generic listener and sendNotifications should have NSDictionary. * Addressed Code Review comments. * Minor conflicts resolved. * Addressed code review comments. * adding xcpretty * Notification Center issues fixed. * removed xcpretty * supress warnings.
1 parent 6f7b652 commit 6ff2290

13 files changed

+369
-136
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ before_install:
1515
- gem install slather --no-rdoc --no-ri --no-document --quiet
1616
script:
1717
- pod spec lint --quick
18-
- if [[ "$TRAVIS_BRANCH" == "master" ]]; then xcodebuild test -quiet -workspace OptimizelySDK.xcworkspace -scheme $SCHEME -configuration Release CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -sdk $TEST_SDK -destination "platform=$PLATFORM,OS=$OS,name=$NAME" ONLY_ACTIVE_ARCH=YES | egrep -B 10 -A 10 "(error|warning|failed|crash|exit|FAILED|Failing|failures)"; fi
18+
- if [[ "$TRAVIS_BRANCH" == "master" ]]; then xcodebuild test -quiet -workspace OptimizelySDK.xcworkspace -scheme $SCHEME -configuration Release CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -sdk $TEST_SDK -destination "platform=$PLATFORM,OS=$OS,name=$NAME" ONLY_ACTIVE_ARCH=YES | egrep -B 10 -A 10 "(error|failed|crash|exit|FAILED|Failing|failures)"; fi
1919
after_success:
2020
- slather
2121
- sleep 5 # https://github.com/travis-ci/travis-ci/issues/4725

OptimizelySDKCore/OptimizelySDKCore.xcodeproj/project.pbxproj

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@
225225
90855D0120ED254600A97BEC /* OPTLYControlAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 90855CFC20ED237F00A97BEC /* OPTLYControlAttributes.h */; settings = {ATTRIBUTES = (Public, ); }; };
226226
90855D0D20ED2E0100A97BEC /* OPTLYControlAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 90855D0420ED2B0200A97BEC /* OPTLYControlAttributes.m */; };
227227
90855D0E20ED2E0300A97BEC /* OPTLYControlAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 90855D0420ED2B0200A97BEC /* OPTLYControlAttributes.m */; };
228+
C77958C3219BFBC300B4CA89 /* OPTLYNSObject+Validation.h in Headers */ = {isa = PBXBuildFile; fileRef = C77958C0219BFBA000B4CA89 /* OPTLYNSObject+Validation.h */; };
229+
C77958C4219BFBC400B4CA89 /* OPTLYNSObject+Validation.h in Headers */ = {isa = PBXBuildFile; fileRef = C77958C0219BFBA000B4CA89 /* OPTLYNSObject+Validation.h */; };
230+
C77958C5219BFBC700B4CA89 /* OPTLYNSObject+Validation.m in Sources */ = {isa = PBXBuildFile; fileRef = C77958C1219BFBA000B4CA89 /* OPTLYNSObject+Validation.m */; };
231+
C77958C6219BFBC800B4CA89 /* OPTLYNSObject+Validation.m in Sources */ = {isa = PBXBuildFile; fileRef = C77958C1219BFBA000B4CA89 /* OPTLYNSObject+Validation.m */; };
228232
EA064BC71DD3FC8800DF7537 /* OPTLYQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = EA064BC51DD3FC8800DF7537 /* OPTLYQueue.h */; settings = {ATTRIBUTES = (Public, ); }; };
229233
EA064BC81DD3FC8800DF7537 /* OPTLYQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = EA064BC51DD3FC8800DF7537 /* OPTLYQueue.h */; settings = {ATTRIBUTES = (Public, ); }; };
230234
EA064BC91DD3FC8800DF7537 /* OPTLYQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = EA064BC61DD3FC8800DF7537 /* OPTLYQueue.m */; };
@@ -629,6 +633,8 @@
629633
A52039FD7B704890859320C4 /* Pods-OptimizelySDKCoreiOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OptimizelySDKCoreiOSTests.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-OptimizelySDKCoreiOSTests/Pods-OptimizelySDKCoreiOSTests.debug.xcconfig"; sourceTree = "<group>"; };
630634
B333468714C0D4A8633103EF /* Pods-OptimizelySDKCoreiOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OptimizelySDKCoreiOSTests.release.xcconfig"; path = "../Pods/Target Support Files/Pods-OptimizelySDKCoreiOSTests/Pods-OptimizelySDKCoreiOSTests.release.xcconfig"; sourceTree = "<group>"; };
631635
BE0C3BD9DC6186DB98A667C2 /* Pods_OptimizelySDKCoreTVOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OptimizelySDKCoreTVOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
636+
C77958C0219BFBA000B4CA89 /* OPTLYNSObject+Validation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OPTLYNSObject+Validation.h"; sourceTree = "<group>"; };
637+
C77958C1219BFBA000B4CA89 /* OPTLYNSObject+Validation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "OPTLYNSObject+Validation.m"; sourceTree = "<group>"; };
632638
E2E7211C032DF7A75264FDDB /* Pods-OptimizelySDKCoreTVOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OptimizelySDKCoreTVOSTests.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-OptimizelySDKCoreTVOSTests/Pods-OptimizelySDKCoreTVOSTests.debug.xcconfig"; sourceTree = "<group>"; };
633639
EA064BC51DD3FC8800DF7537 /* OPTLYQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OPTLYQueue.h; sourceTree = "<group>"; };
634640
EA064BC61DD3FC8800DF7537 /* OPTLYQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OPTLYQueue.m; sourceTree = "<group>"; };
@@ -1003,6 +1009,15 @@
10031009
name = Pods;
10041010
sourceTree = "<group>";
10051011
};
1012+
C77958BF219BFADE00B4CA89 /* Categories */ = {
1013+
isa = PBXGroup;
1014+
children = (
1015+
C77958C0219BFBA000B4CA89 /* OPTLYNSObject+Validation.h */,
1016+
C77958C1219BFBA000B4CA89 /* OPTLYNSObject+Validation.m */,
1017+
);
1018+
name = Categories;
1019+
sourceTree = "<group>";
1020+
};
10061021
EA2FA83D1DC5E0E900B1D81B /* Utilities */ = {
10071022
isa = PBXGroup;
10081023
children = (
@@ -1216,6 +1231,7 @@
12161231
EA2FAA4A1DC6F53E00B1D81B /* Optimizely.m */,
12171232
EA2FA83F1DC5E11F00B1D81B /* Bucketer */,
12181233
EA2FA90B1DC6F17400B1D81B /* Builder */,
1234+
C77958BF219BFADE00B4CA89 /* Categories */,
12191235
EA2FA8401DC5E13A00B1D81B /* Data Models */,
12201236
EA2FA8411DC5E14700B1D81B /* Error Handler */,
12211237
EA2FA8421DC5E15700B1D81B /* Event Builder */,
@@ -1348,6 +1364,7 @@
13481364
EA2FAAAC1DC6F57200B1D81B /* OPTLYEvent.h in Headers */,
13491365
EA2FAAD01DC6F57200B1D81B /* OPTLYEventFeature.h in Headers */,
13501366
EA2C24331DE7887C0063ADA0 /* OPTLYVariationVariable.h in Headers */,
1367+
C77958C3219BFBC300B4CA89 /* OPTLYNSObject+Validation.h in Headers */,
13511368
EA2FAABE1DC6F57200B1D81B /* OPTLYEventDecision.h in Headers */,
13521369
EA2FAAA61DC6F57200B1D81B /* OPTLYDecisionEventTicket.h in Headers */,
13531370
EA2FAAC41DC6F57200B1D81B /* OPTLYEventDecisionTicket.h in Headers */,
@@ -1413,6 +1430,7 @@
14131430
EA2FAAE91DC6F57200B1D81B /* OPTLYEventParameterKeys.h in Headers */,
14141431
EA2FAAFB1DC6F57200B1D81B /* OPTLYEventView.h in Headers */,
14151432
EA2C24341DE7887C0063ADA0 /* OPTLYVariationVariable.h in Headers */,
1433+
C77958C4219BFBC400B4CA89 /* OPTLYNSObject+Validation.h in Headers */,
14161434
EA2FAABF1DC6F57200B1D81B /* OPTLYEventDecision.h in Headers */,
14171435
EA2FAAD71DC6F57200B1D81B /* OPTLYEventHeader.h in Headers */,
14181436
EA2FAAD11DC6F57200B1D81B /* OPTLYEventFeature.h in Headers */,
@@ -1914,6 +1932,7 @@
19141932
EA2FAC0A1DC6FFC600B1D81B /* OPTLYAttribute.m in Sources */,
19151933
EA2FAC0B1DC6FFC600B1D81B /* OPTLYAudience.m in Sources */,
19161934
EA2FAC0C1DC6FFC600B1D81B /* OPTLYBaseCondition.m in Sources */,
1935+
C77958C5219BFBC700B4CA89 /* OPTLYNSObject+Validation.m in Sources */,
19171936
EA2FAC0D1DC6FFC600B1D81B /* OPTLYCondition.m in Sources */,
19181937
EA2FAC0E1DC6FFC600B1D81B /* OPTLYDatafileKeys.m in Sources */,
19191938
EA2FAC0F1DC6FFC600B1D81B /* OPTLYDecisionEventTicket.m in Sources */,
@@ -2005,6 +2024,7 @@
20052024
EA2FABE61DC6FFA100B1D81B /* OPTLYAudience.m in Sources */,
20062025
EA2FABE71DC6FFA100B1D81B /* OPTLYBaseCondition.m in Sources */,
20072026
EA2FABE81DC6FFA100B1D81B /* OPTLYCondition.m in Sources */,
2027+
C77958C6219BFBC800B4CA89 /* OPTLYNSObject+Validation.m in Sources */,
20082028
EA2FABE91DC6FFA100B1D81B /* OPTLYDatafileKeys.m in Sources */,
20092029
EA2FABEA1DC6FFA100B1D81B /* OPTLYDecisionEventTicket.m in Sources */,
20102030
EA2FABEB1DC6FFA100B1D81B /* OPTLYEvent.m in Sources */,

OptimizelySDKCore/OptimizelySDKCore/OPTLYDecisionService.m

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#import "OPTLYFeatureDecision.h"
3232
#import "OPTLYGroup.h"
3333
#import "OPTLYControlAttributes.h"
34+
#import "OPTLYNSObject+Validation.h"
3435

3536
@interface OPTLYDecisionService()
3637
@property (nonatomic, strong) OPTLYProjectConfig *config;
@@ -163,11 +164,14 @@ - (NSString *)getBucketingId:(NSString *)userId
163164
NSString *bucketingId = userId;
164165
// If the bucketing ID key is defined in attributes, then use that
165166
// in place of the userID for the murmur hash key
166-
if (![OPTLYDecisionService isEmptyString:attributes[OptimizelyBucketId]]) {
167-
bucketingId = attributes[OptimizelyBucketId];
168-
[self.config.logger logMessage:[NSString stringWithFormat:OPTLYLoggerMessagesDecisionServiceSettingTheBucketingID,
169-
bucketingId]
170-
withLevel:OptimizelyLogLevelDebug];
167+
if (attributes != nil) {
168+
NSString *validBucketingId = [attributes[OptimizelyBucketId] getValidString];
169+
if (validBucketingId != nil) {
170+
bucketingId = validBucketingId;
171+
[self.config.logger logMessage:[NSString stringWithFormat:OPTLYLoggerMessagesDecisionServiceSettingTheBucketingID,
172+
bucketingId]
173+
withLevel:OptimizelyLogLevelDebug];
174+
}
171175
}
172176
return bucketingId;
173177
}
@@ -194,7 +198,7 @@ - (OPTLYFeatureDecision *)getVariationForFeatureGroup:(OPTLYFeatureFlag *)featur
194198
OPTLYFeatureDecision *decision = nil;
195199
NSString *logMessage = nil;
196200

197-
if ([OPTLYDecisionService isEmptyString:groupId]) {
201+
if ([groupId getValidString] == nil) {
198202
logMessage = OPTLYLoggerMessagesDecisionServiceGroupIdNotFound;
199203
} else {
200204
NSString *bucketing_id = [self getBucketingId:userId attributes:attributes];
@@ -230,7 +234,7 @@ - (OPTLYFeatureDecision *)getVariationForFeatureExperiment:(OPTLYFeatureFlag *)f
230234
NSString *featureFlagKey = featureFlag.key;
231235
NSArray *experimentIds = featureFlag.experimentIds;
232236
// Check if there are any experiment IDs inside feature flag
233-
if ([OPTLYDecisionService isEmptyArray:experimentIds]) {
237+
if ([experimentIds getValidArray] == nil) {
234238
[self.config.logger logMessage:[NSString stringWithFormat:OPTLYLoggerMessagesDecisionServiceFFNotUsed, featureFlagKey]
235239
withLevel:OptimizelyLogLevelDebug];
236240
return nil;
@@ -266,7 +270,7 @@ - (OPTLYFeatureDecision *)getVariationForFeatureRollout:(OPTLYFeatureFlag *)feat
266270
NSString *bucketing_id = [self getBucketingId:userId attributes:attributes];
267271
NSString *featureFlagKey = featureFlag.key;
268272
NSString *rolloutId = featureFlag.rolloutId;
269-
if ([OPTLYDecisionService isEmptyString:rolloutId]) {
273+
if ([rolloutId getValidString] == nil) {
270274
[self.config.logger logMessage:[NSString stringWithFormat:OPTLYLoggerMessagesDecisionServiceFFNotUsed, featureFlagKey]
271275
withLevel:OptimizelyLogLevelDebug];
272276
return nil;
@@ -277,7 +281,7 @@ - (OPTLYFeatureDecision *)getVariationForFeatureRollout:(OPTLYFeatureFlag *)feat
277281
return nil;
278282
}
279283
NSArray *rolloutRules = rollout.experiments;
280-
if ([OPTLYDecisionService isEmptyArray:rolloutRules]) {
284+
if ([rolloutRules getValidArray] == nil) {
281285
return nil;
282286
}
283287
// Evaluate all rollout rules except for last one
@@ -500,17 +504,4 @@ - (BOOL)isUserInExperiment:(OPTLYProjectConfig *)config
500504

501505
return false;
502506
}
503-
504-
+ (BOOL)isEmptyString:(NSObject*)string {
505-
return (!string
506-
|| ![string isKindOfClass:[NSString class]]
507-
|| [(NSString *)string isEqualToString:@""]);
508-
}
509-
510-
511-
+ (BOOL)isEmptyArray:(NSObject*)array {
512-
return (!array
513-
|| ![array isKindOfClass:[NSArray class]]
514-
|| (((NSArray *)array).count == 0));
515-
}
516507
@end

OptimizelySDKCore/OptimizelySDKCore/OPTLYEventBuilder.m

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#import "OPTLYLogger.h"
2626
#import "OPTLYProjectConfig.h"
2727
#import "OPTLYVariation.h"
28+
#import "OPTLYNSObject+Validation.h"
2829

2930
NSString * const OptimizelyActivateEventKey = @"campaign_activated";
3031

@@ -92,15 +93,15 @@ - (NSDictionary *)createCommonParamsForUser:(NSString *)userId
9293

9394
NSMutableDictionary *visitor = [NSMutableDictionary new];
9495
visitor[OPTLYEventParameterKeysSnapshots] = [NSMutableArray new];
95-
visitor[OPTLYEventParameterKeysVisitorId] = [OPTLYEventBuilderDefault stringOrEmpty:userId];
96+
visitor[OPTLYEventParameterKeysVisitorId] = [userId getStringOrEmpty];
9697
visitor[OPTLYEventParameterKeysAttributes] = [self createUserFeatures:self.config attributes:attributes];
9798

9899
commonParams[OPTLYEventParameterKeysVisitors] = @[visitor];
99-
commonParams[OPTLYEventParameterKeysProjectId] = [OPTLYEventBuilderDefault stringOrEmpty:self.config.projectId ];
100-
commonParams[OPTLYEventParameterKeysAccountId] = [OPTLYEventBuilderDefault stringOrEmpty:self.config.accountId];
101-
commonParams[OPTLYEventParameterKeysClientEngine] = [OPTLYEventBuilderDefault stringOrEmpty:[self.config clientEngine]];
102-
commonParams[OPTLYEventParameterKeysClientVersion] = [OPTLYEventBuilderDefault stringOrEmpty:[self.config clientVersion]];
103-
commonParams[OPTLYEventParameterKeysRevision] = [OPTLYEventBuilderDefault stringOrEmpty:self.config.revision];
100+
commonParams[OPTLYEventParameterKeysProjectId] = [self.config.projectId getStringOrEmpty];
101+
commonParams[OPTLYEventParameterKeysAccountId] = [self.config.accountId getStringOrEmpty];
102+
commonParams[OPTLYEventParameterKeysClientEngine] = [[self.config clientEngine] getStringOrEmpty];
103+
commonParams[OPTLYEventParameterKeysClientVersion] = [[self.config clientVersion] getStringOrEmpty];
104+
commonParams[OPTLYEventParameterKeysRevision] = [self.config.revision getStringOrEmpty];
104105
commonParams[OPTLYEventParameterKeysAnonymizeIP] = @(self.config.anonymizeIP.boolValue);
105106

106107
return [commonParams copy];
@@ -111,13 +112,13 @@ - (NSDictionary *)createImpressionParamsOfExperiment:(OPTLYExperiment *)experime
111112
NSMutableDictionary *snapshot = [NSMutableDictionary new];
112113

113114
NSMutableDictionary *decision = [NSMutableDictionary new];
114-
decision[OPTLYEventParameterKeysDecisionCampaignId] = [OPTLYEventBuilderDefault stringOrEmpty:experiment.layerId];
115+
decision[OPTLYEventParameterKeysDecisionCampaignId] = [experiment.layerId getStringOrEmpty];
115116
decision[OPTLYEventParameterKeysDecisionExperimentId] = experiment.experimentId;
116117
decision[OPTLYEventParameterKeysDecisionVariationId] = variation.variationId;
117118
NSArray *decisions = @[decision];
118119

119120
NSMutableDictionary *event = [NSMutableDictionary new];
120-
event[OPTLYEventParameterKeysEntityId] = [OPTLYEventBuilderDefault stringOrEmpty:experiment.layerId];
121+
event[OPTLYEventParameterKeysEntityId] = [experiment.layerId getStringOrEmpty];
121122
event[OPTLYEventParameterKeysTimestamp] = [self time] ? : @0;
122123
event[OPTLYEventParameterKeysKey] = OptimizelyActivateEventKey;
123124
event[OPTLYEventParameterKeysUUID] = [[NSUUID UUID] UUIDString];
@@ -149,7 +150,7 @@ - (NSArray *)createConversionParamsOfEvent:(OPTLYEvent *)event
149150
NSMutableDictionary *snapshot = [NSMutableDictionary new];
150151

151152
NSMutableDictionary *eventDict = [NSMutableDictionary new];
152-
eventDict[OPTLYEventParameterKeysEntityId] = [OPTLYEventBuilderDefault stringOrEmpty:event.eventId];
153+
eventDict[OPTLYEventParameterKeysEntityId] = [event.eventId getStringOrEmpty];
153154
eventDict[OPTLYEventParameterKeysTimestamp] = [self time] ? : @0;
154155
eventDict[OPTLYEventParameterKeysKey] = event.eventKey;
155156
eventDict[OPTLYEventParameterKeysUUID] = [[NSUUID UUID] UUIDString];
@@ -213,7 +214,7 @@ - (NSArray *)createUserFeatures:(OPTLYProjectConfig *)config
213214
continue;
214215
}
215216
NSString *attributeId = [config getAttributeIdForKey:attributeKey];
216-
if ([OPTLYEventBuilderDefault isEmptyString:attributeId]) {
217+
if ([attributeId getValidString] == nil) {
217218
NSString *logMessage = [NSString stringWithFormat:OPTLYLoggerMessagesAttributeInvalidFormat, attributeKey];
218219
[config.logger logMessage:logMessage withLevel:OptimizelyLogLevelDebug];
219220
continue;
@@ -247,17 +248,6 @@ - (NSNumber *)time
247248
return timestamp;
248249
}
249250

250-
+ (NSString *)stringOrEmpty:(NSString *)str {
251-
NSString *string = str != nil ? str : @"";
252-
return string;
253-
}
254-
255-
+ (BOOL)isEmptyString:(NSObject *)str {
256-
return (!str
257-
|| ![str isKindOfClass:[NSString class]]
258-
|| [(NSString *)str isEqualToString:@""]);
259-
}
260-
261251
+ (BOOL)isValidAttributeValue:(NSObject *)value {
262252
// check value is NSObject
263253
if (!value || [value isEqual:[NSNull null]]) {

OptimizelySDKCore/OptimizelySDKCore/OPTLYFeatureFlag.m

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2017, Optimizely, Inc. and contributors *
2+
* Copyright 2018, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *
@@ -19,6 +19,7 @@
1919
#import "OPTLYProjectConfig.h"
2020
#import "OPTLYExperiment.h"
2121
#import "OPTLYFeatureVariable.h"
22+
#import "OPTLYNSObject+Validation.h"
2223

2324
@interface OPTLYFeatureFlag()
2425

@@ -40,7 +41,7 @@ + (OPTLYJSONKeyMapper*)keyMapper
4041
}
4142

4243
- (BOOL)isValid:(OPTLYProjectConfig *)config {
43-
if ([OPTLYFeatureFlag isEmptyArray:self.experimentIds]) {
44+
if ([self.experimentIds getValidArray] == nil) {
4445
return true;
4546
}
4647
if (self.experimentIds.count == 1) {
@@ -80,10 +81,4 @@ - (OPTLYFeatureVariable *)getFeatureVariableForKey:(NSString *)variableKey {
8081
return [NSDictionary dictionaryWithDictionary:map];
8182
}
8283

83-
+ (BOOL)isEmptyArray:(NSObject*)array {
84-
return (!array
85-
|| ![array isKindOfClass:[NSArray class]]
86-
|| (((NSArray *)array).count == 0));
87-
}
88-
8984
@end
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/****************************************************************************
2+
* Copyright 2018, Optimizely, Inc. and contributors *
3+
* *
4+
* Licensed under the Apache License, Version 2.0 (the "License"); *
5+
* you may not use this file except in compliance with the License. *
6+
* You may obtain a copy of the License at *
7+
* *
8+
* http://www.apache.org/licenses/LICENSE-2.0 *
9+
* *
10+
* Unless required by applicable law or agreed to in writing, software *
11+
* distributed under the License is distributed on an "AS IS" BASIS, *
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
13+
* See the License for the specific language governing permissions and *
14+
* limitations under the License. *
15+
***************************************************************************/
16+
17+
#import <Foundation/Foundation.h>
18+
19+
NS_ASSUME_NONNULL_BEGIN
20+
21+
@interface NSObject (Validation)
22+
23+
/**
24+
* Determines if object is a valid non-empty string type.
25+
*
26+
* @returns A NSString if object is valid string type, else return nil.
27+
**/
28+
- (nullable NSString *)getValidString;
29+
30+
/**
31+
* Determines if object is a valid non-empty array type.
32+
*
33+
* @returns A NSArray if object is valid array type, else return nil.
34+
**/
35+
- (nullable NSArray *)getValidArray;
36+
37+
/**
38+
* Determines if object is a valid non-empty dictionary type.
39+
*
40+
* @returns A NSDictionary if object is valid dictionary type, else return nil.
41+
**/
42+
- (nullable NSDictionary *)getValidDictionary;
43+
44+
/**
45+
* Returns a string value for the object
46+
*
47+
* @returns A NSString if object is valid string type, else return empty string.
48+
**/
49+
- (NSString *)getStringOrEmpty;
50+
51+
@end
52+
53+
NS_ASSUME_NONNULL_END

0 commit comments

Comments
 (0)