TNLCLI/TNLMutableRequestConfiguration+TNLCLI.m (117 lines of code) (raw):
//
// TNLMutableRequestConfiguration+TNLCLI.m
// tnlcli
//
// Created on 9/17/19.
// Copyright © 2020 Twitter. All rights reserved.
//
#import <TwitterNetworkLayer/TwitterNetworkLayer.h>
#import "TNLCLIError.h"
#import "TNLCLIPrint.h"
#import "TNLCLIUtils.h"
#import "TNLMutableRequestConfiguration+TNLCLI.h"
@implementation TNLMutableRequestConfiguration (TNLCLI)
+ (instancetype)tnlcli_configurationWithFile:(NSString *)filePath error:(NSError * _Nullable __autoreleasing *)errorOut
{
@autoreleasepool {
NSError *error;
NSDictionary<NSString *, NSString *> *d;
NSData *jsonData = [NSData dataWithContentsOfFile:filePath
options:0
error:&error];
if (jsonData) {
d = [NSJSONSerialization JSONObjectWithData:jsonData
options:0
error:&error];
if (d) {
if ([d isKindOfClass:[NSDictionary class]]) {
if (d.count) {
__block BOOL allStrings = YES;
[d enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) {
if (![key isKindOfClass:[NSString class]] || ![obj isKindOfClass:[NSString class]]) {
allStrings = NO;
*stop = YES;
}
}];
if (!allStrings) {
d = nil;
}
}
} else {
d = nil;
}
}
}
if (!error && !d) {
error = TNLCLICreateError(TNLCLIErrorInvalidRequestConfigurationFileFormat, @{ @"file" : filePath });
}
if (errorOut) {
*errorOut = error;
}
if (error) {
return nil;
}
return [self tnlcli_configurationWithDictionary:d];
}
}
+ (instancetype)tnlcli_configurationWithDictionary:(NSDictionary<NSString *,NSString *> *)d
{
TNLMutableRequestConfiguration *config = [[self alloc] init];
[d enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) {
(void)[config tnlcli_applySettingWithName:key value:obj];
}];
return config;
}
- (BOOL)tnlcli_applySettingWithName:(NSString *)name value:(NSString *)value
{
#define BOOL_SETTING(setting) \
do { \
if ([name isEqualToString: @"" #setting ]) { \
NSNumber *number = TNLCLIBoolNumberValueFromString(value); \
if (number) { \
self. setting = number.boolValue; \
return YES; \
} \
TNLCLIPrintWarning([NSString stringWithFormat:@"'%@' should be an BOOL for a `TNLRequestConfiguration`, but '%@' was provided", name, value]); \
return NO; \
} \
} while (0)
#define NUMBER_SETTING(setting, accessor) \
do { \
if ([name isEqualToString: @"" #setting ]) { \
NSNumber *number = TNLCLINumberValueFromString(value); \
if (number) { \
self. setting = [number accessor##Value]; \
return YES; \
} \
TNLCLIPrintWarning([NSString stringWithFormat:@"'%@' should be a " #accessor " for `TNLRequestConfiguration`, but '%@' was provided", name, value]); \
return NO; \
} \
} while (0)
#define STRING_SETTING(setting) \
do { \
if ([name isEqualToString: @"" #setting ]) { \
self. setting = value; \
return YES; \
} \
} while (0)
/// BOOL settings
BOOL_SETTING(contributeToExecutingNetworkConnectionsCount);
BOOL_SETTING(skipHostSanitization);
BOOL_SETTING(shouldSetCookies);
BOOL_SETTING(allowsCellularAccess);
BOOL_SETTING(discretionary);
BOOL_SETTING(shouldUseExtendedBackgroundIdleMode);
BOOL_SETTING(shouldLaunchAppForBackgroundEvents);
/// Double settings
NUMBER_SETTING(idleTimeout, double);
NUMBER_SETTING(attemptTimeout, double);
NUMBER_SETTING(operationTimeout, double);
NUMBER_SETTING(deferrableInterval, double);
/// Integer settings
NUMBER_SETTING(executionMode, integer);
NUMBER_SETTING(redirectPolicy, integer);
NUMBER_SETTING(responseDataConsumptionMode, integer);
NUMBER_SETTING(protocolOptions, integer);
NUMBER_SETTING(connectivityOptions, integer);
NUMBER_SETTING(responseComputeHashAlgorithm, integer);
// NUMBER_SETTING(multipathServiceType, integer); -- unavailable on Mac
/// Unsigned Integer settings
NUMBER_SETTING(cachePolicy, unsignedInteger);
NUMBER_SETTING(cookieAcceptPolicy, unsignedInteger);
NUMBER_SETTING(networkServiceType, unsignedInteger);
/// String settings
STRING_SETTING(sharedContainerIdentifier);
/// Unsupported from key-value-pair settings (aka TODO)
// @property id<TNLRequestRetryPolicyProvider> retryPolicyProvider;
// @property id<TNLContentEncoder> contentEncoder;
// @property NSArray<id<TNLContentDecoder>> *additionalContentDecoders;
// @property NSURLCredentialStorage *URLCredentialStorage;
// @property NSURLCache *URLCache;
// @property NSHTTPCookieStorage *cookieStorage;
return NO;
#undef BOOL_SETTING
#undef NUMBER_SETTING
#undef STRING_SETTING
}
@end