├── .gitignore ├── .travis.yml ├── CaesarParser.podspec.json ├── CaesarParser.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── CaesarParser.xcscheme ├── CaesarParser ├── CaesarParser.h ├── Info.plist ├── JSONConvertible.swift ├── JSONDeserialization.swift ├── JSONSerializable.swift ├── JSONSerialization.swift └── JSONType.swift ├── CaesarParserTests ├── Info.plist ├── JSONDeserializationTests.swift └── JSONSerializationTests.swift ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | # Pods/ 27 | 28 | # Carthage 29 | # 30 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 31 | # Carthage/Checkouts 32 | 33 | Carthage/Build 34 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | os: osx 3 | osx_image: xcode7.1 4 | script: 5 | - xctool -project CaesarParser.xcodeproj -scheme CaesarParser -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO -------------------------------------------------------------------------------- /CaesarParser.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CaesarParser", 3 | "version": "1.1.0", 4 | "summary": "CaesarParser is a framework written in Swift for you to parse Model from JSON or to JSON.", 5 | "homepage": "https://github.com/lancy/CaesarParser", 6 | "license": "MIT", 7 | "authors": { 8 | "Lancy": "lancy1014@gmail.com" 9 | }, 10 | "source": { 11 | "git": "https://github.com/lancy/CaesarParser.git" 12 | }, 13 | "source_files": [ 14 | "CaesarParser/*.{h,swift}" 15 | ], 16 | "platforms":{ 17 | "ios":"8.0", 18 | "osx":"10.9", 19 | "tvos":"9.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /CaesarParser.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | BF7E51D71C3D509F00823F20 /* CaesarParser.h in Headers */ = {isa = PBXBuildFile; fileRef = BF7E51D61C3D509F00823F20 /* CaesarParser.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | BF7E51DE1C3D509F00823F20 /* CaesarParser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF7E51D31C3D509F00823F20 /* CaesarParser.framework */; }; 12 | BF7E51F01C3D519E00823F20 /* JSONDeserialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7E51ED1C3D519E00823F20 /* JSONDeserialization.swift */; }; 13 | BF7E51F11C3D519E00823F20 /* JSONSerialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7E51EE1C3D519E00823F20 /* JSONSerialization.swift */; }; 14 | BF7E51F21C3D519E00823F20 /* JSONType.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7E51EF1C3D519E00823F20 /* JSONType.swift */; }; 15 | BF7E51F51C3D51BA00823F20 /* JSONConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7E51F31C3D51BA00823F20 /* JSONConvertible.swift */; }; 16 | BF7E51F61C3D51BA00823F20 /* JSONSerializable.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7E51F41C3D51BA00823F20 /* JSONSerializable.swift */; }; 17 | BF7E51FB1C3D520200823F20 /* JSONDeserializationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7E51F91C3D520200823F20 /* JSONDeserializationTests.swift */; }; 18 | BF7E51FC1C3D520200823F20 /* JSONSerializationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7E51FA1C3D520200823F20 /* JSONSerializationTests.swift */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | BF7E51DF1C3D509F00823F20 /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = BF7E51CA1C3D509F00823F20 /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = BF7E51D21C3D509F00823F20; 27 | remoteInfo = CaesarParser; 28 | }; 29 | /* End PBXContainerItemProxy section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | BF7E51D31C3D509F00823F20 /* CaesarParser.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CaesarParser.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | BF7E51D61C3D509F00823F20 /* CaesarParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CaesarParser.h; sourceTree = ""; }; 34 | BF7E51D81C3D509F00823F20 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 35 | BF7E51DD1C3D509F00823F20 /* CaesarParserTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CaesarParserTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 36 | BF7E51E41C3D509F00823F20 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 37 | BF7E51ED1C3D519E00823F20 /* JSONDeserialization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONDeserialization.swift; sourceTree = ""; }; 38 | BF7E51EE1C3D519E00823F20 /* JSONSerialization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONSerialization.swift; sourceTree = ""; }; 39 | BF7E51EF1C3D519E00823F20 /* JSONType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONType.swift; sourceTree = ""; }; 40 | BF7E51F31C3D51BA00823F20 /* JSONConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONConvertible.swift; sourceTree = ""; }; 41 | BF7E51F41C3D51BA00823F20 /* JSONSerializable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONSerializable.swift; sourceTree = ""; }; 42 | BF7E51F91C3D520200823F20 /* JSONDeserializationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONDeserializationTests.swift; sourceTree = ""; }; 43 | BF7E51FA1C3D520200823F20 /* JSONSerializationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONSerializationTests.swift; sourceTree = ""; }; 44 | BF7E51FD1C3D53CB00823F20 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | BF7E51CF1C3D509F00823F20 /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | BF7E51DA1C3D509F00823F20 /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | BF7E51DE1C3D509F00823F20 /* CaesarParser.framework in Frameworks */, 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXFrameworksBuildPhase section */ 64 | 65 | /* Begin PBXGroup section */ 66 | BF7E51C91C3D509F00823F20 = { 67 | isa = PBXGroup; 68 | children = ( 69 | BF7E51FD1C3D53CB00823F20 /* README.md */, 70 | BF7E51D51C3D509F00823F20 /* CaesarParser */, 71 | BF7E51E11C3D509F00823F20 /* CaesarParserTests */, 72 | BF7E51D41C3D509F00823F20 /* Products */, 73 | ); 74 | sourceTree = ""; 75 | }; 76 | BF7E51D41C3D509F00823F20 /* Products */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | BF7E51D31C3D509F00823F20 /* CaesarParser.framework */, 80 | BF7E51DD1C3D509F00823F20 /* CaesarParserTests.xctest */, 81 | ); 82 | name = Products; 83 | sourceTree = ""; 84 | }; 85 | BF7E51D51C3D509F00823F20 /* CaesarParser */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | BF7E51D61C3D509F00823F20 /* CaesarParser.h */, 89 | BF7E51F81C3D51CA00823F20 /* Build-In Support */, 90 | BF7E51F71C3D51C100823F20 /* Core */, 91 | BF7E51D81C3D509F00823F20 /* Info.plist */, 92 | ); 93 | path = CaesarParser; 94 | sourceTree = ""; 95 | }; 96 | BF7E51E11C3D509F00823F20 /* CaesarParserTests */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | BF7E51F91C3D520200823F20 /* JSONDeserializationTests.swift */, 100 | BF7E51FA1C3D520200823F20 /* JSONSerializationTests.swift */, 101 | BF7E51E41C3D509F00823F20 /* Info.plist */, 102 | ); 103 | path = CaesarParserTests; 104 | sourceTree = ""; 105 | }; 106 | BF7E51F71C3D51C100823F20 /* Core */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | BF7E51EF1C3D519E00823F20 /* JSONType.swift */, 110 | BF7E51ED1C3D519E00823F20 /* JSONDeserialization.swift */, 111 | BF7E51EE1C3D519E00823F20 /* JSONSerialization.swift */, 112 | ); 113 | name = Core; 114 | sourceTree = ""; 115 | }; 116 | BF7E51F81C3D51CA00823F20 /* Build-In Support */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | BF7E51F31C3D51BA00823F20 /* JSONConvertible.swift */, 120 | BF7E51F41C3D51BA00823F20 /* JSONSerializable.swift */, 121 | ); 122 | name = "Build-In Support"; 123 | sourceTree = ""; 124 | }; 125 | /* End PBXGroup section */ 126 | 127 | /* Begin PBXHeadersBuildPhase section */ 128 | BF7E51D01C3D509F00823F20 /* Headers */ = { 129 | isa = PBXHeadersBuildPhase; 130 | buildActionMask = 2147483647; 131 | files = ( 132 | BF7E51D71C3D509F00823F20 /* CaesarParser.h in Headers */, 133 | ); 134 | runOnlyForDeploymentPostprocessing = 0; 135 | }; 136 | /* End PBXHeadersBuildPhase section */ 137 | 138 | /* Begin PBXNativeTarget section */ 139 | BF7E51D21C3D509F00823F20 /* CaesarParser */ = { 140 | isa = PBXNativeTarget; 141 | buildConfigurationList = BF7E51E71C3D509F00823F20 /* Build configuration list for PBXNativeTarget "CaesarParser" */; 142 | buildPhases = ( 143 | BF7E51CE1C3D509F00823F20 /* Sources */, 144 | BF7E51CF1C3D509F00823F20 /* Frameworks */, 145 | BF7E51D01C3D509F00823F20 /* Headers */, 146 | BF7E51D11C3D509F00823F20 /* Resources */, 147 | ); 148 | buildRules = ( 149 | ); 150 | dependencies = ( 151 | ); 152 | name = CaesarParser; 153 | productName = CaesarParser; 154 | productReference = BF7E51D31C3D509F00823F20 /* CaesarParser.framework */; 155 | productType = "com.apple.product-type.framework"; 156 | }; 157 | BF7E51DC1C3D509F00823F20 /* CaesarParserTests */ = { 158 | isa = PBXNativeTarget; 159 | buildConfigurationList = BF7E51EA1C3D509F00823F20 /* Build configuration list for PBXNativeTarget "CaesarParserTests" */; 160 | buildPhases = ( 161 | BF7E51D91C3D509F00823F20 /* Sources */, 162 | BF7E51DA1C3D509F00823F20 /* Frameworks */, 163 | BF7E51DB1C3D509F00823F20 /* Resources */, 164 | ); 165 | buildRules = ( 166 | ); 167 | dependencies = ( 168 | BF7E51E01C3D509F00823F20 /* PBXTargetDependency */, 169 | ); 170 | name = CaesarParserTests; 171 | productName = CaesarParserTests; 172 | productReference = BF7E51DD1C3D509F00823F20 /* CaesarParserTests.xctest */; 173 | productType = "com.apple.product-type.bundle.unit-test"; 174 | }; 175 | /* End PBXNativeTarget section */ 176 | 177 | /* Begin PBXProject section */ 178 | BF7E51CA1C3D509F00823F20 /* Project object */ = { 179 | isa = PBXProject; 180 | attributes = { 181 | LastSwiftUpdateCheck = 0720; 182 | LastUpgradeCheck = 0720; 183 | ORGANIZATIONNAME = "Chenyu Lan"; 184 | TargetAttributes = { 185 | BF7E51D21C3D509F00823F20 = { 186 | CreatedOnToolsVersion = 7.2; 187 | LastSwiftMigration = 0800; 188 | }; 189 | BF7E51DC1C3D509F00823F20 = { 190 | CreatedOnToolsVersion = 7.2; 191 | LastSwiftMigration = 0800; 192 | }; 193 | }; 194 | }; 195 | buildConfigurationList = BF7E51CD1C3D509F00823F20 /* Build configuration list for PBXProject "CaesarParser" */; 196 | compatibilityVersion = "Xcode 3.2"; 197 | developmentRegion = English; 198 | hasScannedForEncodings = 0; 199 | knownRegions = ( 200 | en, 201 | ); 202 | mainGroup = BF7E51C91C3D509F00823F20; 203 | productRefGroup = BF7E51D41C3D509F00823F20 /* Products */; 204 | projectDirPath = ""; 205 | projectRoot = ""; 206 | targets = ( 207 | BF7E51D21C3D509F00823F20 /* CaesarParser */, 208 | BF7E51DC1C3D509F00823F20 /* CaesarParserTests */, 209 | ); 210 | }; 211 | /* End PBXProject section */ 212 | 213 | /* Begin PBXResourcesBuildPhase section */ 214 | BF7E51D11C3D509F00823F20 /* Resources */ = { 215 | isa = PBXResourcesBuildPhase; 216 | buildActionMask = 2147483647; 217 | files = ( 218 | ); 219 | runOnlyForDeploymentPostprocessing = 0; 220 | }; 221 | BF7E51DB1C3D509F00823F20 /* Resources */ = { 222 | isa = PBXResourcesBuildPhase; 223 | buildActionMask = 2147483647; 224 | files = ( 225 | ); 226 | runOnlyForDeploymentPostprocessing = 0; 227 | }; 228 | /* End PBXResourcesBuildPhase section */ 229 | 230 | /* Begin PBXSourcesBuildPhase section */ 231 | BF7E51CE1C3D509F00823F20 /* Sources */ = { 232 | isa = PBXSourcesBuildPhase; 233 | buildActionMask = 2147483647; 234 | files = ( 235 | BF7E51F11C3D519E00823F20 /* JSONSerialization.swift in Sources */, 236 | BF7E51F21C3D519E00823F20 /* JSONType.swift in Sources */, 237 | BF7E51F61C3D51BA00823F20 /* JSONSerializable.swift in Sources */, 238 | BF7E51F01C3D519E00823F20 /* JSONDeserialization.swift in Sources */, 239 | BF7E51F51C3D51BA00823F20 /* JSONConvertible.swift in Sources */, 240 | ); 241 | runOnlyForDeploymentPostprocessing = 0; 242 | }; 243 | BF7E51D91C3D509F00823F20 /* Sources */ = { 244 | isa = PBXSourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | BF7E51FC1C3D520200823F20 /* JSONSerializationTests.swift in Sources */, 248 | BF7E51FB1C3D520200823F20 /* JSONDeserializationTests.swift in Sources */, 249 | ); 250 | runOnlyForDeploymentPostprocessing = 0; 251 | }; 252 | /* End PBXSourcesBuildPhase section */ 253 | 254 | /* Begin PBXTargetDependency section */ 255 | BF7E51E01C3D509F00823F20 /* PBXTargetDependency */ = { 256 | isa = PBXTargetDependency; 257 | target = BF7E51D21C3D509F00823F20 /* CaesarParser */; 258 | targetProxy = BF7E51DF1C3D509F00823F20 /* PBXContainerItemProxy */; 259 | }; 260 | /* End PBXTargetDependency section */ 261 | 262 | /* Begin XCBuildConfiguration section */ 263 | BF7E51E51C3D509F00823F20 /* Debug */ = { 264 | isa = XCBuildConfiguration; 265 | buildSettings = { 266 | ALWAYS_SEARCH_USER_PATHS = NO; 267 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 268 | CLANG_CXX_LIBRARY = "libc++"; 269 | CLANG_ENABLE_MODULES = YES; 270 | CLANG_ENABLE_OBJC_ARC = YES; 271 | CLANG_WARN_BOOL_CONVERSION = YES; 272 | CLANG_WARN_CONSTANT_CONVERSION = YES; 273 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 274 | CLANG_WARN_EMPTY_BODY = YES; 275 | CLANG_WARN_ENUM_CONVERSION = YES; 276 | CLANG_WARN_INT_CONVERSION = YES; 277 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 278 | CLANG_WARN_UNREACHABLE_CODE = YES; 279 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 280 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 281 | COPY_PHASE_STRIP = NO; 282 | CURRENT_PROJECT_VERSION = 1; 283 | DEBUG_INFORMATION_FORMAT = dwarf; 284 | ENABLE_STRICT_OBJC_MSGSEND = YES; 285 | ENABLE_TESTABILITY = YES; 286 | GCC_C_LANGUAGE_STANDARD = gnu99; 287 | GCC_DYNAMIC_NO_PIC = NO; 288 | GCC_NO_COMMON_BLOCKS = YES; 289 | GCC_OPTIMIZATION_LEVEL = 0; 290 | GCC_PREPROCESSOR_DEFINITIONS = ( 291 | "DEBUG=1", 292 | "$(inherited)", 293 | ); 294 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 295 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 296 | GCC_WARN_UNDECLARED_SELECTOR = YES; 297 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 298 | GCC_WARN_UNUSED_FUNCTION = YES; 299 | GCC_WARN_UNUSED_VARIABLE = YES; 300 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 301 | MTL_ENABLE_DEBUG_INFO = YES; 302 | ONLY_ACTIVE_ARCH = YES; 303 | SDKROOT = iphoneos; 304 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 305 | TARGETED_DEVICE_FAMILY = "1,2"; 306 | VERSIONING_SYSTEM = "apple-generic"; 307 | VERSION_INFO_PREFIX = ""; 308 | }; 309 | name = Debug; 310 | }; 311 | BF7E51E61C3D509F00823F20 /* Release */ = { 312 | isa = XCBuildConfiguration; 313 | buildSettings = { 314 | ALWAYS_SEARCH_USER_PATHS = NO; 315 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 316 | CLANG_CXX_LIBRARY = "libc++"; 317 | CLANG_ENABLE_MODULES = YES; 318 | CLANG_ENABLE_OBJC_ARC = YES; 319 | CLANG_WARN_BOOL_CONVERSION = YES; 320 | CLANG_WARN_CONSTANT_CONVERSION = YES; 321 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 322 | CLANG_WARN_EMPTY_BODY = YES; 323 | CLANG_WARN_ENUM_CONVERSION = YES; 324 | CLANG_WARN_INT_CONVERSION = YES; 325 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 326 | CLANG_WARN_UNREACHABLE_CODE = YES; 327 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 328 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 329 | COPY_PHASE_STRIP = NO; 330 | CURRENT_PROJECT_VERSION = 1; 331 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 332 | ENABLE_NS_ASSERTIONS = NO; 333 | ENABLE_STRICT_OBJC_MSGSEND = YES; 334 | GCC_C_LANGUAGE_STANDARD = gnu99; 335 | GCC_NO_COMMON_BLOCKS = YES; 336 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 337 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 338 | GCC_WARN_UNDECLARED_SELECTOR = YES; 339 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 340 | GCC_WARN_UNUSED_FUNCTION = YES; 341 | GCC_WARN_UNUSED_VARIABLE = YES; 342 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 343 | MTL_ENABLE_DEBUG_INFO = NO; 344 | SDKROOT = iphoneos; 345 | TARGETED_DEVICE_FAMILY = "1,2"; 346 | VALIDATE_PRODUCT = YES; 347 | VERSIONING_SYSTEM = "apple-generic"; 348 | VERSION_INFO_PREFIX = ""; 349 | }; 350 | name = Release; 351 | }; 352 | BF7E51E81C3D509F00823F20 /* Debug */ = { 353 | isa = XCBuildConfiguration; 354 | buildSettings = { 355 | CLANG_ENABLE_MODULES = YES; 356 | DEFINES_MODULE = YES; 357 | DYLIB_COMPATIBILITY_VERSION = 1; 358 | DYLIB_CURRENT_VERSION = 1; 359 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 360 | INFOPLIST_FILE = CaesarParser/Info.plist; 361 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 362 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 363 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 364 | PRODUCT_BUNDLE_IDENTIFIER = com.gracelancy.CaesarParser; 365 | PRODUCT_NAME = "$(TARGET_NAME)"; 366 | SKIP_INSTALL = YES; 367 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 368 | SWIFT_VERSION = 2.3; 369 | }; 370 | name = Debug; 371 | }; 372 | BF7E51E91C3D509F00823F20 /* Release */ = { 373 | isa = XCBuildConfiguration; 374 | buildSettings = { 375 | CLANG_ENABLE_MODULES = YES; 376 | DEFINES_MODULE = YES; 377 | DYLIB_COMPATIBILITY_VERSION = 1; 378 | DYLIB_CURRENT_VERSION = 1; 379 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 380 | INFOPLIST_FILE = CaesarParser/Info.plist; 381 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 382 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 383 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 384 | PRODUCT_BUNDLE_IDENTIFIER = com.gracelancy.CaesarParser; 385 | PRODUCT_NAME = "$(TARGET_NAME)"; 386 | SKIP_INSTALL = YES; 387 | SWIFT_VERSION = 2.3; 388 | }; 389 | name = Release; 390 | }; 391 | BF7E51EB1C3D509F00823F20 /* Debug */ = { 392 | isa = XCBuildConfiguration; 393 | buildSettings = { 394 | INFOPLIST_FILE = CaesarParserTests/Info.plist; 395 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 396 | PRODUCT_BUNDLE_IDENTIFIER = com.gracelancy.CaesarParserTests; 397 | PRODUCT_NAME = "$(TARGET_NAME)"; 398 | SWIFT_VERSION = 2.3; 399 | }; 400 | name = Debug; 401 | }; 402 | BF7E51EC1C3D509F00823F20 /* Release */ = { 403 | isa = XCBuildConfiguration; 404 | buildSettings = { 405 | INFOPLIST_FILE = CaesarParserTests/Info.plist; 406 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 407 | PRODUCT_BUNDLE_IDENTIFIER = com.gracelancy.CaesarParserTests; 408 | PRODUCT_NAME = "$(TARGET_NAME)"; 409 | SWIFT_VERSION = 2.3; 410 | }; 411 | name = Release; 412 | }; 413 | /* End XCBuildConfiguration section */ 414 | 415 | /* Begin XCConfigurationList section */ 416 | BF7E51CD1C3D509F00823F20 /* Build configuration list for PBXProject "CaesarParser" */ = { 417 | isa = XCConfigurationList; 418 | buildConfigurations = ( 419 | BF7E51E51C3D509F00823F20 /* Debug */, 420 | BF7E51E61C3D509F00823F20 /* Release */, 421 | ); 422 | defaultConfigurationIsVisible = 0; 423 | defaultConfigurationName = Release; 424 | }; 425 | BF7E51E71C3D509F00823F20 /* Build configuration list for PBXNativeTarget "CaesarParser" */ = { 426 | isa = XCConfigurationList; 427 | buildConfigurations = ( 428 | BF7E51E81C3D509F00823F20 /* Debug */, 429 | BF7E51E91C3D509F00823F20 /* Release */, 430 | ); 431 | defaultConfigurationIsVisible = 0; 432 | defaultConfigurationName = Release; 433 | }; 434 | BF7E51EA1C3D509F00823F20 /* Build configuration list for PBXNativeTarget "CaesarParserTests" */ = { 435 | isa = XCConfigurationList; 436 | buildConfigurations = ( 437 | BF7E51EB1C3D509F00823F20 /* Debug */, 438 | BF7E51EC1C3D509F00823F20 /* Release */, 439 | ); 440 | defaultConfigurationIsVisible = 0; 441 | defaultConfigurationName = Release; 442 | }; 443 | /* End XCConfigurationList section */ 444 | }; 445 | rootObject = BF7E51CA1C3D509F00823F20 /* Project object */; 446 | } 447 | -------------------------------------------------------------------------------- /CaesarParser.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CaesarParser.xcodeproj/xcshareddata/xcschemes/CaesarParser.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /CaesarParser/CaesarParser.h: -------------------------------------------------------------------------------- 1 | // 2 | // CaesarParser.h 3 | // CaesarParser 4 | // 5 | // Created by lancy on 1/6/16. 6 | // Copyright © 2016 Chenyu Lan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for CaesarParser. 12 | FOUNDATION_EXPORT double CaesarParserVersionNumber; 13 | 14 | //! Project version string for CaesarParser. 15 | FOUNDATION_EXPORT const unsigned char CaesarParserVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /CaesarParser/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.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /CaesarParser/JSONConvertible.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JSONBuiltInConverter.swift 3 | // JSONHelper 4 | // 5 | // Created by Chenyu Lan on 5/15/15. 6 | // Copyright (c) 2015 Chenyu Lan. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // MARK: - Primitive Type 12 | 13 | extension Int: JSONConvertible { 14 | public static func convert(data: JSONObject) -> Int? { 15 | if let int = data as? Int { 16 | return int 17 | } else if let str = data as? String, int = Int(str) { 18 | return int 19 | } 20 | return nil 21 | } 22 | } 23 | 24 | extension String: JSONConvertible { 25 | public static func convert(data: JSONObject) -> String? { 26 | return data as? String 27 | } 28 | } 29 | 30 | extension Double: JSONConvertible { 31 | public static func convert(data: JSONObject) -> Double? { 32 | return data as? Double 33 | } 34 | } 35 | 36 | extension Bool: JSONConvertible { 37 | public static func convert(data: JSONObject) -> Bool? { 38 | return data as? Bool 39 | } 40 | } 41 | 42 | extension Float: JSONConvertible { 43 | public static func convert(data: JSONObject) -> Float? { 44 | return data as? Float 45 | } 46 | } 47 | 48 | 49 | // MARK: - URL 50 | 51 | extension NSURL: JSONConvertible { 52 | public static func convert(data: JSONObject) -> Self? { 53 | if let str = data as? String, url = self.init(string: str) { 54 | return url 55 | } 56 | return nil 57 | } 58 | } 59 | 60 | // MARK: - Date 61 | 62 | extension NSDate: JSONConvertible { 63 | public static func convert(data: JSONObject) -> Self? { 64 | if let timestamp = data as? Int { 65 | return self.init(timeIntervalSince1970: Double(timestamp)) 66 | } else if let timestamp = data as? Double { 67 | return self.init(timeIntervalSince1970: timestamp) 68 | } else if let timestamp = data as? NSNumber { 69 | return self.init(timeIntervalSince1970: timestamp.doubleValue) 70 | } 71 | return nil 72 | } 73 | } 74 | 75 | public func DateFormatConverter(dateFormat: String) -> (JSONObject) -> NSDate? { 76 | return { data in 77 | if let dateString = data as? String { 78 | let dateFormatter = NSDateFormatter() 79 | dateFormatter.dateFormat = dateFormat 80 | if let date = dateFormatter.dateFromString(dateString) { 81 | return date 82 | } 83 | } 84 | return nil 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /CaesarParser/JSONDeserialization.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JSONOperator.swift 3 | // JSONHelper 4 | // 5 | // Created by Chenyu Lan on 5/15/15. 6 | // Copyright (c) 2015 Chenyu Lan. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // MARK: - Protocol 12 | 13 | /// Use for Class, Nested Type 14 | public protocol JSONDeserializable { 15 | init(json: JSONDictionary) 16 | } 17 | 18 | /// Use for Primitive Type 19 | public protocol JSONConvertible { 20 | static func convert(json: JSONObject) -> Self? 21 | } 22 | 23 | // MARK: - Deserialization 24 | 25 | struct Deserialization { 26 | 27 | // MARK: - Utils 28 | 29 | /// Convert object to nil if is Null 30 | private static func convertToNilIfNull(object: JSONObject?) -> JSONObject? { 31 | return object is NSNull ? nil : object 32 | } 33 | 34 | // MARK: - JSONConvertible Type Deserialization 35 | 36 | static func convertAndAssign(inout property: T?, fromJSONObject jsonObject: JSONObject?) -> T? { 37 | if let data: JSONObject = convertToNilIfNull(jsonObject), convertedValue = T.convert(data) { 38 | property = convertedValue 39 | } else { 40 | property = nil 41 | } 42 | return property 43 | } 44 | 45 | static func convertAndAssign(inout property: T, fromJSONObject jsonObject: JSONObject?) -> T { 46 | var newValue: T? 47 | Deserialization.convertAndAssign(&newValue, fromJSONObject: jsonObject) 48 | if let newValue = newValue { property = newValue } 49 | return property 50 | } 51 | 52 | static func convertAndAssign(inout array: [T]?, fromJSONObject jsonObject: JSONObject?) -> [T]? { 53 | if let dataArray = convertToNilIfNull(jsonObject) as? [JSONObject] { 54 | array = [T]() 55 | for data in dataArray { 56 | if let property = T.convert(data) { 57 | array!.append(property) 58 | } 59 | } 60 | } else { 61 | array = nil 62 | } 63 | return array 64 | } 65 | 66 | static func convertAndAssign(inout array: [T], fromJSONObject jsonObject: JSONObject?) -> [T] { 67 | var newValue: [T]? 68 | Deserialization.convertAndAssign(&newValue, fromJSONObject: jsonObject) 69 | if let newValue = newValue { array = newValue } 70 | return array 71 | } 72 | 73 | // MARK: - Custom Type Deserialization 74 | 75 | static func convertAndAssign(inout instance: T?, fromJSONObject jsonObject: JSONObject?) -> T? { 76 | if let data = convertToNilIfNull(jsonObject) as? JSONDictionary { 77 | instance = T(json: data) 78 | } else { 79 | instance = nil 80 | } 81 | return instance 82 | } 83 | 84 | static func convertAndAssign(inout instance: T, fromJSONObject jsonObject: JSONObject?) -> T { 85 | var newValue: T? 86 | Deserialization.convertAndAssign(&newValue, fromJSONObject: jsonObject) 87 | if let newValue = newValue { instance = newValue } 88 | return instance 89 | } 90 | 91 | static func convertAndAssign(inout array: [T]?, fromJSONObject jsonObject: JSONObject?) -> [T]? { 92 | if let dataArray = convertToNilIfNull(jsonObject) as? [JSONDictionary] { 93 | array = [T]() 94 | for data in dataArray { 95 | array!.append(T(json: data)) 96 | } 97 | } else { 98 | array = nil 99 | } 100 | return array 101 | } 102 | 103 | static func convertAndAssign(inout array: [T], fromJSONObject jsonObject: JSONObject?) -> [T] { 104 | var newValue: [T]? 105 | Deserialization.convertAndAssign(&newValue, fromJSONObject: jsonObject) 106 | if let newArray = newValue { array = newArray } 107 | return array 108 | } 109 | 110 | // MARK: - Custom Value Converter 111 | 112 | static func convertAndAssign(inout property: T?, fromJSONObject bundle:(jsonObject: JSONObject?, converter: (JSONObject) -> T?)) -> T? { 113 | if let data: JSONObject = convertToNilIfNull(bundle.jsonObject), convertedValue = bundle.converter(data) { 114 | property = convertedValue 115 | } 116 | return property 117 | } 118 | 119 | static func convertAndAssign(inout property: T, fromJSONObject bundle:(jsonObject: JSONObject?, converter: (JSONObject) -> T?)) -> T { 120 | var newValue: T? 121 | Deserialization.convertAndAssign(&newValue, fromJSONObject: bundle) 122 | if let newValue = newValue { property = newValue } 123 | return property 124 | } 125 | 126 | // MARK: - Custom Map Deserialiazation 127 | 128 | static func convertAndAssign(inout map: [U: T]?, fromJSONObject jsonObject: JSONObject?) -> [U: T]? { 129 | if let dataMap = convertToNilIfNull(jsonObject) as? JSONDictionary { 130 | map = [U: T]() 131 | for (key, data) in dataMap { 132 | if let convertedKey = U.convert(key), convertedValue = T.convert(data) { 133 | map![convertedKey] = convertedValue 134 | } 135 | } 136 | } else { 137 | map = nil 138 | } 139 | return map 140 | } 141 | 142 | static func convertAndAssign(inout map: [U: T], fromJSONObject jsonObject: JSONObject?) -> [U: T] { 143 | var newValue: [U: T]? 144 | Deserialization.convertAndAssign(&newValue, fromJSONObject: jsonObject) 145 | if let newValue = newValue { map = newValue } 146 | return map 147 | } 148 | 149 | static func convertAndAssign(inout map: [U: T]?, fromJSONObject jsonObject: JSONObject?) -> [U: T]? { 150 | if let dataMap = convertToNilIfNull(jsonObject) as? [String: JSONDictionary] { 151 | map = [U: T]() 152 | for (key, data) in dataMap { 153 | if let convertedKey = U.convert(key) { 154 | map![convertedKey] = T(json: data) 155 | } 156 | } 157 | } else { 158 | map = nil 159 | } 160 | return map 161 | } 162 | 163 | static func convertAndAssign(inout map: [U: T], fromJSONObject jsonObject: JSONObject?) -> [U: T] { 164 | var newValue: [U: T]? 165 | Deserialization.convertAndAssign(&newValue, fromJSONObject: jsonObject) 166 | if let newValue = newValue { map = newValue } 167 | return map 168 | } 169 | 170 | // MARK: - Raw Value Representable (Enum) Deserialization 171 | 172 | static func convertAndAssign(inout property: T?, fromJSONObject jsonObject: JSONObject?) -> T? { 173 | var newEnumValue: T? 174 | var newRawEnumValue: T.RawValue? 175 | Deserialization.convertAndAssign(&newRawEnumValue, fromJSONObject: jsonObject) 176 | if let unwrappedNewRawEnumValue = newRawEnumValue { 177 | if let enumValue = T(rawValue: unwrappedNewRawEnumValue) { 178 | newEnumValue = enumValue 179 | } 180 | } 181 | property = newEnumValue 182 | return property 183 | } 184 | 185 | static func convertAndAssign(inout property: T, fromJSONObject jsonObject: JSONObject?) -> T { 186 | var newValue: T? 187 | Deserialization.convertAndAssign(&newValue, fromJSONObject: jsonObject) 188 | if let newValue = newValue { property = newValue } 189 | return property 190 | } 191 | 192 | static func convertAndAssign(inout array: [T]?, fromJSONObject jsonObject: JSONObject?) -> [T]? { 193 | if let dataArray = convertToNilIfNull(jsonObject) as? [JSONObject] { 194 | array = [T]() 195 | for data in dataArray { 196 | var newValue: T? 197 | Deserialization.convertAndAssign(&newValue, fromJSONObject: data) 198 | if let newValue = newValue { array!.append(newValue) } 199 | } 200 | } else { 201 | array = nil 202 | } 203 | return array 204 | } 205 | 206 | static func convertAndAssign(inout array: [T], fromJSONObject jsonObject: JSONObject?) -> [T] { 207 | var newValue: [T]? 208 | Deserialization.convertAndAssign(&newValue, fromJSONObject: jsonObject) 209 | if let newArray = newValue { array = newArray } 210 | return array 211 | } 212 | 213 | } 214 | 215 | // MARK: - Operator for use in deserialization operations. 216 | 217 | infix operator <-- { associativity right precedence 150 } 218 | 219 | // MARK: - JSONConvertible Type Deserialization 220 | 221 | public func <-- (inout property: T?, jsonObject: JSONObject?) -> T? { 222 | return Deserialization.convertAndAssign(&property, fromJSONObject: jsonObject) 223 | } 224 | 225 | public func <-- (inout property: T, jsonObject: JSONObject?) -> T { 226 | return Deserialization.convertAndAssign(&property, fromJSONObject: jsonObject) 227 | } 228 | 229 | public func <-- (inout array: [T]?, jsonObject: JSONObject?) -> [T]? { 230 | return Deserialization.convertAndAssign(&array, fromJSONObject: jsonObject) 231 | } 232 | 233 | public func <-- (inout array: [T], jsonObject: JSONObject?) -> [T] { 234 | return Deserialization.convertAndAssign(&array, fromJSONObject: jsonObject) 235 | } 236 | 237 | // MARK: - Custom Type Deserialization 238 | 239 | public func <-- (inout instance: T?, jsonObject: JSONObject?) -> T? { 240 | return Deserialization.convertAndAssign(&instance, fromJSONObject: jsonObject) 241 | } 242 | 243 | public func <-- (inout instance: T, jsonObject: JSONObject?) -> T { 244 | return Deserialization.convertAndAssign(&instance, fromJSONObject: jsonObject) 245 | } 246 | 247 | public func <-- (inout array: [T]?, jsonObject: JSONObject?) -> [T]? { 248 | return Deserialization.convertAndAssign(&array, fromJSONObject: jsonObject) 249 | } 250 | 251 | public func <-- (inout array: [T], jsonObject: JSONObject?) -> [T] { 252 | return Deserialization.convertAndAssign(&array, fromJSONObject: jsonObject) 253 | } 254 | 255 | // MARK: - Custom Value Converter 256 | 257 | public func <-- (inout property: T?, bundle:(jsonObject: JSONObject?, converter: (JSONObject) -> T?)) -> T? { 258 | return Deserialization.convertAndAssign(&property, fromJSONObject: bundle) 259 | } 260 | 261 | public func <-- (inout property: T, bundle:(jsonObject: JSONObject?, converter: (JSONObject) -> T?)) -> T { 262 | return Deserialization.convertAndAssign(&property, fromJSONObject: bundle) 263 | } 264 | 265 | // MARK: - Custom Map Deserialiazation 266 | 267 | public func <-- (inout map: [U: T]?, jsonObject: JSONObject?) -> [U: T]? { 268 | return Deserialization.convertAndAssign(&map, fromJSONObject: jsonObject) 269 | } 270 | 271 | public func <-- (inout map: [U: T], jsonObject: JSONObject?) -> [U: T] { 272 | return Deserialization.convertAndAssign(&map, fromJSONObject: jsonObject) 273 | } 274 | 275 | public func <-- (inout map: [U: T]?, jsonObject: JSONObject?) -> [U: T]? { 276 | return Deserialization.convertAndAssign(&map, fromJSONObject: jsonObject) 277 | } 278 | 279 | public func <-- (inout map: [U: T], jsonObject: JSONObject?) -> [U: T] { 280 | return Deserialization.convertAndAssign(&map, fromJSONObject: jsonObject) 281 | } 282 | 283 | // MARK: - Raw Value Representable (Enum) Deserialization 284 | 285 | public func <-- (inout property: T?, jsonObject: JSONObject?) -> T? { 286 | return Deserialization.convertAndAssign(&property, fromJSONObject: jsonObject) 287 | } 288 | 289 | public func <-- (inout property: T, jsonObject: JSONObject?) -> T { 290 | return Deserialization.convertAndAssign(&property, fromJSONObject: jsonObject) 291 | } 292 | 293 | public func <-- (inout array: [T]?, jsonObject: JSONObject?) -> [T]? { 294 | return Deserialization.convertAndAssign(&array, fromJSONObject: jsonObject) 295 | } 296 | 297 | public func <-- (inout array: [T], jsonObject: JSONObject?) -> [T] { 298 | return Deserialization.convertAndAssign(&array, fromJSONObject: jsonObject) 299 | } 300 | -------------------------------------------------------------------------------- /CaesarParser/JSONSerializable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JSONSerializable.swift 3 | // Caesar 4 | // 5 | // Created by lancy on 5/17/15. 6 | // Copyright (c) 2015 Chenyu Lan. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | extension Int: JSONSerializable { 13 | public func toJSONObject() -> JSONObject { 14 | return self 15 | } 16 | } 17 | 18 | extension String: JSONSerializable { 19 | public func toJSONObject() -> JSONObject { 20 | return self 21 | } 22 | } 23 | 24 | extension Double: JSONSerializable { 25 | public func toJSONObject() -> JSONObject { 26 | return self 27 | } 28 | } 29 | 30 | 31 | extension Float: JSONSerializable { 32 | public func toJSONObject() -> JSONObject { 33 | return self 34 | } 35 | } 36 | 37 | extension Bool: JSONSerializable { 38 | public func toJSONObject() -> JSONObject { 39 | return self 40 | } 41 | } 42 | 43 | extension String: CustomStringConvertible { 44 | public var description: String { 45 | return self 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /CaesarParser/JSONSerialization.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JSONSerialization.swift 3 | // Caesar 4 | // 5 | // Created by lancy on 5/17/15. 6 | // Copyright (c) 2015 Chenyu Lan. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // MARK: - Protocol 12 | 13 | /// convert to JSON object 14 | public protocol JSONSerializable { 15 | func toJSONObject() -> JSONObject 16 | } 17 | 18 | // MARK: - Serialization 19 | 20 | struct Serialization { 21 | 22 | // MARK: - General Type Serialization 23 | 24 | static func convertAndAssign(property: T?, inout toJSONObject jsonObject: JSONObject?) -> JSONObject? { 25 | if let property = property { 26 | jsonObject = property.toJSONObject() 27 | } 28 | return jsonObject 29 | } 30 | 31 | // MARK: - Array Serialization 32 | 33 | static func convertAndAssign(properties: [T]?, inout toJSONObject jsonObject: JSONObject?) -> JSONObject? { 34 | if let properties = properties { 35 | jsonObject = properties.map { p in p.toJSONObject() } 36 | } 37 | return jsonObject 38 | } 39 | 40 | // MARK: - Map Serialization 41 | 42 | static func convertAndAssign(map: [U: T]?, inout toJSONObject jsonObject: JSONObject?) -> JSONObject? { 43 | if let jsonMap = map { 44 | var json = JSONDictionary() 45 | for (key, value) in jsonMap { 46 | json[key.description] = value.toJSONObject() 47 | } 48 | jsonObject = json 49 | } 50 | return jsonObject 51 | } 52 | 53 | // MARK: - Raw Representable (Enum) Serialization 54 | 55 | static func convertAndAssign(property: T?, inout toJSONObject value: JSONObject?) -> JSONObject? { 56 | if let jsonValue: JSONObject = property?.rawValue.toJSONObject() { 57 | value = jsonValue 58 | } 59 | return value 60 | } 61 | 62 | static func convertAndAssign(properties: [T]?, inout toJSONObject jsonObject: JSONObject?) -> JSONObject? { 63 | if let properties = properties { 64 | jsonObject = properties.map { p in p.rawValue.toJSONObject() } 65 | } 66 | return jsonObject 67 | } 68 | 69 | } 70 | 71 | // MARK: - Operator for use in serialization operations. 72 | 73 | infix operator --> { associativity right precedence 150 } 74 | 75 | public func --> (property: T?, inout jsonObject: JSONObject?) -> JSONObject? { 76 | return Serialization.convertAndAssign(property, toJSONObject: &jsonObject) 77 | } 78 | 79 | public func --> (properties: [T]?, inout jsonObject: JSONObject?) -> JSONObject? { 80 | return Serialization.convertAndAssign(properties, toJSONObject: &jsonObject) 81 | } 82 | 83 | public func --> (map: [U: T]?, inout jsonObject: JSONObject?) -> JSONObject? { 84 | return Serialization.convertAndAssign(map, toJSONObject: &jsonObject) 85 | } 86 | 87 | public func --> (property: T?, inout jsonObject: JSONObject?) -> JSONObject? { 88 | return Serialization.convertAndAssign(property, toJSONObject: &jsonObject) 89 | } 90 | 91 | public func --> (property: [T]?, inout jsonObject: JSONObject?) -> JSONObject? { 92 | return Serialization.convertAndAssign(property, toJSONObject: &jsonObject) 93 | } 94 | -------------------------------------------------------------------------------- /CaesarParser/JSONType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JSONType.swift 3 | // JSONHelper 4 | // 5 | // Created by Chenyu Lan on 5/15/15. 6 | // Copyright (c) 2015 Chenyu Lan. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// A type of dictionary that only uses strings for keys and can contain any 12 | /// type of object as a value. 13 | public typealias JSONDictionary = [String: JSONObject] 14 | 15 | /// A type of any object 16 | public typealias JSONObject = AnyObject 17 | 18 | // MARK: - Deprecated 19 | 20 | @available(*, unavailable, renamed="JSONDeserializable") 21 | typealias Deserializable = JSONDeserializable 22 | 23 | @available(*, unavailable, renamed="JSONConvertible") 24 | typealias Convertible = JSONConvertible 25 | 26 | @available(*, unavailable, renamed="JSONSerializable") 27 | typealias Serializable = JSONSerializable 28 | -------------------------------------------------------------------------------- /CaesarParserTests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /CaesarParserTests/JSONDeserializationTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CaesarParserTests.swift 3 | // CaesarParserTests 4 | // 5 | // Created by lancy on 5/17/15. 6 | // Copyright (c) 2015 Chenyu Lan. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XCTest 11 | import CaesarParser 12 | 13 | class JSONDeserializationTests: XCTestCase { 14 | 15 | func JSONStringToJSONObject(jsonString: String) -> JSONObject? { 16 | let data: NSData = jsonString.dataUsingEncoding(NSUTF8StringEncoding)! 17 | return try? NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(rawValue: 0)) 18 | } 19 | 20 | let dummyResponse = [ 21 | "string": "a", 22 | "int": 1, 23 | "int_string": "1", 24 | "bool": true, 25 | "date": "2014-09-19", 26 | "url": "http://github.com/", 27 | "stringArray": ["a", "b", "c"], 28 | "intArray": [1, 2, 3, 4, 5], 29 | "boolArray": [true, false], 30 | "instance": [ 31 | "name": "b" 32 | ], 33 | "instanceArray": [ 34 | [ 35 | "name": "c" 36 | ], [ 37 | "name": "d" 38 | ] 39 | ], 40 | "instanceMap": [ 41 | "ePerson": [ 42 | "name": "e" 43 | ], 44 | "fPerson": [ 45 | "name": "f" 46 | ] 47 | ] 48 | ] 49 | 50 | struct Person: JSONDeserializable { 51 | var name = "" 52 | 53 | init(json: JSONDictionary) { 54 | name <-- json["name"] 55 | } 56 | 57 | init() {} 58 | } 59 | 60 | enum EnumTest: Int { 61 | case Zero = 0 62 | case One = 1 63 | } 64 | 65 | func testOptionalString() { 66 | var property: String? 67 | property <-- dummyResponse["string"] 68 | XCTAssertEqual(property!, "a", "String? property should equal 'a'") 69 | property <-- dummyResponse["invalidKey"] 70 | XCTAssertNil(property, "String? property should equal nil after invalid assignment") 71 | } 72 | 73 | func testString() { 74 | var property = "b" 75 | property <-- dummyResponse["invalidKey"] 76 | XCTAssertEqual(property, "b", "String property should have the default value 'b'") 77 | property <-- dummyResponse["string"] 78 | XCTAssertEqual(property, "a", "String property should equal 'a'") 79 | } 80 | 81 | func testOptionalInt() { 82 | var property: Int? 83 | property <-- dummyResponse["int"] 84 | XCTAssertEqual(property!, 1, "Int? property should equal 1") 85 | property <-- dummyResponse["invalidKey"] 86 | XCTAssertNil(property, "Int? property should equal nil after invalid assignment") 87 | } 88 | 89 | func testInt() { 90 | var property = 2 91 | property <-- dummyResponse["invalidKey"] 92 | XCTAssertEqual(property, 2, "Int property should have the default value 2") 93 | property <-- dummyResponse["int"] 94 | XCTAssertEqual(property, 1, "Int property should equal 1") 95 | } 96 | 97 | func testStringToOptionalInt() { 98 | var number: Int? 99 | number <-- dummyResponse["int_string"] 100 | XCTAssertEqual(number!, 1, "Strings containing numbers should successfully deserialize into optional Ints.") 101 | } 102 | 103 | func testStringToInt() { 104 | var number = 0 105 | number <-- dummyResponse["int_string"] 106 | XCTAssertEqual(number, 1, "Strings containing numbers should successfully deserialize into Ints.") 107 | } 108 | 109 | func testOptionalBool() { 110 | var property: Bool? 111 | property <-- dummyResponse["bool"] 112 | XCTAssertEqual(property!, true, "Bool? property should equal true") 113 | property <-- dummyResponse["invalidKey"] 114 | XCTAssertNil(property, "Bool? property should equal nil after invalid assignment") 115 | } 116 | 117 | func testBool() { 118 | var property = true 119 | property <-- dummyResponse["invalidKey"] 120 | XCTAssertEqual(property, true, "Bool property should have the default value true") 121 | property <-- dummyResponse["bool"] 122 | XCTAssertEqual(property, true, "Bool property should equal true") 123 | } 124 | 125 | func testOptionalNSDate() { 126 | var property: NSDate? 127 | property <-- (dummyResponse["date"], DateFormatConverter("yyyy-MM-dd")) 128 | let dateFormatter = NSDateFormatter() 129 | dateFormatter.dateFormat = "yyyy-MM-dd" 130 | let testDate = dateFormatter.dateFromString("2014-09-19") 131 | XCTAssertEqual(property!.compare(testDate!), NSComparisonResult.OrderedSame, "NSDate? property should equal 2014-09-19") 132 | property <-- dummyResponse["invalidKey"] 133 | XCTAssertNil(property, "NSDate? property should equal nil after invalid assignment") 134 | } 135 | 136 | func testNSDate() { 137 | let dateFormatter = NSDateFormatter() 138 | dateFormatter.dateFormat = "yyyy-MM-dd" 139 | let defaultTestDate = dateFormatter.dateFromString("2015-09-19") 140 | var property = defaultTestDate! 141 | property <-- (dummyResponse["invalidKey"], DateFormatConverter("yyyy-MM-dd")) 142 | XCTAssertEqual(property.compare(defaultTestDate!), NSComparisonResult.OrderedSame, "NSDate should have the default value 2015-09-19") 143 | property <-- (dummyResponse["date"], DateFormatConverter("yyyy-MM-dd")) 144 | let testDate = dateFormatter.dateFromString("2014-09-19") 145 | XCTAssertEqual(property.compare(testDate!), NSComparisonResult.OrderedSame, "NSDate should have the value 2015-09-19") 146 | } 147 | 148 | func testOptionalNSURL() { 149 | var property: NSURL? 150 | property <-- dummyResponse["url"] 151 | XCTAssertEqual(property!.host!, "github.com", "NSURL? property should equal github.com") 152 | property <-- dummyResponse["invalidKey"] 153 | XCTAssertNil(property, "NSURL? property should equal nil after invalid assignment") 154 | } 155 | 156 | func testNSURL() { 157 | var property = NSURL(string: "http://google.com")! 158 | property <-- dummyResponse["invalidKey"] 159 | XCTAssertEqual(property.host!, "google.com", "NSURL should have the default value google.com") 160 | property <-- dummyResponse["url"] 161 | XCTAssertEqual(property.host!, "github.com", "NSURL should have the value github.com") 162 | } 163 | 164 | func testStringArray() { 165 | var property = [String]() 166 | property <-- dummyResponse["stringArray"] 167 | XCTAssertEqual(property.count, 3, "[String] property should have 3 members") 168 | } 169 | 170 | func testIntArray() { 171 | var property = [Int]() 172 | property <-- dummyResponse["intArray"] 173 | XCTAssertEqual(property.count, 5, "[Int] property should have 5 members") 174 | } 175 | 176 | func testBoolArray() { 177 | var property = [Bool]() 178 | property <-- dummyResponse["boolArray"] 179 | XCTAssertEqual(property.count, 2, "[Bool] property should have 2 members") 180 | } 181 | 182 | func testInstance() { 183 | var instance = Person() 184 | instance <-- dummyResponse["instance"] 185 | XCTAssertEqual(instance.name, "b", "Person instance's name property should equal 'b'") 186 | } 187 | 188 | func testInstanceArray() { 189 | var property = [Person]() 190 | property <-- dummyResponse["instanceArray"] 191 | XCTAssertEqual(property.count, 2, "[Person] property should have 2 members") 192 | } 193 | 194 | func testInstanceMap() { 195 | var property = [String:Person]() 196 | property <-- dummyResponse["instanceMap"] 197 | XCTAssertEqual(property["ePerson"]!.name, "e", "member \"ePerson\" of [String:Person] property should have \"e\" for name") 198 | } 199 | 200 | func testRawValueEnum() { 201 | var property = EnumTest.Zero 202 | property <-- dummyResponse["int"] 203 | XCTAssertEqual(property, EnumTest.One, "EnumTest should be equal to .One") 204 | } 205 | 206 | func testRawValueEnumArray() { 207 | var property: [EnumTest]? 208 | property <-- dummyResponse["intArray"] 209 | XCTAssertEqual(property?.count ?? 0, 1, "[EnumTest] property should have 1 member") 210 | } 211 | 212 | func testJSONStringArrayParsing() { 213 | let jsonString = "[{\"name\": \"I am \"},{\"name\": \"Groot!\"}]" 214 | let jsonObject: JSONObject? = JSONStringToJSONObject(jsonString) 215 | var people = [Person]() 216 | var areYouGroot = "" 217 | 218 | people <-- jsonObject 219 | 220 | for person in people { 221 | areYouGroot += person.name 222 | } 223 | 224 | XCTAssertEqual(areYouGroot, "I am Groot!", "Groot should be Groot") 225 | } 226 | 227 | func testJSONStringMapParsing() { 228 | let jsonString = "{\"person one\": {\"name\": \"I am \"}, \"person two\": {\"name\": \"Groot!\"}}" 229 | let jsonObject: JSONObject? = JSONStringToJSONObject(jsonString) 230 | var people = [String:Person]() 231 | var areYouGroot = "" 232 | var keys = "" 233 | 234 | people <-- jsonObject 235 | 236 | for (personKey, person) in people { 237 | areYouGroot += person.name 238 | keys += personKey 239 | } 240 | 241 | XCTAssertEqual(keys, "person oneperson two", "keys should be correctly picked up") 242 | XCTAssertEqual(areYouGroot, "I am Groot!", "Groot should be Groot") 243 | } 244 | 245 | func testJSONIntObjectMap() { 246 | let jsonString = "{\"1\": {\"name\": \"Grace\"}, \"2\": {\"name\": \"Lancy\"}}" 247 | let jsonObject: JSONObject? = JSONStringToJSONObject(jsonString) 248 | var people = [Int: Person]() 249 | 250 | people <-- jsonObject 251 | 252 | XCTAssertEqual(people[1]!.name, "Grace", "people[1] should be Grace") 253 | XCTAssertEqual(people[2]!.name, "Lancy", "people[2] should be Lancy") 254 | } 255 | 256 | func testJSONIntIntMap() { 257 | let jsonString = "{\"1\": 1, \"2\": 2}" 258 | let jsonObject: JSONObject? = JSONStringToJSONObject(jsonString) 259 | var dict = [Int: Int]() 260 | 261 | dict <-- jsonObject 262 | 263 | XCTAssertEqual(dict[1]!, 1, "dict[1] should be 1") 264 | XCTAssertEqual(dict[2]!, 2, "dict[2] should be 2") 265 | } 266 | 267 | } -------------------------------------------------------------------------------- /CaesarParserTests/JSONSerializationTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JSONSerializationTests.swift 3 | // Caesar 4 | // 5 | // Created by lancy on 5/17/15. 6 | // Copyright (c) 2015 Chenyu Lan. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XCTest 11 | import CaesarParser 12 | 13 | 14 | class JSONSerializationTests: XCTestCase { 15 | enum Gender: Int { 16 | case Unknown = 0 17 | case Male = 1 18 | case Female = 2 19 | } 20 | 21 | class Person: JSONSerializable { 22 | var name = "" 23 | var age = 0 24 | var birthday: Double = 0.0 25 | var weight: Float = 0.0 26 | var adult = false 27 | var gender = Gender.Unknown 28 | var girlFriend: Person? 29 | var friends = [Person]() 30 | var luckyNumbers = [Int]() 31 | var favouredSingers = [String: Person]() 32 | var vips = [Int: Person]() 33 | var preferNumbers = [Int: Int]() 34 | var orientation = [Gender]() 35 | 36 | func toJSONObject() -> JSONObject { 37 | var json = JSONDictionary() 38 | 39 | name --> json["name"] 40 | age --> json["age"] 41 | birthday --> json["birthday"] 42 | weight --> json["weight"] 43 | adult --> json["adult"] 44 | gender --> json["gender"] 45 | girlFriend --> json["girlFriend"] 46 | friends --> json["friends"] 47 | luckyNumbers --> json["luckyNumbers"] 48 | favouredSingers --> json["favouredSingers"] 49 | vips --> json["vips"] 50 | preferNumbers --> json["preferNumbers"] 51 | orientation --> json["orientation"] 52 | 53 | return json 54 | } 55 | 56 | init() {} 57 | 58 | init(name: String) { 59 | self.name = name 60 | } 61 | } 62 | 63 | func testPrimitiveType() { 64 | let person = Person(name: "lancy") 65 | person.age = 23 66 | person.birthday = 14 67 | person.weight = 60 68 | person.adult = true 69 | 70 | if let dict = person.toJSONObject() as? JSONDictionary { 71 | XCTAssertEqual((dict["name"] as! String), "lancy", "my name is lancy") 72 | XCTAssertEqual((dict["age"] as! Int), 23, "I'm 23") 73 | XCTAssertEqual((dict["birthday"] as! Double), 14, "my birthday is 14") 74 | XCTAssertEqual((dict["weight"] as! Float), 60, "weight 60!") 75 | XCTAssertEqual((dict["adult"] as! Bool), true, "i'm an adult") 76 | } else { 77 | XCTFail("JSON Object should be a dictionary") 78 | } 79 | } 80 | 81 | func testEnumType() { 82 | let person = Person(name: "God") 83 | person.gender = .Female 84 | if let dict = person.toJSONObject() as? JSONDictionary { 85 | XCTAssertEqual((dict["gender"] as! Int), Gender.Female.rawValue, "God is a girl") 86 | } else { 87 | XCTFail("JSON Object of Person should be a dictionary") 88 | } 89 | } 90 | 91 | func testEnumTypeArray() { 92 | let person = Person(name: "siri") 93 | person.orientation = [.Male, .Female, .Unknown] 94 | if let dict = person.toJSONObject() as? JSONDictionary { 95 | XCTAssertEqual((dict["name"] as! String), "siri", "my name is siri") 96 | if let orientation = dict["orientation"] as? [Int] { 97 | XCTAssertEqual(orientation[0], Gender.Male.rawValue, "siri likes male!") 98 | XCTAssertEqual(orientation[1], Gender.Female.rawValue, "siri also likes female!") 99 | XCTAssertEqual(orientation[2], Gender.Unknown.rawValue, "and siri likes all others!") 100 | } else { 101 | XCTFail("JSON Object of orientation should be a [Int]") 102 | } 103 | } else { 104 | XCTFail("JSON Object of Person should be a dictionary") 105 | } 106 | } 107 | 108 | func testNestedType() { 109 | let person = Person(name: "lancy") 110 | let girl = Person(name: "grace") 111 | person.girlFriend = girl 112 | 113 | if let dict = person.toJSONObject() as? JSONDictionary { 114 | XCTAssertEqual((dict["name"] as! String), "lancy", "my name is lancy") 115 | if let girlDict = dict["girlFriend"] as? JSONDictionary { 116 | XCTAssertEqual((girlDict["name"] as! String), "grace", "my girl is grace") 117 | } else { 118 | XCTFail("JSON Object of girl friend should be a dictionary") 119 | } 120 | } else { 121 | XCTFail("JSON Object of Person should be a dictionary") 122 | } 123 | } 124 | 125 | func testObjectArray() { 126 | let person = Person(name: "lancy") 127 | let friend1 = Person(name: "grace") 128 | let friend2 = Person(name: "cambi") 129 | person.friends = [friend1, friend2] 130 | 131 | if let dict = person.toJSONObject() as? JSONDictionary { 132 | XCTAssertEqual((dict["name"] as! String), "lancy", "my name is lancy") 133 | if let friends = dict["friends"] as? [JSONDictionary] { 134 | XCTAssertEqual((friends[0]["name"] as! String), "grace", "grace is my friend") 135 | XCTAssertEqual((friends[1]["name"] as! String), "cambi", "cambi is my friend") 136 | } else { 137 | XCTFail("JSON Object of friends friend should be a [JSONDictionary]") 138 | } 139 | } else { 140 | XCTFail("JSON Object of Person should be a dictionary") 141 | } 142 | } 143 | 144 | func testIntArray() { 145 | let person = Person(name: "lancy") 146 | person.luckyNumbers = [8, 14, 55] 147 | 148 | if let dict = person.toJSONObject() as? JSONDictionary { 149 | XCTAssertEqual((dict["name"] as! String), "lancy", "my name is lancy") 150 | if let friends = dict["luckyNumbers"] as? [Int] { 151 | XCTAssertEqual(friends[0], 8, "lucky 8!") 152 | XCTAssertEqual(friends[1], 14, "lucky 14!") 153 | XCTAssertEqual(friends[2], 55, "lucky 55! Give me!") 154 | } else { 155 | XCTFail("JSON Object of friends friend should be a [Int]") 156 | } 157 | } else { 158 | XCTFail("JSON Object of Person should be a dictionary") 159 | } 160 | } 161 | 162 | func testStringObjectMap() { 163 | let person = Person(name: "lancy") 164 | person.favouredSingers = [ 165 | "first": Person(name: "sia"), 166 | "second": Person(name: "lana") 167 | ] 168 | 169 | if let dict = person.toJSONObject() as? JSONDictionary { 170 | XCTAssertEqual((dict["name"] as! String), "lancy", "my name is lancy") 171 | if let singers = dict["favouredSingers"] as? JSONDictionary { 172 | XCTAssertEqual(((singers["first"] as! JSONDictionary)["name"] as! String), "sia", "sia the best!") 173 | XCTAssertEqual(((singers["second"] as! JSONDictionary)["name"] as! String), "lana", "lana go lana!") 174 | } else { 175 | XCTFail("JSON Object of friends friend should be a JSON dictionary") 176 | } 177 | } else { 178 | XCTFail("JSON Object of Person should be a dictionary") 179 | } 180 | } 181 | 182 | func testIntObjectMap() { 183 | let person = Person(name: "lancy") 184 | person.vips = [ 185 | 0: Person(name: "lover and family"), 186 | 1: Person(name: "best friends"), 187 | 2: Person(name: "maybe boss") 188 | ] 189 | 190 | if let dict = person.toJSONObject() as? JSONDictionary { 191 | XCTAssertEqual((dict["name"] as! String), "lancy", "my name is lancy") 192 | if let persons = dict["vips"] as? JSONDictionary { 193 | XCTAssertEqual(((persons["0"] as! JSONDictionary)["name"] as! String), "lover and family", "My love My Life! Very Importance!") 194 | XCTAssertEqual(((persons["1"] as! JSONDictionary)["name"] as! String), "best friends", "BFF!") 195 | XCTAssertEqual(((persons["2"] as! JSONDictionary)["name"] as! String), "maybe boss", "Please raise the pay...") 196 | 197 | } else { 198 | XCTFail("JSON Object of friends friend should be a JSON dictionary") 199 | } 200 | } else { 201 | XCTFail("JSON Object of Person should be a dictionary") 202 | } 203 | } 204 | 205 | func testIntIntMap() { 206 | let person = Person(name: "lancy") 207 | person.preferNumbers = [ 208 | 0: 1, 209 | 1: 2, 210 | 2: 4, 211 | 3: 8, 212 | 4: 16, 213 | 5: 32, 214 | 6: 64 215 | ] 216 | 217 | if let dict = person.toJSONObject() as? JSONDictionary { 218 | XCTAssertEqual((dict["name"] as! String), "lancy", "my name is lancy") 219 | if let singers = dict["preferNumbers"] as? JSONDictionary { 220 | XCTAssertEqual((singers["0"] as! Int), 1, "1") 221 | XCTAssertEqual((singers["1"] as! Int), 2, "2") 222 | XCTAssertEqual((singers["2"] as! Int), 4, "4") 223 | XCTAssertEqual((singers["3"] as! Int), 8, "8") 224 | XCTAssertEqual((singers["4"] as! Int), 16, "16") 225 | XCTAssertEqual((singers["5"] as! Int), 32, "32") 226 | XCTAssertEqual((singers["6"] as! Int), 64, "64") 227 | } else { 228 | XCTFail("JSON Object of friends friend should be a [JSONDictionary]") 229 | } 230 | } else { 231 | XCTFail("JSON Object of Person should be a dictionary") 232 | } 233 | 234 | } 235 | 236 | } 237 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Lancy 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 | # CaesarParser 2 | 3 | [![Build 4 | Status](https://travis-ci.org/lancy/CaesarParser.svg?branch=master)](https://travis-ci.org/lancy/CaesarParser) 5 | 6 | CaesarParser is a framework written in Swift for you to parse Model from JSON or to JSON. 7 | 8 | ## Features 9 | 10 | * JSON deserialization, parse JSON to Model 11 | * JSON serialization, parse Model to JSON 12 | * Support nested class, stand along, in arrays or in dictionaries 13 | * Custom converter during parsing 14 | * Support struct, primitive type, raw representable enum 15 | 16 | ## Requirements 17 | 18 | Cocoa Touch Framework requires iOS 8 or later. 19 | 20 | Manual add CaesarParser to your project requires iOS 7 or later. 21 | 22 | ## Installation 23 | 24 | ###[Carthage](https://github.com/Carthage/Carthage#installing-carthage) 25 | 26 | Add the following line to your [Cartfile](https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md#cartfile). 27 | 28 | ``` 29 | github "lancy/CaesarParser" 30 | ``` 31 | 32 | Then do `carthage update`. After that, add the framework to your project. 33 | 34 | ###[Cocoapods](https://github.com/CocoaPods/CocoaPods) 35 | 36 | Add the following line in your `Podfile`. 37 | 38 | ``` 39 | pod "CaesarParser", :git => 'https://github.com/lancy/CaesarParser.git' 40 | ``` 41 | 42 | ## Basic Usages 43 | 44 | Any type that confirm `JSONDeserializable` or `JSONConvertible` protocol can be parse. Besides you can use custom value converter during parsing. 45 | 46 | ```swift 47 | /// Use for Class, Nested Type 48 | public protocol JSONDeserializable { 49 | init(json: JSONDictionary) 50 | } 51 | 52 | /// Use for Primitive Type 53 | public protocol JSONConvertible { 54 | static func convert(json: JSONObject) -> Self? 55 | } 56 | ``` 57 | 58 | Any type that confirm `JSONSerializable` can be parse to JSON. 59 | 60 | ```swift 61 | /// convert to JSON object 62 | public protocol JSONSerializable { 63 | func toJSONObject() -> JSONObject 64 | } 65 | ``` 66 | 67 | **Build-in Support** 68 | 69 | * Int 70 | * String 71 | * Double 72 | * Float 73 | * Bool 74 | * NSURL 75 | * NSDate (unix_timestamp to NSDate, can be custom by build-in DateFormatConverter) 76 | * NSURL (string to URL) 77 | * Raw representable enums which raw value confirm to `JSONConvertible` 78 | * Array\ 79 | * Dictionary\ 80 | 81 | **Demo Code** 82 | 83 | ```swift 84 | enum Gender: Int { 85 | case Unknown = 0 86 | case Male = 1 87 | case Female = 2 88 | } 89 | 90 | class Person: JSONDeserializable, JSONSerializable { 91 | var name: String? 92 | var age: Int? 93 | var birthday: Double? 94 | var weight: Float? 95 | var adult: Bool = false 96 | var gender: Gender = .Unknown 97 | var girlFriend: Person? 98 | var friends = [Person]() 99 | var luckyNumbers = [Int]() 100 | var favouredSingers = [String: Person]() 101 | var vips = [Int: Person]() 102 | var preferNumbers = [Int: Int]() 103 | var orientation = [Gender]() 104 | 105 | init(json: JSONDictionary) { 106 | name <-- json["name"] 107 | age <-- json["age"] 108 | birthday <-- json["birthday"] 109 | weight <-- json["weight"] 110 | adult <-- json["adult"] 111 | gender <-- json["gender"] 112 | girlFriend <-- json["girlFriend"] 113 | friends <-- json["friends"] 114 | luckyNumbers <-- json["luckyNumbers"] 115 | favouredSingers <-- json["favouredSingers"] 116 | vips <-- json["vips"] 117 | preferNumbers <-- json["preferNumbers"] 118 | orientation <-- json["orientation"] 119 | } 120 | 121 | func toJSONObject() -> JSONObject { 122 | var json = JSONDictionary() 123 | 124 | name --> json["name"] 125 | age --> json["age"] 126 | birthday --> json["birthday"] 127 | weight --> json["weight"] 128 | adult --> json["adult"] 129 | gender --> json["gender"] 130 | girlFriend --> json["girlFriend"] 131 | friends --> json["friends"] 132 | luckyNumbers --> json["luckyNumbers"] 133 | favouredSingers --> json["favouredSingers"] 134 | vips --> json["vips"] 135 | preferNumbers --> json["preferNumbers"] 136 | orientation --> json["orientation"] 137 | 138 | return json 139 | } 140 | } 141 | 142 | ``` 143 | 144 | ## Acknowledgements 145 | * [JSONHelper](https://github.com/isair/JSONHelper) CaesarParser is inspired by JSONHelper a lot, thanks for their great work. 146 | 147 | ## License 148 | CaesarParser is available under the MIT license. 149 | --------------------------------------------------------------------------------