├── .gitignore ├── Example ├── TransformerKit Example.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── main.m ├── Framework ├── Info.plist └── module.modulemap ├── LICENSE.md ├── README.md ├── Sources ├── NSValueTransformer+TransformerKit.h ├── NSValueTransformer+TransformerKit.m ├── NSValueTransformerName.h ├── TTTCryptographyTransformers.h ├── TTTCryptographyTransformers.m ├── TTTDataTransformers.h ├── TTTDataTransformers.m ├── TTTDateTransformers.h ├── TTTDateTransformers.m ├── TTTImageTransformers.h ├── TTTImageTransformers.m ├── TTTJSONTransformer.h ├── TTTJSONTransformer.m ├── TTTStringTransformers.h ├── TTTStringTransformers.m └── TransformerKit.h ├── TransformerKit.playground ├── Contents.swift └── contents.xcplayground ├── TransformerKit.podspec ├── TransformerKit.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ ├── TransformerKit iOS.xcscheme │ └── TransformerKit macOS.xcscheme └── TransformerKit.xcworkspace ├── contents.xcworkspacedata └── xcshareddata └── IDEWorkspaceChecks.plist /.gitignore: -------------------------------------------------------------------------------- 1 | xcuserdata 2 | *.xccheckout 3 | *.xcuserstate 4 | /Carthage 5 | -------------------------------------------------------------------------------- /Example/TransformerKit Example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | F872E1522176D21300B0FF99 /* TransformerKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F872E1512176D21300B0FF99 /* TransformerKit.framework */; }; 11 | F872E1542176D21900B0FF99 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F872E1532176D21900B0FF99 /* Foundation.framework */; }; 12 | F8E344E02176D16400264D73 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F8E344DF2176D16400264D73 /* main.m */; }; 13 | /* End PBXBuildFile section */ 14 | 15 | /* Begin PBXCopyFilesBuildPhase section */ 16 | F8E344DA2176D16400264D73 /* CopyFiles */ = { 17 | isa = PBXCopyFilesBuildPhase; 18 | buildActionMask = 2147483647; 19 | dstPath = /usr/share/man/man1/; 20 | dstSubfolderSpec = 0; 21 | files = ( 22 | ); 23 | runOnlyForDeploymentPostprocessing = 1; 24 | }; 25 | /* End PBXCopyFilesBuildPhase section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | F872E1512176D21300B0FF99 /* TransformerKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TransformerKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | F872E1532176D21900B0FF99 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 30 | F8E344DC2176D16400264D73 /* TransformerKit Example */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "TransformerKit Example"; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | F8E344DF2176D16400264D73 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 32 | /* End PBXFileReference section */ 33 | 34 | /* Begin PBXFrameworksBuildPhase section */ 35 | F8E344D92176D16400264D73 /* Frameworks */ = { 36 | isa = PBXFrameworksBuildPhase; 37 | buildActionMask = 2147483647; 38 | files = ( 39 | F872E1542176D21900B0FF99 /* Foundation.framework in Frameworks */, 40 | F872E1522176D21300B0FF99 /* TransformerKit.framework in Frameworks */, 41 | ); 42 | runOnlyForDeploymentPostprocessing = 0; 43 | }; 44 | /* End PBXFrameworksBuildPhase section */ 45 | 46 | /* Begin PBXGroup section */ 47 | F872E1502176D21300B0FF99 /* Frameworks */ = { 48 | isa = PBXGroup; 49 | children = ( 50 | F872E1532176D21900B0FF99 /* Foundation.framework */, 51 | F872E1512176D21300B0FF99 /* TransformerKit.framework */, 52 | ); 53 | name = Frameworks; 54 | sourceTree = ""; 55 | }; 56 | F8E344D32176D16400264D73 = { 57 | isa = PBXGroup; 58 | children = ( 59 | F8E344DE2176D16400264D73 /* Sources */, 60 | F8E344DD2176D16400264D73 /* Products */, 61 | F872E1502176D21300B0FF99 /* Frameworks */, 62 | ); 63 | sourceTree = ""; 64 | }; 65 | F8E344DD2176D16400264D73 /* Products */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | F8E344DC2176D16400264D73 /* TransformerKit Example */, 69 | ); 70 | name = Products; 71 | sourceTree = ""; 72 | }; 73 | F8E344DE2176D16400264D73 /* Sources */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | F8E344DF2176D16400264D73 /* main.m */, 77 | ); 78 | name = Sources; 79 | sourceTree = ""; 80 | }; 81 | /* End PBXGroup section */ 82 | 83 | /* Begin PBXNativeTarget section */ 84 | F8E344DB2176D16400264D73 /* TransformerKit Example */ = { 85 | isa = PBXNativeTarget; 86 | buildConfigurationList = F8E344E32176D16400264D73 /* Build configuration list for PBXNativeTarget "TransformerKit Example" */; 87 | buildPhases = ( 88 | F8E344D82176D16400264D73 /* Sources */, 89 | F8E344D92176D16400264D73 /* Frameworks */, 90 | F8E344DA2176D16400264D73 /* CopyFiles */, 91 | ); 92 | buildRules = ( 93 | ); 94 | dependencies = ( 95 | ); 96 | name = "TransformerKit Example"; 97 | productName = "TransformerKit Example"; 98 | productReference = F8E344DC2176D16400264D73 /* TransformerKit Example */; 99 | productType = "com.apple.product-type.tool"; 100 | }; 101 | /* End PBXNativeTarget section */ 102 | 103 | /* Begin PBXProject section */ 104 | F8E344D42176D16400264D73 /* Project object */ = { 105 | isa = PBXProject; 106 | attributes = { 107 | LastUpgradeCheck = 1140; 108 | ORGANIZATIONNAME = Mattt; 109 | TargetAttributes = { 110 | F8E344DB2176D16400264D73 = { 111 | CreatedOnToolsVersion = 10.1; 112 | }; 113 | }; 114 | }; 115 | buildConfigurationList = F8E344D72176D16400264D73 /* Build configuration list for PBXProject "TransformerKit Example" */; 116 | compatibilityVersion = "Xcode 9.3"; 117 | developmentRegion = en; 118 | hasScannedForEncodings = 0; 119 | knownRegions = ( 120 | en, 121 | Base, 122 | ); 123 | mainGroup = F8E344D32176D16400264D73; 124 | productRefGroup = F8E344DD2176D16400264D73 /* Products */; 125 | projectDirPath = ""; 126 | projectRoot = ""; 127 | targets = ( 128 | F8E344DB2176D16400264D73 /* TransformerKit Example */, 129 | ); 130 | }; 131 | /* End PBXProject section */ 132 | 133 | /* Begin PBXSourcesBuildPhase section */ 134 | F8E344D82176D16400264D73 /* Sources */ = { 135 | isa = PBXSourcesBuildPhase; 136 | buildActionMask = 2147483647; 137 | files = ( 138 | F8E344E02176D16400264D73 /* main.m in Sources */, 139 | ); 140 | runOnlyForDeploymentPostprocessing = 0; 141 | }; 142 | /* End PBXSourcesBuildPhase section */ 143 | 144 | /* Begin XCBuildConfiguration section */ 145 | F8E344E12176D16400264D73 /* Debug */ = { 146 | isa = XCBuildConfiguration; 147 | buildSettings = { 148 | ALWAYS_SEARCH_USER_PATHS = NO; 149 | CLANG_ANALYZER_NONNULL = YES; 150 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 151 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 152 | CLANG_CXX_LIBRARY = "libc++"; 153 | CLANG_ENABLE_MODULES = YES; 154 | CLANG_ENABLE_OBJC_ARC = YES; 155 | CLANG_ENABLE_OBJC_WEAK = YES; 156 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 157 | CLANG_WARN_BOOL_CONVERSION = YES; 158 | CLANG_WARN_COMMA = YES; 159 | CLANG_WARN_CONSTANT_CONVERSION = YES; 160 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 161 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 162 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 163 | CLANG_WARN_EMPTY_BODY = YES; 164 | CLANG_WARN_ENUM_CONVERSION = YES; 165 | CLANG_WARN_INFINITE_RECURSION = YES; 166 | CLANG_WARN_INT_CONVERSION = YES; 167 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 168 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 169 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 170 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 171 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 172 | CLANG_WARN_STRICT_PROTOTYPES = YES; 173 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 174 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 175 | CLANG_WARN_UNREACHABLE_CODE = YES; 176 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 177 | CODE_SIGN_IDENTITY = "-"; 178 | COPY_PHASE_STRIP = NO; 179 | DEBUG_INFORMATION_FORMAT = dwarf; 180 | ENABLE_STRICT_OBJC_MSGSEND = YES; 181 | ENABLE_TESTABILITY = YES; 182 | GCC_C_LANGUAGE_STANDARD = gnu11; 183 | GCC_DYNAMIC_NO_PIC = NO; 184 | GCC_NO_COMMON_BLOCKS = YES; 185 | GCC_OPTIMIZATION_LEVEL = 0; 186 | GCC_PREPROCESSOR_DEFINITIONS = ( 187 | "DEBUG=1", 188 | "$(inherited)", 189 | ); 190 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 191 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 192 | GCC_WARN_UNDECLARED_SELECTOR = YES; 193 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 194 | GCC_WARN_UNUSED_FUNCTION = YES; 195 | GCC_WARN_UNUSED_VARIABLE = YES; 196 | MACOSX_DEPLOYMENT_TARGET = 10.14; 197 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 198 | MTL_FAST_MATH = YES; 199 | ONLY_ACTIVE_ARCH = YES; 200 | SDKROOT = macosx; 201 | }; 202 | name = Debug; 203 | }; 204 | F8E344E22176D16400264D73 /* Release */ = { 205 | isa = XCBuildConfiguration; 206 | buildSettings = { 207 | ALWAYS_SEARCH_USER_PATHS = NO; 208 | CLANG_ANALYZER_NONNULL = YES; 209 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 210 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 211 | CLANG_CXX_LIBRARY = "libc++"; 212 | CLANG_ENABLE_MODULES = YES; 213 | CLANG_ENABLE_OBJC_ARC = YES; 214 | CLANG_ENABLE_OBJC_WEAK = YES; 215 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 216 | CLANG_WARN_BOOL_CONVERSION = YES; 217 | CLANG_WARN_COMMA = YES; 218 | CLANG_WARN_CONSTANT_CONVERSION = YES; 219 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 220 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 221 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 222 | CLANG_WARN_EMPTY_BODY = YES; 223 | CLANG_WARN_ENUM_CONVERSION = YES; 224 | CLANG_WARN_INFINITE_RECURSION = YES; 225 | CLANG_WARN_INT_CONVERSION = YES; 226 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 227 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 228 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 229 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 230 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 231 | CLANG_WARN_STRICT_PROTOTYPES = YES; 232 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 233 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 234 | CLANG_WARN_UNREACHABLE_CODE = YES; 235 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 236 | CODE_SIGN_IDENTITY = "-"; 237 | COPY_PHASE_STRIP = NO; 238 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 239 | ENABLE_NS_ASSERTIONS = NO; 240 | ENABLE_STRICT_OBJC_MSGSEND = YES; 241 | GCC_C_LANGUAGE_STANDARD = gnu11; 242 | GCC_NO_COMMON_BLOCKS = YES; 243 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 244 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 245 | GCC_WARN_UNDECLARED_SELECTOR = YES; 246 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 247 | GCC_WARN_UNUSED_FUNCTION = YES; 248 | GCC_WARN_UNUSED_VARIABLE = YES; 249 | MACOSX_DEPLOYMENT_TARGET = 10.14; 250 | MTL_ENABLE_DEBUG_INFO = NO; 251 | MTL_FAST_MATH = YES; 252 | SDKROOT = macosx; 253 | }; 254 | name = Release; 255 | }; 256 | F8E344E42176D16400264D73 /* Debug */ = { 257 | isa = XCBuildConfiguration; 258 | buildSettings = { 259 | CODE_SIGN_STYLE = Automatic; 260 | PRODUCT_NAME = "$(TARGET_NAME)"; 261 | }; 262 | name = Debug; 263 | }; 264 | F8E344E52176D16400264D73 /* Release */ = { 265 | isa = XCBuildConfiguration; 266 | buildSettings = { 267 | CODE_SIGN_STYLE = Automatic; 268 | PRODUCT_NAME = "$(TARGET_NAME)"; 269 | }; 270 | name = Release; 271 | }; 272 | /* End XCBuildConfiguration section */ 273 | 274 | /* Begin XCConfigurationList section */ 275 | F8E344D72176D16400264D73 /* Build configuration list for PBXProject "TransformerKit Example" */ = { 276 | isa = XCConfigurationList; 277 | buildConfigurations = ( 278 | F8E344E12176D16400264D73 /* Debug */, 279 | F8E344E22176D16400264D73 /* Release */, 280 | ); 281 | defaultConfigurationIsVisible = 0; 282 | defaultConfigurationName = Release; 283 | }; 284 | F8E344E32176D16400264D73 /* Build configuration list for PBXNativeTarget "TransformerKit Example" */ = { 285 | isa = XCConfigurationList; 286 | buildConfigurations = ( 287 | F8E344E42176D16400264D73 /* Debug */, 288 | F8E344E52176D16400264D73 /* Release */, 289 | ); 290 | defaultConfigurationIsVisible = 0; 291 | defaultConfigurationName = Release; 292 | }; 293 | /* End XCConfigurationList section */ 294 | }; 295 | rootObject = F8E344D42176D16400264D73 /* Project object */; 296 | } 297 | -------------------------------------------------------------------------------- /Example/TransformerKit Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/TransformerKit Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/main.m: -------------------------------------------------------------------------------- 1 | // main.m 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | #import 25 | 26 | int main(int __unused argc, const char __unused *argv[]) { 27 | @autoreleasepool { 28 | [@{ 29 | @"Capitalized String" : TTTCapitalizedStringTransformerName, 30 | @"Uppercase String" : TTTUppercaseStringTransformerName, 31 | @"Lowercase String" : TTTLowercaseStringTransformerName, 32 | @"Camel Case String" : TTTCamelCaseStringTransformerName, 33 | @"Llama Case String" : TTTLlamaCaseStringTransformerName, 34 | @"Snake Case String" : TTTSnakeCaseStringTransformerName, 35 | @"Train Case String" : TTTTrainCaseStringTransformerName, 36 | @"Reversed String" : TTTReverseStringTransformerName, 37 | @"Rémövê Dîaçritics" : TTTRemoveDiacriticStringTransformerName, 38 | @"ट्रांस्लितेराते स्ट्रिंग" : TTTTransliterateStringToLatinTransformerName, 39 | @{@"key" : @"value"} : TTTJSONTransformerName 40 | } enumerateKeysAndObjectsUsingBlock:^(__unused id value, __unused id name, __unused BOOL *stop) { 41 | NSLog(@"%@: %@", value, [[NSValueTransformer valueTransformerForName:name] transformedValue:value]); 42 | }]; 43 | 44 | [@{ 45 | @"s\\v'ErStS": @"IPA-XSampa" 46 | } enumerateKeysAndObjectsUsingBlock:^(__unused id value, __unused id transform, __unused BOOL *stop) { 47 | NSLog(@"%@: %@", value, [TTTStringTransformerForICUTransform(transform) reverseTransformedValue:value]); 48 | }]; 49 | 50 | [@{ 51 | @"CamelCaseString" : TTTCamelCaseStringTransformerName, 52 | @"llamaCaseString" : TTTLlamaCaseStringTransformerName, 53 | @"snake_case_string" : TTTSnakeCaseStringTransformerName, 54 | @"train-case-string" : TTTTrainCaseStringTransformerName, 55 | @"gnirtS desreveR" : TTTReverseStringTransformerName, 56 | } enumerateKeysAndObjectsUsingBlock:^(__unused id value, __unused id name, __unused BOOL *stop) { 57 | NSLog(@"%@ (Reversed): %@", value, [[NSValueTransformer valueTransformerForName:name] reverseTransformedValue:value]); 58 | }]; 59 | 60 | [@[TTTISO8601DateTransformerName, TTTRFC2822DateTransformerName] enumerateObjectsUsingBlock:^(id name, __unused NSUInteger idx, __unused BOOL *stop) { 61 | NSValueTransformer *transformer = [NSValueTransformer valueTransformerForName:name]; 62 | NSLog(@"%@ (Timestamp): %@", name, [transformer transformedValue:[NSDate date]]); 63 | NSLog(@"%@ (Date): %@", name, [transformer reverseTransformedValue:[transformer transformedValue:[NSDate date]]]); 64 | }]; 65 | 66 | [@[TTTMD5TransformerName, TTTSHA1TransformerName, TTTSHA256TransformerName] enumerateObjectsUsingBlock:^(id name, __unused NSUInteger idx, __unused BOOL *stop) { 67 | NSValueTransformer *transformer = [NSValueTransformer valueTransformerForName:name]; 68 | NSLog(@"%@: %@", name, [transformer transformedValue:[name dataUsingEncoding:NSASCIIStringEncoding]]); 69 | }]; 70 | 71 | [@[TTTBase16EncodedDataTransformerName, TTTBase32EncodedDataTransformerName, TTTBase64EncodedDataTransformerName, TTTBase85EncodedDataTransformerName] enumerateObjectsUsingBlock:^(id name, __unused NSUInteger idx, __unused BOOL *stop) { 72 | NSValueTransformer *transformer = [NSValueTransformer valueTransformerForName:name]; 73 | NSLog(@"%@: %@", name, [transformer transformedValue:[name dataUsingEncoding:NSASCIIStringEncoding]]); 74 | 75 | NSData *data = [name dataUsingEncoding:NSASCIIStringEncoding]; 76 | if (![[transformer reverseTransformedValue:[transformer transformedValue:data]] isEqualToData:data]) { 77 | NSLog(@"Not equal!"); 78 | } 79 | }]; 80 | } 81 | 82 | return 0; 83 | } 84 | 85 | -------------------------------------------------------------------------------- /Framework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Framework/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module TransformerKit { 2 | umbrella header "TransformerKit.h" 3 | export * 4 | module * { export * } 5 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 – 2020 Mattt (https://mat.tt/) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TransformerKit 2 | 3 | **A block-based API for NSValueTransformer, 4 | with a growing collection of useful examples.** 5 | 6 | [`NSValueTransformer`](https://nshipster.com/nsvaluetransformer/), 7 | while perhaps obscure to most iOS programmers, 8 | remains a staple of OS X development. 9 | Before Objective-C APIs got in the habit of 10 | flinging block parameters hither and thither with reckless abandon, `NSValueTransformer` was the go-to way to encapsulate mutation functionality --- especially when it came to Bindings. 11 | 12 | `NSValueTransformer` is convenient to use but a pain to set up. 13 | To create a value transformer you have to 14 | create a subclass, 15 | implement a handful of required methods, 16 | and register a singleton instance by name. 17 | 18 | TransformerKit breathes new life into `NSValueTransformer` 19 | by making them dead-simple to define and register: 20 | 21 | ```objective-c 22 | NSString * const TTTCapitalizedStringTransformerName = @"TTTCapitalizedStringTransformerName"; 23 | 24 | [NSValueTransformer registerValueTransformerWithName:TTTCapitalizedStringTransformerName 25 | transformedValueClass:[NSString class] 26 | returningTransformedValueWithBlock:^id(id value) { 27 | return [value capitalizedString]; 28 | }]; 29 | ``` 30 | 31 | > TransformerKit pairs nicely with 32 | > [InflectorKit](https://github.com/mattt/InflectorKit) and 33 | > [FormatterKit](https://github.com/mattt/FormatterKit), 34 | > providing well-designed APIs for manipulating user-facing content. 35 | 36 | --- 37 | 38 | TransformerKit also contains a _growing_ number of convenient transformers 39 | that your apps will love and cherish: 40 | 41 | ### String Transformers 42 | 43 | - Capitalized 44 | - UPPERCASE 45 | - lowercase 46 | - CamelCase 47 | - llamaCase 48 | - snake_case 49 | - train-case 50 | - esreveR\* _(Reverse)_ 51 | - Rémövê Dîaçritics _(Remove accents and combining marks)_ 52 | - ट्रांस्लितेराते स्ट्रिंग _(Transliterate to Latin)_ 53 | - Any Valid [ICU Transform](http://userguide.icu-project.org/transforms/general)\* 54 | 55 | ### Image Transformers 56 | 57 | - PNG Representation\* 58 | - JPEG Representation\* 59 | - GIF Representation _(macOS)_ 60 | - TIFF Representation _(macOS)_ 61 | 62 | ### Date Transformers 63 | 64 | - [ISO 8601](http://www.iso.org/iso/home/standards/iso8601.htm) Timestamp\* 65 | - [RFC 2822](https://www.ietf.org/rfc/rfc2822) Timestamp\* 66 | 67 | ### JSON Data Transformers 68 | 69 | - JSON Transformer\* 70 | 71 | ### Data Transformers _(macOS)_ 72 | 73 | - Base16 String Encode / Decode 74 | - Base32 String Encode / Decode 75 | - Base64 String Encode / Decode 76 | - Base85 String Encode / Decode 77 | 78 | 79 | ### Cryptographic Transformers _(macOS)_ 80 | 81 | - MD5, SHA-1, SHA-256, et al. Digests 82 | 83 | > \* - **Reversible** 84 | 85 | ## Contact 86 | 87 | Mattt ([@mattt](https://twitter.com/mattt)) 88 | 89 | ## License 90 | 91 | TransformerKit is released under the MIT license. 92 | See the LICENSE file for more info. 93 | -------------------------------------------------------------------------------- /Sources/NSValueTransformer+TransformerKit.h: -------------------------------------------------------------------------------- 1 | // NSValueTransformer+TransformerKit.h 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | @import Foundation; 24 | 25 | NS_ASSUME_NONNULL_BEGIN 26 | 27 | @interface NSValueTransformer (TransformerKit) 28 | 29 | + (BOOL)registerValueTransformerWithName:(NSString *)name 30 | transformedValueClass:(Class)transformedValueClass 31 | returningTransformedValueWithBlock:(id (^)(id value))transformedValueBlock 32 | NS_SWIFT_NAME(registerValueTransformer(named:producing:with:)); 33 | 34 | + (BOOL)registerValueTransformerWithName:(NSString *)name 35 | transformedValueClass:(Class)transformedValueClass 36 | returningTransformedValueWithBlock:(id (^)(id value))transformedValueBlock 37 | allowingReverseTransformationWithBlock:(nullable id (^)(id value))reverseTransformedValueBlock 38 | NS_SWIFT_NAME(registerValueTransformer(named:producing:forward:reverse:));; 39 | 40 | @end 41 | 42 | NS_ASSUME_NONNULL_END 43 | -------------------------------------------------------------------------------- /Sources/NSValueTransformer+TransformerKit.m: -------------------------------------------------------------------------------- 1 | // NSValueTransformer+TransformerKit.h 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "NSValueTransformer+TransformerKit.h" 24 | 25 | @import Darwin.Availability; 26 | @import ObjectiveC.runtime; 27 | 28 | NS_ASSUME_NONNULL_BEGIN 29 | 30 | @implementation NSValueTransformer (TransformerKit) 31 | 32 | + (BOOL)registerValueTransformerWithName:(NSString *)name 33 | transformedValueClass:(Class)transformedValueClass 34 | returningTransformedValueWithBlock:(id (^)(id value))transformedValueBlock 35 | { 36 | return [self registerValueTransformerWithName:name transformedValueClass:transformedValueClass returningTransformedValueWithBlock:transformedValueBlock allowingReverseTransformationWithBlock:nil]; 37 | } 38 | 39 | + (BOOL)registerValueTransformerWithName:(NSString *)name 40 | transformedValueClass:(Class)transformedValueClass 41 | returningTransformedValueWithBlock:(id (^)(id value))transformedValueBlock 42 | allowingReverseTransformationWithBlock:(nullable id (^)(id value))reverseTransformedValueBlock 43 | { 44 | if (objc_lookUpClass((const char * _Nonnull)[name UTF8String])) { 45 | return NO; 46 | } 47 | 48 | if ([NSValueTransformer valueTransformerForName:name]) { 49 | return NO; 50 | } 51 | 52 | Class class = objc_allocateClassPair([NSValueTransformer class], (const char * _Nonnull)[name UTF8String], 0); 53 | if (!class) { 54 | return NO; 55 | } 56 | 57 | SEL transformedValueClassSelector = @selector(transformedValueClass); 58 | IMP transformedValueClassImplementation = imp_implementationWithBlock(^Class { 59 | return transformedValueClass; 60 | }); 61 | Method transformedValueClassMethod = class_getClassMethod(class, transformedValueClassSelector); 62 | class_replaceMethod(class, transformedValueClassSelector, transformedValueClassImplementation, method_getTypeEncoding(transformedValueClassMethod)); 63 | 64 | SEL transformedValueSelector = @selector(transformedValue:); 65 | IMP transformedValueImplementation = imp_implementationWithBlock(^id (id __unused _self, id _value){ 66 | return transformedValueBlock(_value); 67 | }); 68 | Method transformedValueMethod = class_getInstanceMethod(class, transformedValueSelector); 69 | class_replaceMethod(class, transformedValueSelector, transformedValueImplementation, method_getTypeEncoding(transformedValueMethod)); 70 | 71 | if (reverseTransformedValueBlock) { 72 | SEL allowsReverseTransformationSelector = @selector(allowsReverseTransformation); 73 | IMP allowsReverseTransformationImplementation = imp_implementationWithBlock(^BOOL (id __unused _self) { 74 | return YES; 75 | }); 76 | 77 | Method allowsReverseTransformationMethod; 78 | #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && (!defined(__IPHONE_5_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0) 79 | allowsReverseTransformationMethod = class_getClassMethod(class, allowsReverseTransformationSelector); 80 | #elif defined(MAC_OS_X_VERSION_MIN_REQUIRED) && (!defined(MAC_OS_X_VERSION_10_8) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8) 81 | allowsReverseTransformationMethod = class_getClassMethod(class, allowsReverseTransformationSelector); 82 | #else 83 | allowsReverseTransformationMethod = class_getInstanceMethod(class, allowsReverseTransformationSelector); 84 | #endif 85 | 86 | class_replaceMethod(class, allowsReverseTransformationSelector, allowsReverseTransformationImplementation, method_getTypeEncoding(allowsReverseTransformationMethod)); 87 | 88 | SEL reverseTransformedValueSelector = @selector(reverseTransformedValue:); 89 | IMP reverseTransformedValueImplementation = imp_implementationWithBlock(^id (id __unused _self, id _value){ 90 | return reverseTransformedValueBlock(_value); 91 | }); 92 | Method reverseTransformedValueMethod = class_getInstanceMethod(class, reverseTransformedValueSelector); 93 | class_replaceMethod(class, reverseTransformedValueSelector, reverseTransformedValueImplementation, method_getTypeEncoding(reverseTransformedValueMethod)); 94 | } 95 | 96 | objc_registerClassPair(class); 97 | 98 | NSValueTransformer *valueTransformer = [(NSValueTransformer *)[class alloc] init]; 99 | [self setValueTransformer:valueTransformer forName:name]; 100 | 101 | return YES; 102 | } 103 | 104 | @end 105 | 106 | NS_ASSUME_NONNULL_END 107 | -------------------------------------------------------------------------------- /Sources/NSValueTransformerName.h: -------------------------------------------------------------------------------- 1 | // NSValueTransformerName.h 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | @import Darwin.Availability; 24 | 25 | #ifndef NSValueTransformerName_h 26 | #define NSValueTransformerName_h 27 | 28 | #if !defined(MAC_OS_X_VERSION_10_10) || !defined(__IPHONE_10_0) 29 | typedef NSString *NSValueTransformerName; 30 | #endif 31 | 32 | #endif /* NSValueTransformerName_h */ 33 | -------------------------------------------------------------------------------- /Sources/TTTCryptographyTransformers.h: -------------------------------------------------------------------------------- 1 | // TTTCryptographyTransformers.h 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | @import Foundation; 24 | #import "NSValueTransformerName.h" 25 | 26 | NS_ASSUME_NONNULL_BEGIN 27 | 28 | /** 29 | 30 | */ 31 | extern NSValueTransformerName TTTMD5TransformerName NS_SWIFT_NAME(md5TransformerName); 32 | 33 | /** 34 | 35 | */ 36 | extern NSValueTransformerName TTTSHA1TransformerName NS_SWIFT_NAME(sha1TransformerName); 37 | 38 | /** 39 | 40 | */ 41 | extern NSValueTransformerName TTTSHA256TransformerName NS_SWIFT_NAME(sha256TransformerName); 42 | 43 | #pragma mark - 44 | 45 | typedef NSUInteger TTTDigestAlgorithm NS_SWIFT_NAME(DigestAlgorithm); 46 | 47 | /** 48 | 49 | */ 50 | typedef NS_ENUM(TTTDigestAlgorithm, TTTMessageDigestAlgorithm) { 51 | TTTMD2 = 2, 52 | TTTMD4 = 4, 53 | TTTMD5 = 5, 54 | } NS_SWIFT_NAME(MessageDigestAlgorithm); 55 | 56 | /** 57 | 58 | */ 59 | typedef NS_ENUM(TTTDigestAlgorithm, TTTSecureHashAlgorithm) { 60 | TTTSHA1 = 1, 61 | TTTSHA224 = 224, 62 | TTTSHA256 = 256, 63 | TTTSHA384 = 384, 64 | TTTSHA512 = 512, 65 | } NS_SWIFT_NAME(SecureHashAlgorithm); 66 | 67 | /// 68 | 69 | /** 70 | 71 | */ 72 | extern NSData * TTTDigestWithAlgorithmForString(TTTDigestAlgorithm algorithm, NSString *string) NS_SWIFT_NAME(digest(with:for:)); 73 | 74 | /** 75 | 76 | */ 77 | extern NSData * TTTDigestWithAlgorithmForData(TTTDigestAlgorithm algorithm, NSData *data) NS_SWIFT_NAME(digest(with:for:)); 78 | 79 | /** 80 | 81 | */ 82 | extern __attribute__((overloadable)) NSData * TTTHMACWithDigestAlgorithmForKeyAndData(TTTDigestAlgorithm algorithm, NSString *key, NSData *data) NS_SWIFT_NAME(hmac(with:for:and:)); 83 | 84 | /** 85 | 86 | */ 87 | extern __attribute__((overloadable)) NSData * TTTHMACWithDigestAlgorithmForKeyAndData(TTTDigestAlgorithm algorithm, NSData *key, NSData *data) NS_SWIFT_NAME(hmac(with:for:and:)); 88 | 89 | #pragma mark - 90 | 91 | /** 92 | 93 | */ 94 | extern NSString * TTTCryptographicHashTransformerNameWithAlgorithm(TTTMessageDigestAlgorithm algorithm) NS_SWIFT_NAME(crypographicHashTransformer(with:)); 95 | 96 | /** 97 | 98 | */ 99 | @interface TTTCryptographyTransformers : NSObject 100 | 101 | @end 102 | 103 | #pragma mark - 104 | 105 | /** 106 | 107 | */ 108 | @interface NSValueTransformer (TTTCryptography) 109 | 110 | /** 111 | 112 | */ 113 | + (void)registerValueTransformerForDigestAlgorithm:(TTTDigestAlgorithm)algorithm NS_SWIFT_NAME(registerValueTransformer(for:)); 114 | 115 | @end 116 | 117 | NS_ASSUME_NONNULL_END 118 | -------------------------------------------------------------------------------- /Sources/TTTCryptographyTransformers.m: -------------------------------------------------------------------------------- 1 | // TTTCryptographyTransformers.m 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "TTTCryptographyTransformers.h" 24 | 25 | #import "NSValueTransformer+TransformerKit.h" 26 | 27 | @import CommonCrypto; 28 | 29 | NS_ASSUME_NONNULL_BEGIN 30 | 31 | static NSValueTransformerName TTTMD2TransformerName = @"TTTMD2Transformer"; 32 | static NSValueTransformerName TTTMD4TransformerName = @"TTTMD4Transformer"; 33 | NSValueTransformerName TTTMD5TransformerName = @"TTTMD5Transformer"; 34 | 35 | NSValueTransformerName TTTSHA1TransformerName = @"TTTSHA1Transformer"; 36 | static NSValueTransformerName TTTSHA224TransformerName = @"TTTSHA224Transformer"; 37 | NSValueTransformerName TTTSHA256TransformerName = @"TTTSHA256Transformer"; 38 | static NSValueTransformerName TTTSHA384TransformerName = @"TTTSHA384Transformer"; 39 | static NSValueTransformerName TTTSHA512TransformerName = @"TTTSHA512Transformer"; 40 | 41 | NSValueTransformerName TTTCryptographicHashTransformerNameWithAlgorithm(TTTDigestAlgorithm algorithm) { 42 | switch (algorithm) { 43 | case TTTMD2: 44 | return TTTMD2TransformerName; 45 | case TTTMD4: 46 | return TTTMD4TransformerName; 47 | case TTTMD5: 48 | return TTTMD5TransformerName; 49 | case TTTSHA1: 50 | return TTTSHA1TransformerName; 51 | case TTTSHA224: 52 | return TTTSHA224TransformerName; 53 | case TTTSHA256: 54 | return TTTSHA256TransformerName; 55 | case TTTSHA384: 56 | return TTTSHA384TransformerName; 57 | case TTTSHA512: 58 | return TTTSHA512TransformerName; 59 | default: 60 | return nil; 61 | } 62 | } 63 | 64 | #pragma mark - 65 | 66 | static inline __attribute__((const)) unsigned int TTTDigestLengthForAlgorithm(TTTDigestAlgorithm algorithm) { 67 | switch (algorithm) { 68 | case TTTMD2: 69 | return CC_MD2_DIGEST_LENGTH; 70 | case TTTMD4: 71 | return CC_MD4_DIGEST_LENGTH; 72 | case TTTMD5: 73 | return CC_MD5_DIGEST_LENGTH; 74 | case TTTSHA1: 75 | return CC_SHA1_DIGEST_LENGTH; 76 | case TTTSHA224: 77 | return CC_SHA224_DIGEST_LENGTH; 78 | case TTTSHA256: 79 | return CC_SHA256_DIGEST_LENGTH; 80 | case TTTSHA384: 81 | return CC_SHA384_DIGEST_LENGTH; 82 | case TTTSHA512: 83 | default: 84 | return CC_SHA512_DIGEST_LENGTH; 85 | } 86 | } 87 | 88 | NSData * TTTDigestWithAlgorithmForString(TTTDigestAlgorithm algorithm, NSString *string) { 89 | return TTTDigestWithAlgorithmForData(algorithm, (NSData * _Nonnull)[string dataUsingEncoding:NSASCIIStringEncoding]); 90 | } 91 | 92 | NSData * TTTDigestWithAlgorithmForData(TTTDigestAlgorithm algorithm, NSData *data) { 93 | if (!data) { 94 | return nil; 95 | } 96 | 97 | unsigned int length = TTTDigestLengthForAlgorithm(algorithm); 98 | unsigned char output[length]; 99 | 100 | switch (algorithm) { 101 | case TTTMD2: 102 | CC_MD2(data.bytes, (CC_LONG)data.length, output); 103 | break; 104 | case TTTMD4: 105 | CC_MD4(data.bytes, (CC_LONG)data.length, output); 106 | break; 107 | case TTTMD5: 108 | CC_MD5(data.bytes, (CC_LONG)data.length, output); 109 | break; 110 | case TTTSHA1: 111 | CC_SHA1(data.bytes, (CC_LONG)data.length, output); 112 | break; 113 | case TTTSHA224: 114 | CC_SHA224(data.bytes, (CC_LONG)data.length, output); 115 | break; 116 | case TTTSHA256: 117 | CC_SHA256(data.bytes, (CC_LONG)data.length, output); 118 | break; 119 | case TTTSHA384: 120 | CC_SHA384(data.bytes, (CC_LONG)data.length, output); 121 | break; 122 | case TTTSHA512: 123 | CC_SHA512(data.bytes, (CC_LONG)data.length, output); 124 | break; 125 | } 126 | 127 | return [NSData dataWithBytes:output length:length]; 128 | } 129 | 130 | #pragma mark - 131 | 132 | static inline __attribute__((const)) CCHmacAlgorithm TTTHMACAlgorithmForDigestAlgorithm(TTTDigestAlgorithm algorithm) { 133 | switch (algorithm) { 134 | case TTTMD2: 135 | case TTTMD4: 136 | case TTTMD5: 137 | return kCCHmacAlgMD5; 138 | case TTTSHA224: 139 | return kCCHmacAlgSHA224; 140 | case TTTSHA384: 141 | return kCCHmacAlgSHA384; 142 | case TTTSHA512: 143 | return kCCHmacAlgSHA512; 144 | case TTTSHA256: 145 | return kCCHmacAlgSHA256; 146 | case TTTSHA1: 147 | default: 148 | return kCCHmacAlgSHA1; 149 | } 150 | } 151 | 152 | __attribute__((overloadable)) NSData * TTTHMACWithDigestAlgorithmForKeyAndData(TTTDigestAlgorithm algorithm, NSString *key, NSData *data) { 153 | return TTTHMACWithDigestAlgorithmForKeyAndData(algorithm, (NSData * _Nonnull)[key dataUsingEncoding:NSASCIIStringEncoding], data); 154 | } 155 | 156 | __attribute__((overloadable)) NSData * TTTHMACWithDigestAlgorithmForKeyAndData(TTTDigestAlgorithm algorithm, NSData *key, NSData *data) { 157 | unsigned int length = TTTDigestLengthForAlgorithm(algorithm); 158 | unsigned char output[length]; 159 | 160 | CCHmac(TTTHMACAlgorithmForDigestAlgorithm(algorithm), key.bytes, key.length, data.bytes, data.length, output); 161 | 162 | return [NSData dataWithBytes:output length:length]; 163 | } 164 | 165 | @implementation TTTCryptographyTransformers 166 | 167 | + (void)load { 168 | @autoreleasepool { 169 | [NSValueTransformer registerValueTransformerForDigestAlgorithm:TTTMD5]; 170 | [NSValueTransformer registerValueTransformerForDigestAlgorithm:TTTSHA1]; 171 | [NSValueTransformer registerValueTransformerForDigestAlgorithm:TTTSHA256]; 172 | } 173 | } 174 | 175 | @end 176 | 177 | @implementation NSValueTransformer (TTTCryptography) 178 | 179 | + (void)registerValueTransformerForDigestAlgorithm:(TTTDigestAlgorithm)algorithm { 180 | [NSValueTransformer registerValueTransformerWithName:TTTCryptographicHashTransformerNameWithAlgorithm(algorithm) transformedValueClass:[NSData class] returningTransformedValueWithBlock:^id(id value) { 181 | return TTTDigestWithAlgorithmForData(algorithm, value); 182 | }]; 183 | } 184 | 185 | @end 186 | 187 | NS_ASSUME_NONNULL_END 188 | -------------------------------------------------------------------------------- /Sources/TTTDataTransformers.h: -------------------------------------------------------------------------------- 1 | // TTTDataTransformers.h 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | @import Foundation; 24 | #import "NSValueTransformerName.h" 25 | 26 | NS_ASSUME_NONNULL_BEGIN 27 | 28 | extern NSValueTransformerName const TTTBase2EncodedDataTransformerName NS_SWIFT_NAME(base2EncodedDataTransformerName); 29 | 30 | extern NSValueTransformerName const TTTBase16EncodedDataTransformerName NS_SWIFT_NAME(base16EncodedDataTransformerName); 31 | 32 | extern NSValueTransformerName const TTTBase32EncodedDataTransformerName NS_SWIFT_NAME(base32EncodedDataTransformerName); 33 | 34 | extern NSValueTransformerName const TTTBase64EncodedDataTransformerName NS_SWIFT_NAME(base64EncodedDataTransformerName); 35 | 36 | extern NSValueTransformerName const TTTBase85EncodedDataTransformerName NS_SWIFT_NAME(base85EncodedDataTransformerName); 37 | 38 | /// 39 | 40 | extern NSValueTransformerName const TTTBinaryStringEncodedDataTransformerName NS_SWIFT_NAME(binaryStringEncodedDataTransformerName); 41 | 42 | 43 | extern NSValueTransformerName const TTTHexadecimalStringEncodedDataTransformerName NS_SWIFT_NAME(hexadecimalStringEncodedDataTransformerName); 44 | 45 | 46 | extern NSValueTransformerName const TTTAscii85EncodedDataTransformerName NS_SWIFT_NAME(ascii85EncodedDataTransformerName); 47 | 48 | 49 | @interface TTTDataTransformers : NSValueTransformer 50 | 51 | @end 52 | 53 | NS_ASSUME_NONNULL_END 54 | -------------------------------------------------------------------------------- /Sources/TTTDataTransformers.m: -------------------------------------------------------------------------------- 1 | // TTTDataTransformers.m 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | @import Security; 24 | 25 | #import "TTTDataTransformers.h" 26 | 27 | #import "NSValueTransformer+TransformerKit.h" 28 | 29 | NS_ASSUME_NONNULL_BEGIN 30 | 31 | NSValueTransformerName const TTTBase2EncodedDataTransformerName = @"TTTBase2EncodedDataTransformer"; 32 | 33 | NSValueTransformerName const TTTBase16EncodedDataTransformerName = @"TTTBase16EncodedDataTransformer"; 34 | 35 | NSValueTransformerName const TTTBase32EncodedDataTransformerName = @"TTTBase32EncodedDataTransformer"; 36 | 37 | NSValueTransformerName const TTTBase64EncodedDataTransformerName = @"TTTBase64EncodedDataTransformer"; 38 | 39 | NSValueTransformerName const TTTBase85EncodedDataTransformerName = @"TTTBase85EncodedDataTransformer"; 40 | 41 | #pragma mark - 42 | 43 | static const char _base16Alphabet[16] = "0123456789ABCDEF"; 44 | 45 | static NSString * TTTBase16EncodedStringFromData(NSData *data) { 46 | const uint8_t *inputBuffer = [data bytes]; 47 | 48 | NSUInteger length = [data length]; 49 | NSMutableString *mutableString = [NSMutableString stringWithCapacity:length * 2]; 50 | 51 | for (NSUInteger i = 0; i < length; i++) { 52 | char characters[2]; 53 | characters[0] = _base16Alphabet[(*(inputBuffer + i) & /* 0b11110000 */ 240) >> 4]; 54 | characters[1] = _base16Alphabet[(*(inputBuffer + i) & /* 0b00001111 */ 15) >> 0]; 55 | [mutableString appendString:(NSString * _Nonnull)[[NSString alloc] initWithBytes:characters length:2 encoding:NSASCIIStringEncoding]]; 56 | } 57 | 58 | return mutableString; 59 | } 60 | 61 | static NSData * TTTDataFromBase16EncodedString(NSString *string) { 62 | NSString *base16String = [string uppercaseString]; 63 | if (([base16String length] % 2) != 0) { 64 | return nil; 65 | } 66 | 67 | static NSCharacterSet *base16CharacterSet = nil; 68 | static dispatch_once_t onceToken; 69 | dispatch_once(&onceToken, ^{ 70 | NSMutableCharacterSet *mutableBase16CharacterSet = [[NSMutableCharacterSet alloc] init]; 71 | [mutableBase16CharacterSet addCharactersInString:(NSString * _Nonnull)[[NSString alloc] initWithBytes:_base16Alphabet length:16 encoding:NSASCIIStringEncoding]]; 72 | base16CharacterSet = mutableBase16CharacterSet; 73 | }); 74 | 75 | if ([[base16String stringByTrimmingCharactersInSet:base16CharacterSet] length] != 0) { 76 | return nil; 77 | } 78 | 79 | NSMutableData *output = [NSMutableData dataWithCapacity:([base16String length] / 2)]; 80 | 81 | NSUInteger characterOffset = 0; 82 | while (characterOffset < [base16String length]) { 83 | uint8_t values[2] = {0}; 84 | for (NSUInteger valueIndex = 0; valueIndex < 2; valueIndex++) { 85 | unichar currentCharacter = [base16String characterAtIndex:(characterOffset + valueIndex)]; 86 | const char *ptr = strchr(_base16Alphabet, currentCharacter); 87 | if (ptr) { 88 | values[valueIndex] = (ptr - _base16Alphabet); 89 | } 90 | } 91 | 92 | uint8_t byte = 0; 93 | byte = byte | (values[0] << 4); 94 | byte = byte | (values[1] << 0); 95 | 96 | [output appendBytes:&byte length:1]; 97 | characterOffset += 2; 98 | } 99 | 100 | return output; 101 | } 102 | 103 | static NSString * _Nullable TTTBase32EncodedStringFromData(NSData *data) { 104 | SecTransformRef transform = SecEncodeTransformCreate(kSecBase32Encoding, NULL); 105 | SecTransformSetAttribute(transform, kSecTransformInputAttributeName, (__bridge CFDataRef)data, NULL); 106 | NSData *encodedData = (__bridge_transfer NSData *)SecTransformExecute(transform, NULL); 107 | CFRelease(transform); 108 | 109 | return [[NSString alloc] initWithData:encodedData encoding:NSUTF8StringEncoding]; 110 | } 111 | 112 | static NSData * TTTDataFromBase32EncodedString(NSString *string) { 113 | SecTransformRef transform = SecDecodeTransformCreate(kSecBase32Encoding, NULL); 114 | SecTransformSetAttribute(transform, kSecTransformInputAttributeName, (__bridge CFDataRef)[string dataUsingEncoding:NSUTF8StringEncoding], NULL); 115 | NSData *decodedData = (__bridge_transfer NSData *)SecTransformExecute(transform, NULL); 116 | CFRelease(transform); 117 | 118 | return decodedData; 119 | } 120 | 121 | static NSString * _Nullable TTTBase64EncodedStringFromData(NSData *data) { 122 | SecTransformRef transform = SecEncodeTransformCreate(kSecBase64Encoding, NULL); 123 | SecTransformSetAttribute(transform, kSecTransformInputAttributeName, (__bridge CFDataRef)data, NULL); 124 | NSData *encodedData = (__bridge_transfer NSData *)SecTransformExecute(transform, NULL); 125 | CFRelease(transform); 126 | 127 | return [[NSString alloc] initWithData:encodedData encoding:NSUTF8StringEncoding]; 128 | } 129 | 130 | static NSData * TTTDataFromBase64EncodedString(NSString *string) { 131 | SecTransformRef transform = SecDecodeTransformCreate(kSecBase64Encoding, NULL); 132 | SecTransformSetAttribute(transform, kSecTransformInputAttributeName, (__bridge CFDataRef)[string dataUsingEncoding:NSUTF8StringEncoding], NULL); 133 | NSData *decodedData = (__bridge_transfer NSData *)SecTransformExecute(transform, NULL); 134 | CFRelease(transform); 135 | 136 | return decodedData; 137 | } 138 | 139 | static NSString * _Nullable TTTBase85EncodedStringFromData(NSData *data) { 140 | static uint8_t const _b85encode[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~"; 141 | 142 | NSUInteger length = [data length]; 143 | NSUInteger numberOfBlocks = length / 4; 144 | NSUInteger remainder = length % 4; 145 | 146 | NSMutableData *output = [NSMutableData dataWithLength:(numberOfBlocks * 5) + (remainder + 1)]; 147 | uint8_t *outputBuffer = [output mutableBytes]; 148 | NSUInteger outputLength = 0; 149 | 150 | for (NSUInteger i = 0; i < numberOfBlocks; i++) { 151 | uint32_t x = CFSwapInt32BigToHost(*(uint32_t *)([[data subdataWithRange:NSMakeRange(i * 4, 4)] bytes])); 152 | for (NSUInteger j = 0; j < 5; j++) { 153 | outputBuffer[outputLength + (4 - j)] = _b85encode[x % 85]; 154 | x /= 85; 155 | } 156 | 157 | outputLength += 5; 158 | } 159 | 160 | if (remainder > 0) { 161 | uint32_t x = CFSwapInt32BigToHost(*(uint32_t *)([[data subdataWithRange:NSMakeRange(numberOfBlocks * 4, remainder)] bytes])); 162 | for (NSUInteger j = 0; j < 5; j++) { 163 | outputBuffer[outputLength + (4 - j)] = _b85encode[x % 85]; 164 | x /= 85; 165 | } 166 | 167 | outputLength += (remainder + 1); 168 | } 169 | 170 | return [[NSString alloc] initWithBytes:outputBuffer length:outputLength encoding:NSASCIIStringEncoding]; 171 | } 172 | 173 | static NSData * TTTDataFromBase85EncodedString(NSString *string) { 174 | static const unsigned char _b85decode[] = { 175 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177 | 0, 62, 0, 63, 64, 65, 66, 0, 67, 68, 69, 70, 0, 71, 0, 0, 178 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 72, 73, 74, 75, 76, 179 | 77, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 180 | 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 0, 0, 0, 78, 79, 181 | 80, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 182 | 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 81, 82, 83, 84, 0, 183 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 187 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191 | }; 192 | 193 | const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding]; 194 | NSUInteger length = [string lengthOfBytesUsingEncoding:NSASCIIStringEncoding]; 195 | NSUInteger numberOfBlocks = length / 5; 196 | NSUInteger remainder = length % 5; 197 | 198 | NSMutableData *output = [NSMutableData dataWithLength:numberOfBlocks * 4 + remainder]; 199 | NSUInteger outputLength = 0; 200 | 201 | for (NSUInteger i = 0; i < numberOfBlocks; i++) { 202 | uint32_t x = 0; 203 | for (NSUInteger j = 0; j < 5; j++) { 204 | x = x * 85 + _b85decode[(unsigned char)characters[(i * 5) + j]]; 205 | } 206 | 207 | x = CFSwapInt32HostToBig(x); 208 | [output replaceBytesInRange:NSMakeRange(i * 4, 4) withBytes:&x]; 209 | outputLength += 4; 210 | } 211 | 212 | if (remainder > 0) { 213 | uint32_t x = 0; 214 | for (NSUInteger i = 0; i < remainder; i++) { 215 | x = x * 85 + _b85decode[(unsigned char)characters[(numberOfBlocks * 5) + i]]; 216 | } 217 | 218 | x *= pow(85, 5 - remainder); 219 | if (remainder > 1) { 220 | x += 0xffffff >> (remainder - 2) * 8; 221 | } 222 | 223 | x = CFSwapInt32HostToBig(x); 224 | [output replaceBytesInRange:NSMakeRange((numberOfBlocks * 4), 4) withBytes:&x]; 225 | outputLength += (remainder - 1); 226 | } 227 | 228 | return [output subdataWithRange:NSMakeRange(0, outputLength)]; 229 | } 230 | 231 | @implementation TTTDataTransformers 232 | 233 | + (void)load { 234 | @autoreleasepool { 235 | [NSValueTransformer registerValueTransformerWithName:TTTBase16EncodedDataTransformerName transformedValueClass:[NSString class] returningTransformedValueWithBlock:^id(id value) { 236 | return TTTBase16EncodedStringFromData(value); 237 | } allowingReverseTransformationWithBlock:^id(id value) { 238 | return TTTDataFromBase16EncodedString(value); 239 | }]; 240 | 241 | [NSValueTransformer registerValueTransformerWithName:TTTBase32EncodedDataTransformerName transformedValueClass:[NSString class] returningTransformedValueWithBlock:^id(id value) { 242 | return TTTBase32EncodedStringFromData(value); 243 | } allowingReverseTransformationWithBlock:^id(id value) { 244 | return TTTDataFromBase32EncodedString(value); 245 | }]; 246 | 247 | [NSValueTransformer registerValueTransformerWithName:TTTBase64EncodedDataTransformerName transformedValueClass:[NSString class] returningTransformedValueWithBlock:^id(id value) { 248 | return TTTBase64EncodedStringFromData(value); 249 | } allowingReverseTransformationWithBlock:^id(id value) { 250 | return TTTDataFromBase64EncodedString(value); 251 | }]; 252 | 253 | [NSValueTransformer registerValueTransformerWithName:TTTBase85EncodedDataTransformerName transformedValueClass:[NSString class] returningTransformedValueWithBlock:^id(id value) { 254 | return TTTBase85EncodedStringFromData(value); 255 | } allowingReverseTransformationWithBlock:^id(id value) { 256 | return TTTDataFromBase85EncodedString(value); 257 | }]; 258 | } 259 | } 260 | 261 | @end 262 | 263 | NS_ASSUME_NONNULL_END 264 | -------------------------------------------------------------------------------- /Sources/TTTDateTransformers.h: -------------------------------------------------------------------------------- 1 | // TTTDateTransformers.h 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | @import Foundation; 24 | #import "NSValueTransformerName.h" 25 | 26 | NS_ASSUME_NONNULL_BEGIN 27 | 28 | /** 29 | @warning Because `time.h` represents timestamps as 32-bit integers, times before 00:00::00 UTC on Thursday, January 1, 1970 and after 03:14:07 UTC on Tuesday, 19 January 2038 cannot be represented. 30 | */ 31 | extern NSValueTransformerName const TTTISO8601DateTransformerName NS_SWIFT_NAME(iso8601DateTransformerName); 32 | 33 | /** 34 | @warning Because `time.h` represents timestamps as 32-bit integers, times before 00:00::00 UTC on Thursday, January 1, 1970 and after 03:14:07 UTC on Tuesday, 19 January 2038 cannot be represented. 35 | */ 36 | extern NSValueTransformerName const TTTRFC2822DateTransformerName NS_SWIFT_NAME(rfc2822DateTransformerName); 37 | 38 | @interface TTTDateTransformers : NSObject 39 | 40 | @end 41 | 42 | NS_ASSUME_NONNULL_END 43 | -------------------------------------------------------------------------------- /Sources/TTTDateTransformers.m: -------------------------------------------------------------------------------- 1 | // TTTDateTransformers.m 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "TTTDateTransformers.h" 24 | 25 | #import "NSValueTransformer+TransformerKit.h" 26 | 27 | @import Darwin.C.time; 28 | @import Darwin.C.xlocale; 29 | 30 | NS_ASSUME_NONNULL_BEGIN 31 | 32 | NSValueTransformerName const TTTISO8601DateTransformerName = @"TTTISO8601DateTransformerName"; 33 | NSValueTransformerName const TTTRFC2822DateTransformerName = @"TTTRFC2822DateTransformerName"; 34 | 35 | static NSString * TTTISO8601TimestampFromDate(NSDate *date) { 36 | static NSDateFormatter *_iso8601DateFormatter = nil; 37 | static dispatch_once_t onceToken; 38 | dispatch_once(&onceToken, ^{ 39 | _iso8601DateFormatter = [[NSDateFormatter alloc] init]; 40 | [_iso8601DateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZ"]; 41 | [_iso8601DateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]]; 42 | [_iso8601DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; 43 | }); 44 | 45 | return [_iso8601DateFormatter stringFromDate:date]; 46 | } 47 | 48 | static NSDate * _Nullable TTTDateFromISO8601Timestamp(NSString *timestamp) { 49 | if (!timestamp) { 50 | return nil; 51 | } 52 | 53 | static unsigned int const ISO_8601_MAX_LENGTH = 29; 54 | 55 | const char *source = [timestamp cStringUsingEncoding:NSUTF8StringEncoding]; 56 | char destination[ISO_8601_MAX_LENGTH]; 57 | size_t length = strlen(source); 58 | 59 | if (length == 0) { 60 | return nil; 61 | } 62 | 63 | double milliseconds = 0.0; 64 | if (length == 20 && source[length - 1] == 'Z') { 65 | memcpy(destination, source, length - 1); 66 | strncpy(destination + length - 1, "+0000\0", 6); 67 | } else if (length == 24 && source[length - 5] == '.' && source[length - 1] == 'Z') { 68 | memcpy(destination, source, length - 5); 69 | strncpy(destination + length - 5, "+0000\0", 6); 70 | milliseconds = [[timestamp substringWithRange:NSMakeRange(20, 3)] doubleValue] / 1000.0; 71 | } else if (length == 25 && source[22] == ':') { 72 | memcpy(destination, source, 22); 73 | memcpy(destination + 22, source + 23, 2); 74 | } else if (length == 29 && source[26] == ':') { 75 | memcpy(destination, source, 26); 76 | memcpy(destination + 26, source + 27, 2); 77 | milliseconds = [[timestamp substringWithRange:NSMakeRange(20, 3)] doubleValue] / 1000.0; 78 | } else { 79 | memcpy(destination, source, MIN(length, ISO_8601_MAX_LENGTH - 1)); 80 | } 81 | 82 | destination[sizeof(destination) - 1] = 0; 83 | 84 | struct tm time = { 85 | .tm_isdst = -1, 86 | }; 87 | 88 | strptime_l(destination, "%FT%T%z", &time, NULL); 89 | 90 | return [NSDate dateWithTimeIntervalSince1970:mktime(&time) + milliseconds]; 91 | } 92 | 93 | static NSString * TTTRFC2822TimestampFromDate(NSDate *date) { 94 | static NSDateFormatter *_rfc2822DateFormatter = nil; 95 | static dispatch_once_t onceToken; 96 | dispatch_once(&onceToken, ^{ 97 | _rfc2822DateFormatter = [[NSDateFormatter alloc] init]; 98 | [_rfc2822DateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss zzz"]; 99 | [_rfc2822DateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]]; 100 | [_rfc2822DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; 101 | }); 102 | 103 | return [_rfc2822DateFormatter stringFromDate:date]; 104 | } 105 | 106 | static inline const char * _Nullable TTTFormatForRFC2822Timestamp(const char *timestamp) { 107 | NSCParameterAssert(timestamp); 108 | 109 | size_t length = strlen(timestamp); 110 | switch (length) { 111 | case 11: 112 | return "%d %b %Y"; 113 | case 15: 114 | return "%a %d %b %Y"; 115 | case 16: 116 | if (timestamp[3] == ',') { 117 | return "%a, %d %b %Y"; 118 | } else if (timestamp[14] == ':') { 119 | return "%d %b %Y %H:%M"; 120 | } 121 | break; 122 | case 18: 123 | return "%d %b %Y %H:%M:%S"; 124 | case 21: 125 | return "%a %d %b %Y %H:%M"; 126 | case 22: 127 | return "%a, %d %b %Y %H:%M"; 128 | case 24: 129 | return "%d %b %Y %H:%M:%S"; 130 | case 25: 131 | return "%a, %d %b %Y %H:%M:%S"; 132 | case 26: 133 | return "%d %b %Y %H:%M:%S %z"; 134 | case 28: 135 | case 29: 136 | if (timestamp[3] == ',') { 137 | return "%a, %d %b %Y %H:%M:%S %Z"; 138 | } else { 139 | return "%a %d %b %Y %H:%M:%S %Z"; 140 | } 141 | case 30: 142 | case 31: 143 | if (timestamp[3] == ',') { 144 | return "%a, %d %b %Y %H:%M:%S %z"; 145 | } else { 146 | return "%a %d %b %Y %H:%M:%S %z"; 147 | } 148 | default: 149 | break; 150 | } 151 | 152 | return NULL; 153 | } 154 | 155 | static NSDate * _Nullable TTTDateFromRFC2822Timestamp(NSString *timestamp) { 156 | if (!timestamp) { 157 | return nil; 158 | } 159 | 160 | const char *source = [timestamp cStringUsingEncoding:NSUTF8StringEncoding]; 161 | const char *format = TTTFormatForRFC2822Timestamp(source); 162 | 163 | if (format == NULL) { 164 | return nil; 165 | } 166 | 167 | struct tm time = { 168 | .tm_isdst = -1, 169 | }; 170 | 171 | strptime_l(source, format, &time, NULL); 172 | 173 | return [NSDate dateWithTimeIntervalSince1970:mktime(&time)]; 174 | } 175 | 176 | @implementation TTTDateTransformers 177 | 178 | + (void)load { 179 | @autoreleasepool { 180 | [NSValueTransformer registerValueTransformerWithName:TTTISO8601DateTransformerName transformedValueClass:[NSDate class] returningTransformedValueWithBlock:^id(id value) { 181 | return TTTISO8601TimestampFromDate(value); 182 | } allowingReverseTransformationWithBlock:^id(id value) { 183 | return TTTDateFromISO8601Timestamp(value); 184 | }]; 185 | 186 | [NSValueTransformer registerValueTransformerWithName:TTTRFC2822DateTransformerName transformedValueClass:[NSDate class] returningTransformedValueWithBlock:^id(id value) { 187 | return TTTRFC2822TimestampFromDate(value); 188 | } allowingReverseTransformationWithBlock:^id(id value) { 189 | return TTTDateFromRFC2822Timestamp(value); 190 | }]; 191 | } 192 | } 193 | 194 | @end 195 | 196 | NS_ASSUME_NONNULL_END 197 | -------------------------------------------------------------------------------- /Sources/TTTImageTransformers.h: -------------------------------------------------------------------------------- 1 | // TTTImageTransformers.h 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | @import Foundation; 24 | #if __IPHONE_OS_VERSION_MIN_REQUIRED 25 | @import UIKit; 26 | #elif __MAC_OS_X_VERSION_MIN_REQUIRED 27 | @import AppKit; 28 | #endif 29 | #import "NSValueTransformerName.h" 30 | 31 | NS_ASSUME_NONNULL_BEGIN 32 | 33 | #if defined(UIKIT_EXTERN) || defined(_APPKITDEFINES_H) 34 | 35 | #define kTTTJPEGRepresentationCompressionQuality 0.75 36 | 37 | /** 38 | 39 | */ 40 | extern NSValueTransformerName const TTTPNGRepresentationImageTransformerName NS_SWIFT_NAME(pngRepresentationImageTransformerName); 41 | 42 | /** 43 | 44 | */ 45 | extern NSValueTransformerName const TTTJPEGRepresentationImageTransformerName NS_SWIFT_NAME(jpegRepresentationImageTransformerName); 46 | 47 | #if __MAC_OS_X_VERSION_MIN_REQUIRED 48 | /** 49 | 50 | */ 51 | extern NSValueTransformerName const TTTGIFRepresentationImageTransformerName NS_SWIFT_NAME(gifRepresentationImageTransformerName); 52 | 53 | /** 54 | 55 | */ 56 | extern NSValueTransformerName const TTTTIFFRepresentationImageTransformerName NS_SWIFT_NAME(tiffRepresentationImageTransformerName); 57 | #endif 58 | 59 | @interface TTTImageTransformers : NSObject 60 | 61 | @end 62 | 63 | #endif 64 | 65 | NS_ASSUME_NONNULL_END 66 | -------------------------------------------------------------------------------- /Sources/TTTImageTransformers.m: -------------------------------------------------------------------------------- 1 | // TTTImageTransformers.m 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "TTTImageTransformers.h" 24 | 25 | #import "NSValueTransformer+TransformerKit.h" 26 | 27 | #if __IPHONE_OS_VERSION_MIN_REQUIRED 28 | #import 29 | #elif __MAC_OS_X_VERSION_MIN_REQUIRED 30 | #import 31 | 32 | NS_ASSUME_NONNULL_BEGIN 33 | 34 | static inline NSData * NSImageRepresentationWithType(NSImage *image, NSBitmapImageFileType type, NSDictionary *properties) { 35 | NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect(0.0f, 0.0f, image.size.width, image.size.height)]; 36 | return [bitmap representationUsingType:type properties:properties]; 37 | } 38 | 39 | NS_ASSUME_NONNULL_END 40 | 41 | #endif 42 | 43 | NS_ASSUME_NONNULL_BEGIN 44 | 45 | #if defined(UIKIT_EXTERN) || defined(_APPKITDEFINES_H) 46 | 47 | NSValueTransformerName const TTTPNGRepresentationImageTransformerName = @"TTTPNGRepresentationImageTransformer"; 48 | NSValueTransformerName const TTTJPEGRepresentationImageTransformerName = @"TTTJPEGRepresentationImageTransformer"; 49 | 50 | #if __MAC_OS_X_VERSION_MIN_REQUIRED 51 | NSValueTransformerName const TTTGIFRepresentationImageTransformerName = @"TTTGIFRepresentationImageTransformer"; 52 | NSValueTransformerName const TTTTIFFRepresentationImageTransformerName = @"TTTTIFFRepresentationImageTransformer"; 53 | #endif 54 | 55 | @implementation TTTImageTransformers 56 | 57 | + (void)load { 58 | @autoreleasepool { 59 | #if __IPHONE_OS_VERSION_MIN_REQUIRED 60 | Class imageClass = [UIImage class]; 61 | #elif __MAC_OS_X_VERSION_MIN_REQUIRED 62 | Class imageClass = [NSImage class]; 63 | #endif 64 | 65 | [NSValueTransformer registerValueTransformerWithName:TTTPNGRepresentationImageTransformerName transformedValueClass:imageClass returningTransformedValueWithBlock:^id(id value) { 66 | #if __IPHONE_OS_VERSION_MIN_REQUIRED 67 | return UIImagePNGRepresentation(value); 68 | #elif __MAC_OS_X_VERSION_MIN_REQUIRED 69 | return NSImageRepresentationWithType(value, NSPNGFileType, @{}); 70 | #endif 71 | } allowingReverseTransformationWithBlock:^id(id value) { 72 | #if __IPHONE_OS_VERSION_MIN_REQUIRED 73 | return [[imageClass alloc] initWithData:value scale:[[UIScreen mainScreen] scale]]; 74 | #elif __MAC_OS_X_VERSION_MIN_REQUIRED 75 | return [[imageClass alloc] initWithData:value]; 76 | #endif 77 | }]; 78 | 79 | [NSValueTransformer registerValueTransformerWithName:TTTJPEGRepresentationImageTransformerName transformedValueClass:imageClass returningTransformedValueWithBlock:^id(id value) { 80 | #if __IPHONE_OS_VERSION_MIN_REQUIRED 81 | return UIImageJPEGRepresentation(value, kTTTJPEGRepresentationCompressionQuality); 82 | #elif __MAC_OS_X_VERSION_MIN_REQUIRED 83 | return NSImageRepresentationWithType(value, NSPNGFileType, [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:kTTTJPEGRepresentationCompressionQuality] forKey:NSImageCompressionFactor]); 84 | #endif 85 | } allowingReverseTransformationWithBlock:^id(id value) { 86 | #if __IPHONE_OS_VERSION_MIN_REQUIRED 87 | return [[imageClass alloc] initWithData:value scale:[[UIScreen mainScreen] scale]]; 88 | #elif __MAC_OS_X_VERSION_MIN_REQUIRED 89 | return [[imageClass alloc] initWithData:value]; 90 | #endif 91 | }]; 92 | 93 | #if __MAC_OS_X_VERSION_MIN_REQUIRED 94 | [NSValueTransformer registerValueTransformerWithName:TTTGIFRepresentationImageTransformerName transformedValueClass:imageClass returningTransformedValueWithBlock:^id(id value) { 95 | return NSImageRepresentationWithType(value, NSGIFFileType, @{}); 96 | } allowingReverseTransformationWithBlock:^id(id value) { 97 | return [[imageClass alloc] initWithData:value]; 98 | }]; 99 | 100 | [NSValueTransformer registerValueTransformerWithName:TTTTIFFRepresentationImageTransformerName transformedValueClass:imageClass returningTransformedValueWithBlock:^id(id value) { 101 | return NSImageRepresentationWithType(value, NSTIFFFileType, @{}); 102 | } allowingReverseTransformationWithBlock:^id(id value) { 103 | return [[imageClass alloc] initWithData:value]; 104 | }]; 105 | #endif 106 | } 107 | } 108 | 109 | @end 110 | 111 | #endif 112 | 113 | NS_ASSUME_NONNULL_END 114 | -------------------------------------------------------------------------------- /Sources/TTTJSONTransformer.h: -------------------------------------------------------------------------------- 1 | // TTTJSONTransformer.h 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | @import Foundation; 24 | #import "NSValueTransformerName.h" 25 | 26 | NS_ASSUME_NONNULL_BEGIN 27 | 28 | /** 29 | 30 | */ 31 | extern NSValueTransformerName const TTTJSONTransformerName NS_SWIFT_NAME(jsonTransformerName); 32 | 33 | /** 34 | 35 | */ 36 | @interface TTTJSONTransformer : NSValueTransformer 37 | 38 | /** 39 | 40 | */ 41 | @property (nonatomic, assign) NSJSONReadingOptions readingOptions; 42 | 43 | /** 44 | 45 | */ 46 | @property (nonatomic, assign) NSJSONWritingOptions writingOptions; 47 | 48 | @end 49 | 50 | NS_ASSUME_NONNULL_END 51 | -------------------------------------------------------------------------------- /Sources/TTTJSONTransformer.m: -------------------------------------------------------------------------------- 1 | // TTTJSONTransformer.h 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "TTTJSONTransformer.h" 24 | #import "NSValueTransformer+TransformerKit.h" 25 | 26 | NS_ASSUME_NONNULL_BEGIN 27 | 28 | NSValueTransformerName const TTTJSONTransformerName = @"TTTJSONTransformerName"; 29 | 30 | @implementation TTTJSONTransformer 31 | @synthesize readingOptions; 32 | @synthesize writingOptions; 33 | 34 | + (void)load { 35 | TTTJSONTransformer *transformer = [[TTTJSONTransformer alloc] init]; 36 | [self setValueTransformer:transformer forName:TTTJSONTransformerName]; 37 | } 38 | 39 | + (BOOL)allowsReverseTransformation { 40 | return YES; 41 | } 42 | 43 | + (Class)transformedValueClass { 44 | return [NSData class]; 45 | } 46 | 47 | - (nullable id)transformedValue:(nullable id)value { 48 | if (!value) { 49 | return nil; 50 | } 51 | 52 | NSError *error = nil; 53 | NSData *data = [NSJSONSerialization dataWithJSONObject:(id _Nonnull)value options:self.writingOptions error:&error]; 54 | 55 | return data; 56 | } 57 | 58 | - (nullable id)reverseTransformedValue:(nullable id)value { 59 | if (!value) { 60 | return nil; 61 | } 62 | 63 | id JSON = nil; 64 | NSError *error = nil; 65 | if ([(id)value isKindOfClass:[NSString class]]) { 66 | JSON = [self reverseTransformedValue:[(NSString *)value dataUsingEncoding:NSUTF8StringEncoding]]; 67 | } else if ([(id)value isKindOfClass:[NSData class]]) { 68 | JSON = [NSJSONSerialization JSONObjectWithData:(NSData *)value options:self.readingOptions error:&error]; 69 | } else if ([(id)value isKindOfClass:[NSInputStream class]]) { 70 | JSON = [NSJSONSerialization JSONObjectWithStream:(NSInputStream *)value options:self.readingOptions error:&error]; 71 | } 72 | 73 | return JSON; 74 | } 75 | 76 | @end 77 | 78 | NS_ASSUME_NONNULL_END 79 | -------------------------------------------------------------------------------- /Sources/TTTStringTransformers.h: -------------------------------------------------------------------------------- 1 | // TTTStringTransformers.h 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | @import Foundation; 24 | #import "NSValueTransformerName.h" 25 | 26 | NS_ASSUME_NONNULL_BEGIN 27 | 28 | /** 29 | 30 | */ 31 | extern NSValueTransformerName const TTTCapitalizedStringTransformerName NS_SWIFT_NAME(capitalizedStringTransformerName); 32 | 33 | /** 34 | 35 | */ 36 | extern NSValueTransformerName const TTTUppercaseStringTransformerName NS_SWIFT_NAME(uppercaseStringTransformerName); 37 | 38 | /** 39 | 40 | */ 41 | extern NSValueTransformerName const TTTLowercaseStringTransformerName NS_SWIFT_NAME(lowercaseStringTransformerName); 42 | 43 | /** 44 | 45 | */ 46 | extern NSValueTransformerName const TTTCamelCaseStringTransformerName NS_SWIFT_NAME(camelCaseStringTransformerName); 47 | 48 | /** 49 | 50 | */ 51 | extern NSValueTransformerName const TTTLlamaCaseStringTransformerName NS_SWIFT_NAME(llamaCaseStringTransformerName); 52 | 53 | /** 54 | 55 | */ 56 | extern NSValueTransformerName const TTTSnakeCaseStringTransformerName NS_SWIFT_NAME(snakeCaseStringTransformerName); 57 | 58 | /** 59 | 60 | */ 61 | extern NSValueTransformerName const TTTTrainCaseStringTransformerName NS_SWIFT_NAME(trainCaseStringTransformerName); 62 | 63 | /** 64 | 65 | */ 66 | extern NSValueTransformerName const TTTReverseStringTransformerName NS_SWIFT_NAME(reverseStringTransformerName); 67 | 68 | /** 69 | 70 | */ 71 | extern NSValueTransformerName const TTTRemoveDiacriticStringTransformerName NS_SWIFT_NAME(removeDiacriticStringTransformerName); 72 | 73 | /** 74 | 75 | */ 76 | extern NSValueTransformerName const TTTTransliterateStringToLatinTransformerName NS_SWIFT_NAME(transliterateStringToLatinTransformerName); 77 | 78 | /** 79 | 80 | */ 81 | extern NSValueTransformer * _Nullable TTTStringTransformerForICUTransform(NSString *transform) NS_SWIFT_NAME(StringTransformerForICUTransform(_:)); 82 | 83 | @interface TTTStringTransformers : NSObject 84 | 85 | @end 86 | 87 | NS_ASSUME_NONNULL_END 88 | -------------------------------------------------------------------------------- /Sources/TTTStringTransformers.m: -------------------------------------------------------------------------------- 1 | // TTTStringTransformers.m 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "TTTStringTransformers.h" 24 | 25 | #import "NSValueTransformer+TransformerKit.h" 26 | 27 | NS_ASSUME_NONNULL_BEGIN 28 | 29 | NSValueTransformerName const TTTCapitalizedStringTransformerName = @"TTTCapitalizedStringTransformerName"; 30 | NSValueTransformerName const TTTUppercaseStringTransformerName = @"TTTUppercaseStringTransformer"; 31 | NSValueTransformerName const TTTLowercaseStringTransformerName = @"TTTLowercaseStringTransformer"; 32 | NSValueTransformerName const TTTCamelCaseStringTransformerName = @"TTTCamelCaseStringTransformer"; 33 | NSValueTransformerName const TTTLlamaCaseStringTransformerName = @"TTTLlamaCaseStringTransformer"; 34 | NSValueTransformerName const TTTSnakeCaseStringTransformerName = @"TTTSnakeCaseStringTransformer"; 35 | NSValueTransformerName const TTTTrainCaseStringTransformerName = @"TTTTrainCaseStringTransformer"; 36 | NSValueTransformerName const TTTReverseStringTransformerName = @"TTTReverseStringTransformer"; 37 | NSValueTransformerName const TTTRemoveDiacriticStringTransformerName = @"TTTRemoveDiacriticStringTransformer"; 38 | NSValueTransformerName const TTTTransliterateStringToLatinTransformerName = @"TTTTransliterateStringToLatinTransformer"; 39 | 40 | static NSArray * TTTComponentsBySplittingOnWhitespaceWithString(NSString *string) { 41 | string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 42 | 43 | NSArray *components = [string componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 44 | components = [components filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self <> ''"]]; 45 | 46 | return components; 47 | } 48 | 49 | static NSArray * TTTComponentsBySplittingOnUppercaseWithString(NSString *string) { 50 | NSMutableString *mutableString = [string mutableCopy]; 51 | NSMutableArray *mutableComponents = [[NSMutableArray alloc] init]; 52 | 53 | NSRange uppercaseRange; 54 | while ((uppercaseRange = [mutableString rangeOfCharacterFromSet:[NSCharacterSet uppercaseLetterCharacterSet]]).location != NSNotFound) { 55 | NSRange componentRange = NSMakeRange(0, uppercaseRange.location); 56 | 57 | [mutableComponents addObject:[mutableString substringWithRange:componentRange]]; 58 | [mutableString deleteCharactersInRange:componentRange]; 59 | 60 | [mutableString replaceCharactersInRange:NSMakeRange(0, 1) withString:[[mutableString substringToIndex:1] lowercaseString]]; 61 | } 62 | [mutableComponents addObject:mutableString]; 63 | 64 | [mutableComponents filterUsingPredicate:[NSPredicate predicateWithFormat:@"self <> ''"]]; 65 | 66 | return [NSArray arrayWithArray:mutableComponents]; 67 | } 68 | 69 | static NSString * TTTReversedStringWithString(NSString *string) { 70 | __block NSMutableString *reversedString = [NSMutableString stringWithCapacity:[string length]]; 71 | [string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationReverse | NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange __unused substringRange, NSRange __unused enclosingRange, BOOL __unused *stop) { 72 | [reversedString appendString:substring]; 73 | }]; 74 | 75 | return reversedString; 76 | } 77 | 78 | NSValueTransformer * _Nullable TTTStringTransformerForICUTransform(NSString *transform) { 79 | NSString *transformerName = [NSString stringWithFormat:@"TTTStringICUTransformer(%@)", transform]; 80 | if (![[NSValueTransformer valueTransformerNames] containsObject:transformerName]) { 81 | BOOL success = [NSValueTransformer registerValueTransformerWithName:transformerName transformedValueClass:[NSString class] returningTransformedValueWithBlock:^id(id value) { 82 | NSMutableString *mutableString = [NSMutableString stringWithString:[(id)value description]]; 83 | CFStringTransform((__bridge CFMutableStringRef)mutableString, NULL, (__bridge CFStringRef)transform, NO); 84 | return [NSString stringWithString:mutableString]; 85 | } allowingReverseTransformationWithBlock:^id(id value) { 86 | NSMutableString *mutableString = [NSMutableString stringWithString:[(id)value description]]; 87 | CFStringTransform((__bridge CFMutableStringRef)mutableString, NULL, (__bridge CFStringRef)transform, YES); 88 | return [NSString stringWithString:mutableString]; 89 | }]; 90 | 91 | if (!success) { 92 | return nil; 93 | } 94 | } 95 | 96 | return [NSValueTransformer valueTransformerForName:transformerName]; 97 | } 98 | 99 | @implementation TTTStringTransformers 100 | 101 | + (void)load { 102 | @autoreleasepool { 103 | [NSValueTransformer registerValueTransformerWithName:TTTCapitalizedStringTransformerName transformedValueClass:[NSString class] returningTransformedValueWithBlock:^id(id value) { 104 | return [(NSString *)value capitalizedString]; 105 | }]; 106 | 107 | [NSValueTransformer registerValueTransformerWithName:TTTUppercaseStringTransformerName transformedValueClass:[NSString class] returningTransformedValueWithBlock:^id(id value) { 108 | return [(NSString *)value uppercaseString]; 109 | }]; 110 | 111 | [NSValueTransformer registerValueTransformerWithName:TTTLowercaseStringTransformerName transformedValueClass:[NSString class] returningTransformedValueWithBlock:^id(id value) { 112 | return [(NSString *)value lowercaseString]; 113 | }]; 114 | 115 | [NSValueTransformer registerValueTransformerWithName:TTTCamelCaseStringTransformerName transformedValueClass:[NSString class] returningTransformedValueWithBlock:^id(id value) { 116 | NSArray *components = TTTComponentsBySplittingOnWhitespaceWithString(value); 117 | NSMutableArray *mutableComponents = [NSMutableArray arrayWithCapacity:[components count]]; 118 | [components enumerateObjectsUsingBlock:^(id component, NSUInteger __unused idx, BOOL __unused *stop) { 119 | [mutableComponents addObject:[(NSString *)component capitalizedString]]; 120 | }]; 121 | 122 | return [mutableComponents componentsJoinedByString:@""]; 123 | } allowingReverseTransformationWithBlock:^id(id value) { 124 | NSArray *components = TTTComponentsBySplittingOnUppercaseWithString(value); 125 | 126 | return [components componentsJoinedByString:@" "]; 127 | }]; 128 | 129 | [NSValueTransformer registerValueTransformerWithName:TTTLlamaCaseStringTransformerName transformedValueClass:[NSString class] returningTransformedValueWithBlock:^id(id value) { 130 | NSArray *components = TTTComponentsBySplittingOnWhitespaceWithString(value); 131 | NSMutableArray *mutableComponents = [NSMutableArray arrayWithCapacity:[components count]]; 132 | [components enumerateObjectsUsingBlock:^(id component, NSUInteger idx, BOOL __unused *stop) { 133 | [mutableComponents addObject:(idx == 0 ? [(NSString *)component lowercaseString] : [(NSString *)component capitalizedString])]; 134 | }]; 135 | 136 | return [mutableComponents componentsJoinedByString:@""]; 137 | } allowingReverseTransformationWithBlock:^id(id value) { 138 | NSArray *components = TTTComponentsBySplittingOnUppercaseWithString(value); 139 | 140 | return [components componentsJoinedByString:@" "]; 141 | }]; 142 | 143 | [NSValueTransformer registerValueTransformerWithName:TTTSnakeCaseStringTransformerName transformedValueClass:[NSString class] returningTransformedValueWithBlock:^id(id value) { 144 | NSArray *components = TTTComponentsBySplittingOnWhitespaceWithString(value); 145 | NSMutableArray *mutableComponents = [NSMutableArray arrayWithCapacity:[components count]]; 146 | [components enumerateObjectsUsingBlock:^(id component, NSUInteger __unused idx, BOOL __unused *stop) { 147 | [mutableComponents addObject:[(NSString *)component lowercaseString]]; 148 | }]; 149 | 150 | return [mutableComponents componentsJoinedByString:@"_"]; 151 | } allowingReverseTransformationWithBlock:^id(id value) { 152 | NSArray *components = [(NSString *)value componentsSeparatedByString:@"_"]; 153 | 154 | return [components componentsJoinedByString:@" "]; 155 | }]; 156 | 157 | [NSValueTransformer registerValueTransformerWithName:TTTTrainCaseStringTransformerName transformedValueClass:[NSString class] returningTransformedValueWithBlock:^id(id value) { 158 | NSArray *components = TTTComponentsBySplittingOnWhitespaceWithString(value); 159 | NSMutableArray *mutableComponents = [NSMutableArray arrayWithCapacity:[components count]]; 160 | [components enumerateObjectsUsingBlock:^(id component, NSUInteger __unused idx, BOOL __unused *stop) { 161 | [mutableComponents addObject:[(NSString *)component lowercaseString]]; 162 | }]; 163 | 164 | return [mutableComponents componentsJoinedByString:@"-"]; 165 | } allowingReverseTransformationWithBlock:^id(id value) { 166 | NSArray *components = [(NSString *)value componentsSeparatedByString:@"-"]; 167 | 168 | return [components componentsJoinedByString:@" "]; 169 | }]; 170 | 171 | [NSValueTransformer registerValueTransformerWithName:TTTReverseStringTransformerName transformedValueClass:[NSString class] returningTransformedValueWithBlock:^id(id value) { 172 | return TTTReversedStringWithString(value); 173 | } allowingReverseTransformationWithBlock:^id(id value) { 174 | return TTTReversedStringWithString(value); 175 | }]; 176 | 177 | [NSValueTransformer registerValueTransformerWithName:TTTRemoveDiacriticStringTransformerName transformedValueClass:[NSString class] returningTransformedValueWithBlock:^id(id value) { 178 | NSMutableString *mutableString = [(NSString *)value mutableCopy]; 179 | CFStringTransform((__bridge CFMutableStringRef)(mutableString), NULL, kCFStringTransformStripCombiningMarks, NO); 180 | 181 | return mutableString; 182 | }]; 183 | 184 | [NSValueTransformer registerValueTransformerWithName:TTTTransliterateStringToLatinTransformerName transformedValueClass:[NSString class] returningTransformedValueWithBlock:^id(id value) { 185 | NSMutableString *mutableString = [(NSString *)value mutableCopy]; 186 | CFStringTransform((__bridge CFMutableStringRef)(mutableString), NULL, kCFStringTransformToLatin, NO); 187 | CFStringTransform((__bridge CFMutableStringRef)(mutableString), NULL, kCFStringTransformStripCombiningMarks, NO); 188 | 189 | return mutableString; 190 | }]; 191 | } 192 | } 193 | 194 | @end 195 | 196 | NS_ASSUME_NONNULL_END 197 | -------------------------------------------------------------------------------- /Sources/TransformerKit.h: -------------------------------------------------------------------------------- 1 | // TransformerKit.h 2 | // 3 | // Copyright (c) 2012 - 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #ifndef _TRANSFORMER_KIT_ 24 | #define _TRANSFORMER_KIT_ 25 | 26 | #import "TTTDateTransformers.h" 27 | #import "TTTImageTransformers.h" 28 | #import "TTTStringTransformers.h" 29 | #import "TTTJSONTransformer.h" 30 | #if __MAC_OS_X_VERSION_MIN_REQUIRED 31 | #import "TTTDataTransformers.h" 32 | #import "TTTCryptographyTransformers.h" 33 | #endif 34 | #import "NSValueTransformer+TransformerKit.h" 35 | #endif 36 | -------------------------------------------------------------------------------- /TransformerKit.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import TransformerKit 3 | 4 | // String Transformers 5 | 6 | let stringTransformers: [String: NSValueTransformerName] = [ 7 | "Capitalized String": .capitalizedStringTransformerName, 8 | "Uppercase String": .uppercaseStringTransformerName, 9 | "Lowercase String": .lowercaseStringTransformerName, 10 | "Camel Case String": .camelCaseStringTransformerName, 11 | "Llama Case String": .llamaCaseStringTransformerName, 12 | "Snake Case String": .snakeCaseStringTransformerName, 13 | "Train Case String": .trainCaseStringTransformerName, 14 | "Reversed String": .reverseStringTransformerName, 15 | "Rémövê Dîaçritics": .removeDiacriticStringTransformerName, 16 | "ट्रांस्लितेराते स्ट्रिंग": .transliterateStringToLatinTransformerName 17 | ] 18 | 19 | for (source, name) in stringTransformers { 20 | guard let transformer = ValueTransformer(forName: name), 21 | let result = transformer.transformedValue(source) 22 | else { 23 | fatalError() 24 | } 25 | 26 | print("\(source): \(result)") 27 | } 28 | 29 | // Reversable String Transformers 30 | 31 | let reverseStringTransformers: [String: NSValueTransformerName] = [ 32 | "CamelCaseString": .camelCaseStringTransformerName, 33 | "llamaCaseString": .llamaCaseStringTransformerName, 34 | "snake_case_string": .snakeCaseStringTransformerName, 35 | "train-case-string": .trainCaseStringTransformerName, 36 | "gnirtS desreveR": .reverseStringTransformerName 37 | ] 38 | 39 | for (source, name) in reverseStringTransformers { 40 | guard let transformer = ValueTransformer(forName: name), 41 | let result = transformer.transformedValue(source) 42 | else { 43 | fatalError() 44 | } 45 | 46 | print("\(source): \(result)") 47 | } 48 | 49 | // Date Transformers 50 | 51 | let dateTransformers: [String: NSValueTransformerName] = [ 52 | "ISO 8601": .iso8601DateTransformerName, 53 | "RFC 2822": .rfc2822DateTransformerName 54 | ] 55 | 56 | for (description, name) in dateTransformers { 57 | guard let transformer = ValueTransformer(forName: name), 58 | let timestamp = transformer.transformedValue(Date()) as? String, 59 | let date = transformer.reverseTransformedValue(timestamp) as? Date 60 | else { 61 | fatalError() 62 | } 63 | 64 | print("\(description): \(timestamp) - \(date)") 65 | } 66 | 67 | // Data Transformers 68 | 69 | let dataTransformers: [String: NSValueTransformerName] = [ 70 | "Base16Encode": .base16EncodedDataTransformerName, 71 | "Base32Encode": .base32EncodedDataTransformerName, 72 | "Base64Encode": .base64EncodedDataTransformerName, 73 | "Base85Encode": .base85EncodedDataTransformerName 74 | ] 75 | 76 | for (source, name) in dataTransformers { 77 | guard let transformer = ValueTransformer(forName: name), 78 | let data = source.data(using: .utf8), 79 | let result = transformer.transformedValue(data) as? String 80 | else { 81 | fatalError() 82 | } 83 | 84 | print("\(source): \(result)") 85 | } 86 | 87 | 88 | let cryptoTransformers: [String: NSValueTransformerName] = [ 89 | "MD5 Digest": .md5TransformerName, 90 | "SHA-1 Digest": .sha1TransformerName, 91 | "SHA-256 Digest": .sha256TransformerName 92 | ] 93 | 94 | // Cryptographic Transformers 95 | 96 | for (source, name) in cryptoTransformers { 97 | guard let transformer = ValueTransformer(forName: name), 98 | let data = source.data(using: .utf8), 99 | let result = transformer.transformedValue(data) as? Data 100 | else { 101 | fatalError() 102 | } 103 | 104 | print("\(source): \(result)") 105 | } 106 | -------------------------------------------------------------------------------- /TransformerKit.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /TransformerKit.podspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Pod::Spec.new do |s| 4 | s.name = 'TransformerKit' 5 | s.version = '1.1.1' 6 | s.license = 'MIT' 7 | s.summary = 'A block-based API for NSValueTransformer, with a growing collection of useful examples.' 8 | s.homepage = 'https://github.com/mattt/TransformerKit' 9 | s.authors = { 'Mattt' => 'mattt@me.com' } 10 | s.source = { git: 'https://github.com/mattt/TransformerKit.git', tag: s.version } 11 | 12 | s.ios.deployment_target = '5.0' 13 | s.osx.deployment_target = '10.7' 14 | 15 | s.requires_arc = true 16 | 17 | s.subspec 'Core' do |ss| 18 | ss.source_files = 'Sources/NSValueTransformer+TransformerKit.{h,m}', 'Sources/NSValueTransformerName.h' 19 | end 20 | 21 | s.subspec 'Cryptography' do |ss| 22 | ss.dependency 'TransformerKit/Core' 23 | ss.osx.source_files = 'Sources/TTTCryptographyTransformers.{h,m}' 24 | ss.osx.frameworks = 'Security' 25 | end 26 | 27 | s.subspec 'Data' do |ss| 28 | ss.dependency 'TransformerKit/Core' 29 | ss.osx.source_files = 'Sources/TTTDataTransformers.{h,m}' 30 | ss.osx.frameworks = 'Security' 31 | end 32 | 33 | s.subspec 'Date' do |ss| 34 | ss.dependency 'TransformerKit/Core' 35 | ss.source_files = 'Sources/TTTDateTransformers.{h,m}' 36 | end 37 | 38 | s.subspec 'JSON' do |ss| 39 | ss.dependency 'TransformerKit/Core' 40 | ss.source_files = 'Sources/TTTJSONTransformer.{h,m}' 41 | end 42 | 43 | s.subspec 'Image' do |ss| 44 | ss.dependency 'TransformerKit/Core' 45 | ss.source_files = 'Sources/TTTImageTransformers.{h,m}' 46 | end 47 | 48 | s.subspec 'String' do |ss| 49 | ss.dependency 'TransformerKit/Core' 50 | ss.source_files = 'Sources/TTTStringTransformers.{h,m}' 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /TransformerKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | BED5C6C71C8CF94E00530969 /* NSValueTransformer+TransformerKit.h in Headers */ = {isa = PBXBuildFile; fileRef = BED5C6B71C8CF94E00530969 /* NSValueTransformer+TransformerKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | BED5C6C81C8CF94E00530969 /* NSValueTransformer+TransformerKit.m in Sources */ = {isa = PBXBuildFile; fileRef = BED5C6B81C8CF94E00530969 /* NSValueTransformer+TransformerKit.m */; }; 12 | BED5C6C91C8CF94E00530969 /* TransformerKit.h in Headers */ = {isa = PBXBuildFile; fileRef = BED5C6B91C8CF94E00530969 /* TransformerKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | BED5C6CC1C8CF94E00530969 /* TTTDateTransformers.h in Headers */ = {isa = PBXBuildFile; fileRef = BED5C6BC1C8CF94E00530969 /* TTTDateTransformers.h */; settings = {ATTRIBUTES = (Public, ); }; }; 14 | BED5C6CD1C8CF94E00530969 /* TTTDateTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = BED5C6BD1C8CF94E00530969 /* TTTDateTransformers.m */; }; 15 | BED5C6CE1C8CF94E00530969 /* TTTImageTransformers.h in Headers */ = {isa = PBXBuildFile; fileRef = BED5C6BE1C8CF94E00530969 /* TTTImageTransformers.h */; settings = {ATTRIBUTES = (Public, ); }; }; 16 | BED5C6CF1C8CF94E00530969 /* TTTImageTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = BED5C6BF1C8CF94E00530969 /* TTTImageTransformers.m */; }; 17 | BED5C6D01C8CF94E00530969 /* TTTJSONTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = BED5C6C01C8CF94E00530969 /* TTTJSONTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 18 | BED5C6D11C8CF94E00530969 /* TTTJSONTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = BED5C6C11C8CF94E00530969 /* TTTJSONTransformer.m */; }; 19 | BED5C6D21C8CF94E00530969 /* TTTStringTransformers.h in Headers */ = {isa = PBXBuildFile; fileRef = BED5C6C21C8CF94E00530969 /* TTTStringTransformers.h */; settings = {ATTRIBUTES = (Public, ); }; }; 20 | BED5C6D31C8CF94E00530969 /* TTTStringTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = BED5C6C31C8CF94E00530969 /* TTTStringTransformers.m */; }; 21 | BED5C6E31C8CF9E000530969 /* NSValueTransformer+TransformerKit.h in Headers */ = {isa = PBXBuildFile; fileRef = BED5C6B71C8CF94E00530969 /* NSValueTransformer+TransformerKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 22 | BED5C6E41C8CF9E000530969 /* TransformerKit.h in Headers */ = {isa = PBXBuildFile; fileRef = BED5C6B91C8CF94E00530969 /* TransformerKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 23 | BED5C6E51C8CF9E000530969 /* TTTDataTransformers.h in Headers */ = {isa = PBXBuildFile; fileRef = BED5C6BA1C8CF94E00530969 /* TTTDataTransformers.h */; settings = {ATTRIBUTES = (Public, ); }; }; 24 | BED5C6E61C8CF9E000530969 /* TTTDateTransformers.h in Headers */ = {isa = PBXBuildFile; fileRef = BED5C6BC1C8CF94E00530969 /* TTTDateTransformers.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25 | BED5C6E71C8CF9E000530969 /* TTTImageTransformers.h in Headers */ = {isa = PBXBuildFile; fileRef = BED5C6BE1C8CF94E00530969 /* TTTImageTransformers.h */; settings = {ATTRIBUTES = (Public, ); }; }; 26 | BED5C6E81C8CF9E000530969 /* TTTJSONTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = BED5C6C01C8CF94E00530969 /* TTTJSONTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 27 | BED5C6E91C8CF9E000530969 /* TTTStringTransformers.h in Headers */ = {isa = PBXBuildFile; fileRef = BED5C6C21C8CF94E00530969 /* TTTStringTransformers.h */; settings = {ATTRIBUTES = (Public, ); }; }; 28 | BED5C6EA1C8CF9E000530969 /* TTTCryptographyTransformers.h in Headers */ = {isa = PBXBuildFile; fileRef = BED5C6C41C8CF94E00530969 /* TTTCryptographyTransformers.h */; settings = {ATTRIBUTES = (Public, ); }; }; 29 | F872E1582176D27400B0FF99 /* NSValueTransformer+TransformerKit.m in Sources */ = {isa = PBXBuildFile; fileRef = BED5C6B81C8CF94E00530969 /* NSValueTransformer+TransformerKit.m */; }; 30 | F872E1592176D27400B0FF99 /* TTTDataTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = BED5C6BB1C8CF94E00530969 /* TTTDataTransformers.m */; }; 31 | F872E15A2176D27400B0FF99 /* TTTDateTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = BED5C6BD1C8CF94E00530969 /* TTTDateTransformers.m */; }; 32 | F872E15B2176D27400B0FF99 /* TTTImageTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = BED5C6BF1C8CF94E00530969 /* TTTImageTransformers.m */; }; 33 | F872E15C2176D27400B0FF99 /* TTTJSONTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = BED5C6C11C8CF94E00530969 /* TTTJSONTransformer.m */; }; 34 | F872E15D2176D27400B0FF99 /* TTTStringTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = BED5C6C31C8CF94E00530969 /* TTTStringTransformers.m */; }; 35 | F8F886232176D2A900BB644C /* TTTCryptographyTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = BED5C6C51C8CF94E00530969 /* TTTCryptographyTransformers.m */; }; 36 | F8F886252176D30000BB644C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8F886242176D30000BB644C /* Foundation.framework */; }; 37 | F8F886292176D30D00BB644C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8F886282176D30D00BB644C /* Security.framework */; }; 38 | F8F8862B2176D31500BB644C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8F8862A2176D31500BB644C /* Foundation.framework */; }; 39 | F8F8862E2176D74D00BB644C /* NSValueTransformerName.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F8862D2176D49800BB644C /* NSValueTransformerName.h */; settings = {ATTRIBUTES = (Public, ); }; }; 40 | F8F8862F2176D75900BB644C /* NSValueTransformerName.h in Headers */ = {isa = PBXBuildFile; fileRef = F8F8862D2176D49800BB644C /* NSValueTransformerName.h */; settings = {ATTRIBUTES = (Public, ); }; }; 41 | /* End PBXBuildFile section */ 42 | 43 | /* Begin PBXFileReference section */ 44 | BED5C6AE1C8CF80E00530969 /* TransformerKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TransformerKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | BED5C6B21C8CF80E00530969 /* Framework */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Framework; sourceTree = ""; }; 46 | BED5C6B71C8CF94E00530969 /* NSValueTransformer+TransformerKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSValueTransformer+TransformerKit.h"; sourceTree = ""; }; 47 | BED5C6B81C8CF94E00530969 /* NSValueTransformer+TransformerKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSValueTransformer+TransformerKit.m"; sourceTree = ""; }; 48 | BED5C6B91C8CF94E00530969 /* TransformerKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TransformerKit.h; sourceTree = ""; }; 49 | BED5C6BA1C8CF94E00530969 /* TTTDataTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTTDataTransformers.h; sourceTree = ""; }; 50 | BED5C6BB1C8CF94E00530969 /* TTTDataTransformers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTTDataTransformers.m; sourceTree = ""; }; 51 | BED5C6BC1C8CF94E00530969 /* TTTDateTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTTDateTransformers.h; sourceTree = ""; }; 52 | BED5C6BD1C8CF94E00530969 /* TTTDateTransformers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTTDateTransformers.m; sourceTree = ""; }; 53 | BED5C6BE1C8CF94E00530969 /* TTTImageTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTTImageTransformers.h; sourceTree = ""; }; 54 | BED5C6BF1C8CF94E00530969 /* TTTImageTransformers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTTImageTransformers.m; sourceTree = ""; }; 55 | BED5C6C01C8CF94E00530969 /* TTTJSONTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTTJSONTransformer.h; sourceTree = ""; }; 56 | BED5C6C11C8CF94E00530969 /* TTTJSONTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTTJSONTransformer.m; sourceTree = ""; }; 57 | BED5C6C21C8CF94E00530969 /* TTTStringTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTTStringTransformers.h; sourceTree = ""; }; 58 | BED5C6C31C8CF94E00530969 /* TTTStringTransformers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTTStringTransformers.m; sourceTree = ""; }; 59 | BED5C6C41C8CF94E00530969 /* TTTCryptographyTransformers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTTCryptographyTransformers.h; sourceTree = ""; }; 60 | BED5C6C51C8CF94E00530969 /* TTTCryptographyTransformers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTTCryptographyTransformers.m; sourceTree = ""; }; 61 | BED5C6DB1C8CF97400530969 /* TransformerKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TransformerKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | F8E344CD2176CD6500264D73 /* libcommonCrypto.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcommonCrypto.tbd; path = usr/lib/system/libcommonCrypto.tbd; sourceTree = SDKROOT; }; 63 | F8F886202176D2A300BB644C /* libSystem.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libSystem.tbd; path = usr/lib/libSystem.tbd; sourceTree = SDKROOT; }; 64 | F8F886242176D30000BB644C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.1.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 65 | F8F886262176D30400BB644C /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.1.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; 66 | F8F886282176D30D00BB644C /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 67 | F8F8862A2176D31500BB644C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 68 | F8F8862D2176D49800BB644C /* NSValueTransformerName.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSValueTransformerName.h; sourceTree = ""; }; 69 | /* End PBXFileReference section */ 70 | 71 | /* Begin PBXFrameworksBuildPhase section */ 72 | BED5C6AA1C8CF80E00530969 /* Frameworks */ = { 73 | isa = PBXFrameworksBuildPhase; 74 | buildActionMask = 2147483647; 75 | files = ( 76 | F8F886252176D30000BB644C /* Foundation.framework in Frameworks */, 77 | ); 78 | runOnlyForDeploymentPostprocessing = 0; 79 | }; 80 | BED5C6D71C8CF97400530969 /* Frameworks */ = { 81 | isa = PBXFrameworksBuildPhase; 82 | buildActionMask = 2147483647; 83 | files = ( 84 | F8F8862B2176D31500BB644C /* Foundation.framework in Frameworks */, 85 | F8F886292176D30D00BB644C /* Security.framework in Frameworks */, 86 | ); 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | /* End PBXFrameworksBuildPhase section */ 90 | 91 | /* Begin PBXGroup section */ 92 | BE13377A1C8CF76800117156 = { 93 | isa = PBXGroup; 94 | children = ( 95 | BED5C6C61C8CF94E00530969 /* Sources */, 96 | BED5C6B61C8CF8C300530969 /* Supporting Files */, 97 | BE1337841C8CF76900117156 /* Products */, 98 | F8E344CC2176CD6500264D73 /* Frameworks */, 99 | ); 100 | sourceTree = ""; 101 | }; 102 | BE1337841C8CF76900117156 /* Products */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | BED5C6AE1C8CF80E00530969 /* TransformerKit.framework */, 106 | BED5C6DB1C8CF97400530969 /* TransformerKit.framework */, 107 | ); 108 | name = Products; 109 | sourceTree = ""; 110 | }; 111 | BED5C6B61C8CF8C300530969 /* Supporting Files */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | BED5C6B21C8CF80E00530969 /* Framework */, 115 | ); 116 | name = "Supporting Files"; 117 | sourceTree = ""; 118 | }; 119 | BED5C6C61C8CF94E00530969 /* Sources */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | BED5C6B91C8CF94E00530969 /* TransformerKit.h */, 123 | F8F8862D2176D49800BB644C /* NSValueTransformerName.h */, 124 | BED5C6B71C8CF94E00530969 /* NSValueTransformer+TransformerKit.h */, 125 | BED5C6B81C8CF94E00530969 /* NSValueTransformer+TransformerKit.m */, 126 | BED5C6BA1C8CF94E00530969 /* TTTDataTransformers.h */, 127 | BED5C6BB1C8CF94E00530969 /* TTTDataTransformers.m */, 128 | BED5C6BC1C8CF94E00530969 /* TTTDateTransformers.h */, 129 | BED5C6BD1C8CF94E00530969 /* TTTDateTransformers.m */, 130 | BED5C6BE1C8CF94E00530969 /* TTTImageTransformers.h */, 131 | BED5C6BF1C8CF94E00530969 /* TTTImageTransformers.m */, 132 | BED5C6C01C8CF94E00530969 /* TTTJSONTransformer.h */, 133 | BED5C6C11C8CF94E00530969 /* TTTJSONTransformer.m */, 134 | BED5C6C21C8CF94E00530969 /* TTTStringTransformers.h */, 135 | BED5C6C31C8CF94E00530969 /* TTTStringTransformers.m */, 136 | BED5C6C41C8CF94E00530969 /* TTTCryptographyTransformers.h */, 137 | BED5C6C51C8CF94E00530969 /* TTTCryptographyTransformers.m */, 138 | ); 139 | path = Sources; 140 | sourceTree = ""; 141 | }; 142 | F8E344CC2176CD6500264D73 /* Frameworks */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | F8F8862A2176D31500BB644C /* Foundation.framework */, 146 | F8F886262176D30400BB644C /* Security.framework */, 147 | F8F886282176D30D00BB644C /* Security.framework */, 148 | F8F886242176D30000BB644C /* Foundation.framework */, 149 | F8F886202176D2A300BB644C /* libSystem.tbd */, 150 | F8E344CD2176CD6500264D73 /* libcommonCrypto.tbd */, 151 | ); 152 | name = Frameworks; 153 | sourceTree = ""; 154 | }; 155 | /* End PBXGroup section */ 156 | 157 | /* Begin PBXHeadersBuildPhase section */ 158 | BED5C6AB1C8CF80E00530969 /* Headers */ = { 159 | isa = PBXHeadersBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | BED5C6C91C8CF94E00530969 /* TransformerKit.h in Headers */, 163 | F8F8862F2176D75900BB644C /* NSValueTransformerName.h in Headers */, 164 | BED5C6D21C8CF94E00530969 /* TTTStringTransformers.h in Headers */, 165 | BED5C6CE1C8CF94E00530969 /* TTTImageTransformers.h in Headers */, 166 | BED5C6C71C8CF94E00530969 /* NSValueTransformer+TransformerKit.h in Headers */, 167 | BED5C6D01C8CF94E00530969 /* TTTJSONTransformer.h in Headers */, 168 | BED5C6CC1C8CF94E00530969 /* TTTDateTransformers.h in Headers */, 169 | ); 170 | runOnlyForDeploymentPostprocessing = 0; 171 | }; 172 | BED5C6D81C8CF97400530969 /* Headers */ = { 173 | isa = PBXHeadersBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | BED5C6E41C8CF9E000530969 /* TransformerKit.h in Headers */, 177 | F8F8862E2176D74D00BB644C /* NSValueTransformerName.h in Headers */, 178 | BED5C6E31C8CF9E000530969 /* NSValueTransformer+TransformerKit.h in Headers */, 179 | BED5C6E51C8CF9E000530969 /* TTTDataTransformers.h in Headers */, 180 | BED5C6E61C8CF9E000530969 /* TTTDateTransformers.h in Headers */, 181 | BED5C6E71C8CF9E000530969 /* TTTImageTransformers.h in Headers */, 182 | BED5C6E81C8CF9E000530969 /* TTTJSONTransformer.h in Headers */, 183 | BED5C6E91C8CF9E000530969 /* TTTStringTransformers.h in Headers */, 184 | BED5C6EA1C8CF9E000530969 /* TTTCryptographyTransformers.h in Headers */, 185 | ); 186 | runOnlyForDeploymentPostprocessing = 0; 187 | }; 188 | /* End PBXHeadersBuildPhase section */ 189 | 190 | /* Begin PBXNativeTarget section */ 191 | BED5C6AD1C8CF80E00530969 /* TransformerKit iOS */ = { 192 | isa = PBXNativeTarget; 193 | buildConfigurationList = BED5C6B31C8CF80E00530969 /* Build configuration list for PBXNativeTarget "TransformerKit iOS" */; 194 | buildPhases = ( 195 | BED5C6A91C8CF80E00530969 /* Sources */, 196 | BED5C6AA1C8CF80E00530969 /* Frameworks */, 197 | BED5C6AB1C8CF80E00530969 /* Headers */, 198 | BED5C6AC1C8CF80E00530969 /* Resources */, 199 | ); 200 | buildRules = ( 201 | ); 202 | dependencies = ( 203 | ); 204 | name = "TransformerKit iOS"; 205 | productName = TransformerKit; 206 | productReference = BED5C6AE1C8CF80E00530969 /* TransformerKit.framework */; 207 | productType = "com.apple.product-type.framework"; 208 | }; 209 | BED5C6DA1C8CF97400530969 /* TransformerKit macOS */ = { 210 | isa = PBXNativeTarget; 211 | buildConfigurationList = BED5C6E01C8CF97400530969 /* Build configuration list for PBXNativeTarget "TransformerKit macOS" */; 212 | buildPhases = ( 213 | BED5C6D61C8CF97400530969 /* Sources */, 214 | BED5C6D71C8CF97400530969 /* Frameworks */, 215 | BED5C6D81C8CF97400530969 /* Headers */, 216 | BED5C6D91C8CF97400530969 /* Resources */, 217 | ); 218 | buildRules = ( 219 | ); 220 | dependencies = ( 221 | ); 222 | name = "TransformerKit macOS"; 223 | productName = "TransformerKit-OSX"; 224 | productReference = BED5C6DB1C8CF97400530969 /* TransformerKit.framework */; 225 | productType = "com.apple.product-type.framework"; 226 | }; 227 | /* End PBXNativeTarget section */ 228 | 229 | /* Begin PBXProject section */ 230 | BE13377B1C8CF76800117156 /* Project object */ = { 231 | isa = PBXProject; 232 | attributes = { 233 | LastUpgradeCheck = 1140; 234 | ORGANIZATIONNAME = Mattt; 235 | TargetAttributes = { 236 | BED5C6AD1C8CF80E00530969 = { 237 | CreatedOnToolsVersion = 7.2; 238 | ProvisioningStyle = Automatic; 239 | }; 240 | BED5C6DA1C8CF97400530969 = { 241 | CreatedOnToolsVersion = 7.2; 242 | ProvisioningStyle = Automatic; 243 | }; 244 | }; 245 | }; 246 | buildConfigurationList = BE13377E1C8CF76800117156 /* Build configuration list for PBXProject "TransformerKit" */; 247 | compatibilityVersion = "Xcode 3.2"; 248 | developmentRegion = English; 249 | hasScannedForEncodings = 0; 250 | knownRegions = ( 251 | English, 252 | en, 253 | Base, 254 | ); 255 | mainGroup = BE13377A1C8CF76800117156; 256 | productRefGroup = BE1337841C8CF76900117156 /* Products */; 257 | projectDirPath = ""; 258 | projectRoot = ""; 259 | targets = ( 260 | BED5C6DA1C8CF97400530969 /* TransformerKit macOS */, 261 | BED5C6AD1C8CF80E00530969 /* TransformerKit iOS */, 262 | ); 263 | }; 264 | /* End PBXProject section */ 265 | 266 | /* Begin PBXResourcesBuildPhase section */ 267 | BED5C6AC1C8CF80E00530969 /* Resources */ = { 268 | isa = PBXResourcesBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | ); 272 | runOnlyForDeploymentPostprocessing = 0; 273 | }; 274 | BED5C6D91C8CF97400530969 /* Resources */ = { 275 | isa = PBXResourcesBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | }; 281 | /* End PBXResourcesBuildPhase section */ 282 | 283 | /* Begin PBXSourcesBuildPhase section */ 284 | BED5C6A91C8CF80E00530969 /* Sources */ = { 285 | isa = PBXSourcesBuildPhase; 286 | buildActionMask = 2147483647; 287 | files = ( 288 | BED5C6D11C8CF94E00530969 /* TTTJSONTransformer.m in Sources */, 289 | BED5C6D31C8CF94E00530969 /* TTTStringTransformers.m in Sources */, 290 | BED5C6CD1C8CF94E00530969 /* TTTDateTransformers.m in Sources */, 291 | BED5C6CF1C8CF94E00530969 /* TTTImageTransformers.m in Sources */, 292 | BED5C6C81C8CF94E00530969 /* NSValueTransformer+TransformerKit.m in Sources */, 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | }; 296 | BED5C6D61C8CF97400530969 /* Sources */ = { 297 | isa = PBXSourcesBuildPhase; 298 | buildActionMask = 2147483647; 299 | files = ( 300 | F872E1582176D27400B0FF99 /* NSValueTransformer+TransformerKit.m in Sources */, 301 | F872E1592176D27400B0FF99 /* TTTDataTransformers.m in Sources */, 302 | F872E15A2176D27400B0FF99 /* TTTDateTransformers.m in Sources */, 303 | F872E15B2176D27400B0FF99 /* TTTImageTransformers.m in Sources */, 304 | F872E15C2176D27400B0FF99 /* TTTJSONTransformer.m in Sources */, 305 | F872E15D2176D27400B0FF99 /* TTTStringTransformers.m in Sources */, 306 | F8F886232176D2A900BB644C /* TTTCryptographyTransformers.m in Sources */, 307 | ); 308 | runOnlyForDeploymentPostprocessing = 0; 309 | }; 310 | /* End PBXSourcesBuildPhase section */ 311 | 312 | /* Begin XCBuildConfiguration section */ 313 | BE1337981C8CF76900117156 /* Debug */ = { 314 | isa = XCBuildConfiguration; 315 | buildSettings = { 316 | ALWAYS_SEARCH_USER_PATHS = NO; 317 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 318 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 319 | CLANG_CXX_LIBRARY = "libc++"; 320 | CLANG_ENABLE_MODULES = YES; 321 | CLANG_ENABLE_OBJC_ARC = YES; 322 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 323 | CLANG_WARN_BOOL_CONVERSION = YES; 324 | CLANG_WARN_COMMA = YES; 325 | CLANG_WARN_CONSTANT_CONVERSION = YES; 326 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 327 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 328 | CLANG_WARN_EMPTY_BODY = YES; 329 | CLANG_WARN_ENUM_CONVERSION = YES; 330 | CLANG_WARN_INFINITE_RECURSION = YES; 331 | CLANG_WARN_INT_CONVERSION = YES; 332 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 333 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 334 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 335 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 336 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 337 | CLANG_WARN_STRICT_PROTOTYPES = YES; 338 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 339 | CLANG_WARN_UNREACHABLE_CODE = YES; 340 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 341 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 342 | COPY_PHASE_STRIP = NO; 343 | DEBUG_INFORMATION_FORMAT = dwarf; 344 | ENABLE_STRICT_OBJC_MSGSEND = YES; 345 | ENABLE_TESTABILITY = YES; 346 | GCC_C_LANGUAGE_STANDARD = gnu99; 347 | GCC_DYNAMIC_NO_PIC = NO; 348 | GCC_NO_COMMON_BLOCKS = YES; 349 | GCC_OPTIMIZATION_LEVEL = 0; 350 | GCC_PREPROCESSOR_DEFINITIONS = ( 351 | "DEBUG=1", 352 | "$(inherited)", 353 | ); 354 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 355 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 356 | GCC_WARN_UNDECLARED_SELECTOR = YES; 357 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 358 | GCC_WARN_UNUSED_FUNCTION = YES; 359 | GCC_WARN_UNUSED_VARIABLE = YES; 360 | MTL_ENABLE_DEBUG_INFO = YES; 361 | ONLY_ACTIVE_ARCH = YES; 362 | SDKROOT = macosx; 363 | }; 364 | name = Debug; 365 | }; 366 | BE1337991C8CF76900117156 /* Release */ = { 367 | isa = XCBuildConfiguration; 368 | buildSettings = { 369 | ALWAYS_SEARCH_USER_PATHS = NO; 370 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 371 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 372 | CLANG_CXX_LIBRARY = "libc++"; 373 | CLANG_ENABLE_MODULES = YES; 374 | CLANG_ENABLE_OBJC_ARC = YES; 375 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 376 | CLANG_WARN_BOOL_CONVERSION = YES; 377 | CLANG_WARN_COMMA = YES; 378 | CLANG_WARN_CONSTANT_CONVERSION = YES; 379 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 380 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 381 | CLANG_WARN_EMPTY_BODY = YES; 382 | CLANG_WARN_ENUM_CONVERSION = YES; 383 | CLANG_WARN_INFINITE_RECURSION = YES; 384 | CLANG_WARN_INT_CONVERSION = YES; 385 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 386 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 387 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 388 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 389 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 390 | CLANG_WARN_STRICT_PROTOTYPES = YES; 391 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 392 | CLANG_WARN_UNREACHABLE_CODE = YES; 393 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 394 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 395 | COPY_PHASE_STRIP = NO; 396 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 397 | ENABLE_NS_ASSERTIONS = NO; 398 | ENABLE_STRICT_OBJC_MSGSEND = YES; 399 | GCC_C_LANGUAGE_STANDARD = gnu99; 400 | GCC_NO_COMMON_BLOCKS = YES; 401 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 402 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 403 | GCC_WARN_UNDECLARED_SELECTOR = YES; 404 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 405 | GCC_WARN_UNUSED_FUNCTION = YES; 406 | GCC_WARN_UNUSED_VARIABLE = YES; 407 | MTL_ENABLE_DEBUG_INFO = NO; 408 | SDKROOT = macosx; 409 | VALIDATE_PRODUCT = YES; 410 | }; 411 | name = Release; 412 | }; 413 | BED5C6B41C8CF80E00530969 /* Debug */ = { 414 | isa = XCBuildConfiguration; 415 | buildSettings = { 416 | CODE_SIGN_IDENTITY = "iPhone Developer"; 417 | CODE_SIGN_STYLE = Automatic; 418 | CURRENT_PROJECT_VERSION = 1; 419 | DEFINES_MODULE = YES; 420 | DEVELOPMENT_TEAM = ""; 421 | DYLIB_COMPATIBILITY_VERSION = 1; 422 | DYLIB_CURRENT_VERSION = 1; 423 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 424 | INFOPLIST_FILE = Framework/Info.plist; 425 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 426 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 427 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 428 | MODULEMAP_FILE = "$(PROJECT_DIR)/Framework/module.modulemap"; 429 | PRODUCT_BUNDLE_IDENTIFIER = com.mattt.TransformerKit; 430 | PRODUCT_NAME = TransformerKit; 431 | PROVISIONING_PROFILE_SPECIFIER = ""; 432 | SDKROOT = iphoneos; 433 | SKIP_INSTALL = YES; 434 | TARGETED_DEVICE_FAMILY = "1,2"; 435 | VERSIONING_SYSTEM = "apple-generic"; 436 | VERSION_INFO_PREFIX = ""; 437 | }; 438 | name = Debug; 439 | }; 440 | BED5C6B51C8CF80E00530969 /* Release */ = { 441 | isa = XCBuildConfiguration; 442 | buildSettings = { 443 | CODE_SIGN_IDENTITY = "iPhone Developer"; 444 | CODE_SIGN_STYLE = Automatic; 445 | CURRENT_PROJECT_VERSION = 1; 446 | DEFINES_MODULE = YES; 447 | DEVELOPMENT_TEAM = ""; 448 | DYLIB_COMPATIBILITY_VERSION = 1; 449 | DYLIB_CURRENT_VERSION = 1; 450 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 451 | INFOPLIST_FILE = Framework/Info.plist; 452 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 453 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 454 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 455 | MODULEMAP_FILE = "$(PROJECT_DIR)/Framework/module.modulemap"; 456 | PRODUCT_BUNDLE_IDENTIFIER = com.mattt.TransformerKit; 457 | PRODUCT_NAME = TransformerKit; 458 | PROVISIONING_PROFILE_SPECIFIER = ""; 459 | SDKROOT = iphoneos; 460 | SKIP_INSTALL = YES; 461 | TARGETED_DEVICE_FAMILY = "1,2"; 462 | VERSIONING_SYSTEM = "apple-generic"; 463 | VERSION_INFO_PREFIX = ""; 464 | }; 465 | name = Release; 466 | }; 467 | BED5C6E11C8CF97400530969 /* Debug */ = { 468 | isa = XCBuildConfiguration; 469 | buildSettings = { 470 | CODE_SIGN_IDENTITY = "Mac Developer"; 471 | CODE_SIGN_STYLE = Automatic; 472 | COMBINE_HIDPI_IMAGES = YES; 473 | CURRENT_PROJECT_VERSION = 1; 474 | DEFINES_MODULE = YES; 475 | DEVELOPMENT_TEAM = ""; 476 | DYLIB_COMPATIBILITY_VERSION = 1; 477 | DYLIB_CURRENT_VERSION = 1; 478 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 479 | FRAMEWORK_VERSION = A; 480 | INFOPLIST_FILE = Framework/Info.plist; 481 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 482 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 483 | LIBRARY_SEARCH_PATHS = ( 484 | "$(inherited)", 485 | "$(SDKROOT)/usr/lib/system", 486 | ); 487 | MACOSX_DEPLOYMENT_TARGET = 10.10; 488 | MODULEMAP_FILE = "$(PROJECT_DIR)/Framework/module.modulemap"; 489 | PRODUCT_BUNDLE_IDENTIFIER = "com.mattt.TransformerKit-OSX"; 490 | PRODUCT_NAME = TransformerKit; 491 | PROVISIONING_PROFILE_SPECIFIER = ""; 492 | SDKROOT = macosx; 493 | SKIP_INSTALL = YES; 494 | VERSIONING_SYSTEM = "apple-generic"; 495 | VERSION_INFO_PREFIX = ""; 496 | }; 497 | name = Debug; 498 | }; 499 | BED5C6E21C8CF97400530969 /* Release */ = { 500 | isa = XCBuildConfiguration; 501 | buildSettings = { 502 | CODE_SIGN_IDENTITY = "Mac Developer"; 503 | CODE_SIGN_STYLE = Automatic; 504 | COMBINE_HIDPI_IMAGES = YES; 505 | CURRENT_PROJECT_VERSION = 1; 506 | DEFINES_MODULE = YES; 507 | DEVELOPMENT_TEAM = ""; 508 | DYLIB_COMPATIBILITY_VERSION = 1; 509 | DYLIB_CURRENT_VERSION = 1; 510 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 511 | FRAMEWORK_VERSION = A; 512 | INFOPLIST_FILE = Framework/Info.plist; 513 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 514 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 515 | LIBRARY_SEARCH_PATHS = ( 516 | "$(inherited)", 517 | "$(SDKROOT)/usr/lib/system", 518 | ); 519 | MACOSX_DEPLOYMENT_TARGET = 10.10; 520 | MODULEMAP_FILE = "$(PROJECT_DIR)/Framework/module.modulemap"; 521 | PRODUCT_BUNDLE_IDENTIFIER = "com.mattt.TransformerKit-OSX"; 522 | PRODUCT_NAME = TransformerKit; 523 | PROVISIONING_PROFILE_SPECIFIER = ""; 524 | SDKROOT = macosx; 525 | SKIP_INSTALL = YES; 526 | VERSIONING_SYSTEM = "apple-generic"; 527 | VERSION_INFO_PREFIX = ""; 528 | }; 529 | name = Release; 530 | }; 531 | /* End XCBuildConfiguration section */ 532 | 533 | /* Begin XCConfigurationList section */ 534 | BE13377E1C8CF76800117156 /* Build configuration list for PBXProject "TransformerKit" */ = { 535 | isa = XCConfigurationList; 536 | buildConfigurations = ( 537 | BE1337981C8CF76900117156 /* Debug */, 538 | BE1337991C8CF76900117156 /* Release */, 539 | ); 540 | defaultConfigurationIsVisible = 0; 541 | defaultConfigurationName = Release; 542 | }; 543 | BED5C6B31C8CF80E00530969 /* Build configuration list for PBXNativeTarget "TransformerKit iOS" */ = { 544 | isa = XCConfigurationList; 545 | buildConfigurations = ( 546 | BED5C6B41C8CF80E00530969 /* Debug */, 547 | BED5C6B51C8CF80E00530969 /* Release */, 548 | ); 549 | defaultConfigurationIsVisible = 0; 550 | defaultConfigurationName = Release; 551 | }; 552 | BED5C6E01C8CF97400530969 /* Build configuration list for PBXNativeTarget "TransformerKit macOS" */ = { 553 | isa = XCConfigurationList; 554 | buildConfigurations = ( 555 | BED5C6E11C8CF97400530969 /* Debug */, 556 | BED5C6E21C8CF97400530969 /* Release */, 557 | ); 558 | defaultConfigurationIsVisible = 0; 559 | defaultConfigurationName = Release; 560 | }; 561 | /* End XCConfigurationList section */ 562 | }; 563 | rootObject = BE13377B1C8CF76800117156 /* Project object */; 564 | } 565 | -------------------------------------------------------------------------------- /TransformerKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TransformerKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /TransformerKit.xcodeproj/xcshareddata/xcschemes/TransformerKit iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 53 | 59 | 60 | 61 | 62 | 68 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /TransformerKit.xcodeproj/xcshareddata/xcschemes/TransformerKit macOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 52 | 53 | 59 | 60 | 66 | 67 | 68 | 69 | 71 | 72 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /TransformerKit.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /TransformerKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | --------------------------------------------------------------------------------