├── .gitignore ├── LICENSE ├── Nolan.xcworkspace └── contents.xcworkspacedata ├── Nolan ├── Nolan.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── Nolan.xcscheme ├── Nolan │ ├── Info.plist │ ├── JSONConversionError.swift │ ├── JSONConvertible.swift │ └── Nolan.h └── NolanTests │ ├── Info.plist │ └── NolanTests.swift └── 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 | Carthage/Build 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Mustafa Yusuf 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 all 13 | 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 THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Nolan.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Nolan/Nolan.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 01B4E64F1B4D0D1000232FDB /* Nolan.h in Headers */ = {isa = PBXBuildFile; fileRef = 01B4E64E1B4D0D1000232FDB /* Nolan.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 01B4E6561B4D0D1000232FDB /* Nolan.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 01B4E64B1B4D0D1000232FDB /* Nolan.framework */; }; 12 | 01B4E65B1B4D0D1000232FDB /* NolanTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01B4E65A1B4D0D1000232FDB /* NolanTests.swift */; }; 13 | 01B4E6671B4D0D6000232FDB /* JSONConversionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01B4E6651B4D0D6000232FDB /* JSONConversionError.swift */; }; 14 | 01B4E6681B4D0D6000232FDB /* JSONConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01B4E6661B4D0D6000232FDB /* JSONConvertible.swift */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXContainerItemProxy section */ 18 | 01B4E6571B4D0D1000232FDB /* PBXContainerItemProxy */ = { 19 | isa = PBXContainerItemProxy; 20 | containerPortal = 01B4E6421B4D0D1000232FDB /* Project object */; 21 | proxyType = 1; 22 | remoteGlobalIDString = 01B4E64A1B4D0D1000232FDB; 23 | remoteInfo = Nolan; 24 | }; 25 | /* End PBXContainerItemProxy section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | 01B4E64B1B4D0D1000232FDB /* Nolan.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Nolan.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 01B4E64E1B4D0D1000232FDB /* Nolan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Nolan.h; sourceTree = ""; }; 30 | 01B4E6501B4D0D1000232FDB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 31 | 01B4E6551B4D0D1000232FDB /* NolanTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NolanTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | 01B4E65A1B4D0D1000232FDB /* NolanTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NolanTests.swift; sourceTree = ""; }; 33 | 01B4E65C1B4D0D1000232FDB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 34 | 01B4E6651B4D0D6000232FDB /* JSONConversionError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONConversionError.swift; sourceTree = ""; }; 35 | 01B4E6661B4D0D6000232FDB /* JSONConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONConvertible.swift; sourceTree = ""; }; 36 | /* End PBXFileReference section */ 37 | 38 | /* Begin PBXFrameworksBuildPhase section */ 39 | 01B4E6471B4D0D1000232FDB /* Frameworks */ = { 40 | isa = PBXFrameworksBuildPhase; 41 | buildActionMask = 2147483647; 42 | files = ( 43 | ); 44 | runOnlyForDeploymentPostprocessing = 0; 45 | }; 46 | 01B4E6521B4D0D1000232FDB /* Frameworks */ = { 47 | isa = PBXFrameworksBuildPhase; 48 | buildActionMask = 2147483647; 49 | files = ( 50 | 01B4E6561B4D0D1000232FDB /* Nolan.framework in Frameworks */, 51 | ); 52 | runOnlyForDeploymentPostprocessing = 0; 53 | }; 54 | /* End PBXFrameworksBuildPhase section */ 55 | 56 | /* Begin PBXGroup section */ 57 | 01B4E6411B4D0D1000232FDB = { 58 | isa = PBXGroup; 59 | children = ( 60 | 01B4E64D1B4D0D1000232FDB /* Nolan */, 61 | 01B4E6591B4D0D1000232FDB /* NolanTests */, 62 | 01B4E64C1B4D0D1000232FDB /* Products */, 63 | ); 64 | sourceTree = ""; 65 | }; 66 | 01B4E64C1B4D0D1000232FDB /* Products */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | 01B4E64B1B4D0D1000232FDB /* Nolan.framework */, 70 | 01B4E6551B4D0D1000232FDB /* NolanTests.xctest */, 71 | ); 72 | name = Products; 73 | sourceTree = ""; 74 | }; 75 | 01B4E64D1B4D0D1000232FDB /* Nolan */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 01B4E6651B4D0D6000232FDB /* JSONConversionError.swift */, 79 | 01B4E6661B4D0D6000232FDB /* JSONConvertible.swift */, 80 | 01B4E64E1B4D0D1000232FDB /* Nolan.h */, 81 | 01B4E6501B4D0D1000232FDB /* Info.plist */, 82 | ); 83 | path = Nolan; 84 | sourceTree = ""; 85 | }; 86 | 01B4E6591B4D0D1000232FDB /* NolanTests */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 01B4E65A1B4D0D1000232FDB /* NolanTests.swift */, 90 | 01B4E65C1B4D0D1000232FDB /* Info.plist */, 91 | ); 92 | path = NolanTests; 93 | sourceTree = ""; 94 | }; 95 | /* End PBXGroup section */ 96 | 97 | /* Begin PBXHeadersBuildPhase section */ 98 | 01B4E6481B4D0D1000232FDB /* Headers */ = { 99 | isa = PBXHeadersBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | 01B4E64F1B4D0D1000232FDB /* Nolan.h in Headers */, 103 | ); 104 | runOnlyForDeploymentPostprocessing = 0; 105 | }; 106 | /* End PBXHeadersBuildPhase section */ 107 | 108 | /* Begin PBXNativeTarget section */ 109 | 01B4E64A1B4D0D1000232FDB /* Nolan */ = { 110 | isa = PBXNativeTarget; 111 | buildConfigurationList = 01B4E65F1B4D0D1000232FDB /* Build configuration list for PBXNativeTarget "Nolan" */; 112 | buildPhases = ( 113 | 01B4E6461B4D0D1000232FDB /* Sources */, 114 | 01B4E6471B4D0D1000232FDB /* Frameworks */, 115 | 01B4E6481B4D0D1000232FDB /* Headers */, 116 | 01B4E6491B4D0D1000232FDB /* Resources */, 117 | ); 118 | buildRules = ( 119 | ); 120 | dependencies = ( 121 | ); 122 | name = Nolan; 123 | productName = Nolan; 124 | productReference = 01B4E64B1B4D0D1000232FDB /* Nolan.framework */; 125 | productType = "com.apple.product-type.framework"; 126 | }; 127 | 01B4E6541B4D0D1000232FDB /* NolanTests */ = { 128 | isa = PBXNativeTarget; 129 | buildConfigurationList = 01B4E6621B4D0D1000232FDB /* Build configuration list for PBXNativeTarget "NolanTests" */; 130 | buildPhases = ( 131 | 01B4E6511B4D0D1000232FDB /* Sources */, 132 | 01B4E6521B4D0D1000232FDB /* Frameworks */, 133 | 01B4E6531B4D0D1000232FDB /* Resources */, 134 | ); 135 | buildRules = ( 136 | ); 137 | dependencies = ( 138 | 01B4E6581B4D0D1000232FDB /* PBXTargetDependency */, 139 | ); 140 | name = NolanTests; 141 | productName = NolanTests; 142 | productReference = 01B4E6551B4D0D1000232FDB /* NolanTests.xctest */; 143 | productType = "com.apple.product-type.bundle.unit-test"; 144 | }; 145 | /* End PBXNativeTarget section */ 146 | 147 | /* Begin PBXProject section */ 148 | 01B4E6421B4D0D1000232FDB /* Project object */ = { 149 | isa = PBXProject; 150 | attributes = { 151 | LastSwiftUpdateCheck = 0700; 152 | LastUpgradeCheck = 0700; 153 | ORGANIZATIONNAME = "Mustafa Yusuf"; 154 | TargetAttributes = { 155 | 01B4E64A1B4D0D1000232FDB = { 156 | CreatedOnToolsVersion = 7.0; 157 | }; 158 | 01B4E6541B4D0D1000232FDB = { 159 | CreatedOnToolsVersion = 7.0; 160 | }; 161 | }; 162 | }; 163 | buildConfigurationList = 01B4E6451B4D0D1000232FDB /* Build configuration list for PBXProject "Nolan" */; 164 | compatibilityVersion = "Xcode 3.2"; 165 | developmentRegion = English; 166 | hasScannedForEncodings = 0; 167 | knownRegions = ( 168 | en, 169 | ); 170 | mainGroup = 01B4E6411B4D0D1000232FDB; 171 | productRefGroup = 01B4E64C1B4D0D1000232FDB /* Products */; 172 | projectDirPath = ""; 173 | projectRoot = ""; 174 | targets = ( 175 | 01B4E64A1B4D0D1000232FDB /* Nolan */, 176 | 01B4E6541B4D0D1000232FDB /* NolanTests */, 177 | ); 178 | }; 179 | /* End PBXProject section */ 180 | 181 | /* Begin PBXResourcesBuildPhase section */ 182 | 01B4E6491B4D0D1000232FDB /* Resources */ = { 183 | isa = PBXResourcesBuildPhase; 184 | buildActionMask = 2147483647; 185 | files = ( 186 | ); 187 | runOnlyForDeploymentPostprocessing = 0; 188 | }; 189 | 01B4E6531B4D0D1000232FDB /* Resources */ = { 190 | isa = PBXResourcesBuildPhase; 191 | buildActionMask = 2147483647; 192 | files = ( 193 | ); 194 | runOnlyForDeploymentPostprocessing = 0; 195 | }; 196 | /* End PBXResourcesBuildPhase section */ 197 | 198 | /* Begin PBXSourcesBuildPhase section */ 199 | 01B4E6461B4D0D1000232FDB /* Sources */ = { 200 | isa = PBXSourcesBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | 01B4E6671B4D0D6000232FDB /* JSONConversionError.swift in Sources */, 204 | 01B4E6681B4D0D6000232FDB /* JSONConvertible.swift in Sources */, 205 | ); 206 | runOnlyForDeploymentPostprocessing = 0; 207 | }; 208 | 01B4E6511B4D0D1000232FDB /* Sources */ = { 209 | isa = PBXSourcesBuildPhase; 210 | buildActionMask = 2147483647; 211 | files = ( 212 | 01B4E65B1B4D0D1000232FDB /* NolanTests.swift in Sources */, 213 | ); 214 | runOnlyForDeploymentPostprocessing = 0; 215 | }; 216 | /* End PBXSourcesBuildPhase section */ 217 | 218 | /* Begin PBXTargetDependency section */ 219 | 01B4E6581B4D0D1000232FDB /* PBXTargetDependency */ = { 220 | isa = PBXTargetDependency; 221 | target = 01B4E64A1B4D0D1000232FDB /* Nolan */; 222 | targetProxy = 01B4E6571B4D0D1000232FDB /* PBXContainerItemProxy */; 223 | }; 224 | /* End PBXTargetDependency section */ 225 | 226 | /* Begin XCBuildConfiguration section */ 227 | 01B4E65D1B4D0D1000232FDB /* Debug */ = { 228 | isa = XCBuildConfiguration; 229 | buildSettings = { 230 | ALWAYS_SEARCH_USER_PATHS = NO; 231 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 232 | CLANG_CXX_LIBRARY = "libc++"; 233 | CLANG_ENABLE_MODULES = YES; 234 | CLANG_ENABLE_OBJC_ARC = YES; 235 | CLANG_WARN_BOOL_CONVERSION = YES; 236 | CLANG_WARN_CONSTANT_CONVERSION = YES; 237 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 238 | CLANG_WARN_EMPTY_BODY = YES; 239 | CLANG_WARN_ENUM_CONVERSION = YES; 240 | CLANG_WARN_INT_CONVERSION = YES; 241 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 242 | CLANG_WARN_UNREACHABLE_CODE = YES; 243 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 244 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 245 | COPY_PHASE_STRIP = NO; 246 | CURRENT_PROJECT_VERSION = 1; 247 | DEBUG_INFORMATION_FORMAT = dwarf; 248 | ENABLE_STRICT_OBJC_MSGSEND = YES; 249 | ENABLE_TESTABILITY = YES; 250 | GCC_C_LANGUAGE_STANDARD = gnu99; 251 | GCC_DYNAMIC_NO_PIC = NO; 252 | GCC_NO_COMMON_BLOCKS = YES; 253 | GCC_OPTIMIZATION_LEVEL = 0; 254 | GCC_PREPROCESSOR_DEFINITIONS = ( 255 | "DEBUG=1", 256 | "$(inherited)", 257 | ); 258 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 259 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 260 | GCC_WARN_UNDECLARED_SELECTOR = YES; 261 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 262 | GCC_WARN_UNUSED_FUNCTION = YES; 263 | GCC_WARN_UNUSED_VARIABLE = YES; 264 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 265 | MTL_ENABLE_DEBUG_INFO = YES; 266 | ONLY_ACTIVE_ARCH = YES; 267 | SDKROOT = iphoneos; 268 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 269 | TARGETED_DEVICE_FAMILY = "1,2"; 270 | VERSIONING_SYSTEM = "apple-generic"; 271 | VERSION_INFO_PREFIX = ""; 272 | }; 273 | name = Debug; 274 | }; 275 | 01B4E65E1B4D0D1000232FDB /* Release */ = { 276 | isa = XCBuildConfiguration; 277 | buildSettings = { 278 | ALWAYS_SEARCH_USER_PATHS = NO; 279 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 280 | CLANG_CXX_LIBRARY = "libc++"; 281 | CLANG_ENABLE_MODULES = YES; 282 | CLANG_ENABLE_OBJC_ARC = YES; 283 | CLANG_WARN_BOOL_CONVERSION = YES; 284 | CLANG_WARN_CONSTANT_CONVERSION = YES; 285 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 286 | CLANG_WARN_EMPTY_BODY = YES; 287 | CLANG_WARN_ENUM_CONVERSION = YES; 288 | CLANG_WARN_INT_CONVERSION = YES; 289 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 290 | CLANG_WARN_UNREACHABLE_CODE = YES; 291 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 292 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 293 | COPY_PHASE_STRIP = NO; 294 | CURRENT_PROJECT_VERSION = 1; 295 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 296 | ENABLE_NS_ASSERTIONS = NO; 297 | ENABLE_STRICT_OBJC_MSGSEND = YES; 298 | GCC_C_LANGUAGE_STANDARD = gnu99; 299 | GCC_NO_COMMON_BLOCKS = YES; 300 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 301 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 302 | GCC_WARN_UNDECLARED_SELECTOR = YES; 303 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 304 | GCC_WARN_UNUSED_FUNCTION = YES; 305 | GCC_WARN_UNUSED_VARIABLE = YES; 306 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 307 | MTL_ENABLE_DEBUG_INFO = NO; 308 | SDKROOT = iphoneos; 309 | TARGETED_DEVICE_FAMILY = "1,2"; 310 | VALIDATE_PRODUCT = YES; 311 | VERSIONING_SYSTEM = "apple-generic"; 312 | VERSION_INFO_PREFIX = ""; 313 | }; 314 | name = Release; 315 | }; 316 | 01B4E6601B4D0D1000232FDB /* Debug */ = { 317 | isa = XCBuildConfiguration; 318 | buildSettings = { 319 | CLANG_ENABLE_MODULES = YES; 320 | DEFINES_MODULE = YES; 321 | DYLIB_COMPATIBILITY_VERSION = 1; 322 | DYLIB_CURRENT_VERSION = 1; 323 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 324 | INFOPLIST_FILE = Nolan/Info.plist; 325 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 326 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 327 | PRODUCT_BUNDLE_IDENTIFIER = com.swiftkitchen.Nolan; 328 | PRODUCT_NAME = "$(TARGET_NAME)"; 329 | SKIP_INSTALL = YES; 330 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 331 | }; 332 | name = Debug; 333 | }; 334 | 01B4E6611B4D0D1000232FDB /* Release */ = { 335 | isa = XCBuildConfiguration; 336 | buildSettings = { 337 | CLANG_ENABLE_MODULES = YES; 338 | DEFINES_MODULE = YES; 339 | DYLIB_COMPATIBILITY_VERSION = 1; 340 | DYLIB_CURRENT_VERSION = 1; 341 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 342 | INFOPLIST_FILE = Nolan/Info.plist; 343 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 344 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 345 | PRODUCT_BUNDLE_IDENTIFIER = com.swiftkitchen.Nolan; 346 | PRODUCT_NAME = "$(TARGET_NAME)"; 347 | SKIP_INSTALL = YES; 348 | }; 349 | name = Release; 350 | }; 351 | 01B4E6631B4D0D1000232FDB /* Debug */ = { 352 | isa = XCBuildConfiguration; 353 | buildSettings = { 354 | INFOPLIST_FILE = NolanTests/Info.plist; 355 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 356 | PRODUCT_BUNDLE_IDENTIFIER = com.swiftkitchen.NolanTests; 357 | PRODUCT_NAME = "$(TARGET_NAME)"; 358 | }; 359 | name = Debug; 360 | }; 361 | 01B4E6641B4D0D1000232FDB /* Release */ = { 362 | isa = XCBuildConfiguration; 363 | buildSettings = { 364 | INFOPLIST_FILE = NolanTests/Info.plist; 365 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 366 | PRODUCT_BUNDLE_IDENTIFIER = com.swiftkitchen.NolanTests; 367 | PRODUCT_NAME = "$(TARGET_NAME)"; 368 | }; 369 | name = Release; 370 | }; 371 | /* End XCBuildConfiguration section */ 372 | 373 | /* Begin XCConfigurationList section */ 374 | 01B4E6451B4D0D1000232FDB /* Build configuration list for PBXProject "Nolan" */ = { 375 | isa = XCConfigurationList; 376 | buildConfigurations = ( 377 | 01B4E65D1B4D0D1000232FDB /* Debug */, 378 | 01B4E65E1B4D0D1000232FDB /* Release */, 379 | ); 380 | defaultConfigurationIsVisible = 0; 381 | defaultConfigurationName = Release; 382 | }; 383 | 01B4E65F1B4D0D1000232FDB /* Build configuration list for PBXNativeTarget "Nolan" */ = { 384 | isa = XCConfigurationList; 385 | buildConfigurations = ( 386 | 01B4E6601B4D0D1000232FDB /* Debug */, 387 | 01B4E6611B4D0D1000232FDB /* Release */, 388 | ); 389 | defaultConfigurationIsVisible = 0; 390 | defaultConfigurationName = Release; 391 | }; 392 | 01B4E6621B4D0D1000232FDB /* Build configuration list for PBXNativeTarget "NolanTests" */ = { 393 | isa = XCConfigurationList; 394 | buildConfigurations = ( 395 | 01B4E6631B4D0D1000232FDB /* Debug */, 396 | 01B4E6641B4D0D1000232FDB /* Release */, 397 | ); 398 | defaultConfigurationIsVisible = 0; 399 | defaultConfigurationName = Release; 400 | }; 401 | /* End XCConfigurationList section */ 402 | }; 403 | rootObject = 01B4E6421B4D0D1000232FDB /* Project object */; 404 | } 405 | -------------------------------------------------------------------------------- /Nolan/Nolan.xcodeproj/xcshareddata/xcschemes/Nolan.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 | -------------------------------------------------------------------------------- /Nolan/Nolan/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 | -------------------------------------------------------------------------------- /Nolan/Nolan/JSONConversionError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JSONConversionError.swift 3 | // ProjectNolan 4 | // 5 | // Created by Mustafa Yusuf on 7.07.2015. 6 | // Copyright © 2015 Mustafa Yusuf. All rights reserved. 7 | // 8 | 9 | public enum JSONConversionError: ErrorType { 10 | case TypeIsNotConvertibleToJSON(typeName: String) 11 | } -------------------------------------------------------------------------------- /Nolan/Nolan/JSONConvertible.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JSONConvertible.swift 3 | // ProjectNolan 4 | // 5 | // Created by Mustafa Yusuf on 7.07.2015. 6 | // Copyright © 2015 Mustafa Yusuf. All rights reserved. 7 | // 8 | 9 | public typealias JSON = AnyObject 10 | 11 | public protocol JSONConvertible { 12 | func toJSON() throws -> JSON 13 | } 14 | 15 | public extension JSONConvertible { 16 | func toJSON() throws -> JSON { 17 | let mirror = Mirror(reflecting: self) 18 | var json = [String: JSON]() 19 | for child in mirror.children { 20 | guard let value = child.value as? JSONConvertible else { 21 | let mirror = reflect(child.value) 22 | throw JSONConversionError.TypeIsNotConvertibleToJSON(typeName: mirror.summary) 23 | } 24 | 25 | json[child.label!] = try value.toJSON() 26 | } 27 | 28 | return json 29 | } 30 | } 31 | 32 | extension String: JSONConvertible { 33 | public func toJSON() throws -> JSON { 34 | return self 35 | } 36 | } 37 | 38 | extension Int: JSONConvertible { 39 | public func toJSON() throws -> JSON { 40 | return self 41 | } 42 | } 43 | 44 | extension Double: JSONConvertible { 45 | public func toJSON() throws -> JSON { 46 | return self 47 | } 48 | } 49 | 50 | extension Float: JSONConvertible { 51 | public func toJSON() throws -> JSON { 52 | return Double(self) 53 | } 54 | } 55 | 56 | extension Bool: JSONConvertible { 57 | public func toJSON() throws -> JSON { 58 | return self ? 1 : 0 59 | } 60 | } 61 | 62 | extension Optional: JSONConvertible { 63 | public func toJSON() throws -> JSON { 64 | switch self { 65 | case let .Some(val): 66 | guard let value = val as? JSONConvertible else { 67 | let mirror = reflect(val) 68 | throw JSONConversionError.TypeIsNotConvertibleToJSON(typeName: mirror.summary) 69 | } 70 | return try value.toJSON() 71 | case .None: 72 | return NSNull() 73 | } 74 | } 75 | } 76 | 77 | extension NSURL: JSONConvertible { 78 | public func toJSON() throws -> JSON { 79 | return self.absoluteString 80 | } 81 | } 82 | 83 | extension Array: JSONConvertible { 84 | public func toJSON() throws -> JSON { 85 | var jsonArray = [JSON]() 86 | 87 | for item in self { 88 | if let item = item as? JSONConvertible { 89 | jsonArray.append(try item.toJSON()) 90 | } else { 91 | let mirror = reflect(item) 92 | throw JSONConversionError.TypeIsNotConvertibleToJSON(typeName: mirror.summary) 93 | } 94 | } 95 | 96 | return jsonArray 97 | } 98 | } 99 | 100 | extension NSDate: JSONConvertible { 101 | public func toJSON() throws -> JSON { 102 | let formatter = NSDateFormatter() 103 | formatter.timeZone = NSTimeZone.localTimeZone() 104 | formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ" 105 | return formatter.stringFromDate(self) 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Nolan/Nolan/Nolan.h: -------------------------------------------------------------------------------- 1 | // 2 | // Nolan.h 3 | // Nolan 4 | // 5 | // Created by Mustafa Yusuf on 8.07.2015. 6 | // Copyright © 2015 Mustafa Yusuf. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | FOUNDATION_EXPORT double NolanVersionNumber; 12 | FOUNDATION_EXPORT const unsigned char NolanVersionString[]; 13 | 14 | 15 | -------------------------------------------------------------------------------- /Nolan/NolanTests/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 | -------------------------------------------------------------------------------- /Nolan/NolanTests/NolanTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NolanTests.swift 3 | // NolanTests 4 | // 5 | // Created by Mustafa Yusuf on 8.07.2015. 6 | // Copyright © 2015 Mustafa Yusuf. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class NolanTests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | super.tearDown() 21 | } 22 | 23 | func testExample() { 24 | // This is an example of a functional test case. 25 | // Use XCTAssert and related functions to verify your tests produce the correct results. 26 | } 27 | 28 | func testPerformanceExample() { 29 | // This is an example of a performance test case. 30 | self.measureBlock() { 31 | // Put the code you want to measure the time of here. 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ##Nolan 3 | 4 | Nolan is a library that converts __swift 2__ values into JSON format. It can convert any type (except functions and tuples) to JSON object. It uses protocol extensions, error handling that is only available in swift version 2. 5 | 6 | ###Requirements 7 | * Swift 2 8 | * Xcode 7 9 | 10 | ###Installation 11 | 12 | Nolan supports [Carthage](https://github.com/Carthage/Carthage). Add `github "mstfy/Nolan"` line into your Cartfile and run `carthage install` command on terminal. 13 | 14 | ###How to use 15 | By default Nolan can convert `String`, `NSDate`, `Float`, `Double`, `Int`, `NSURL` and `Optional` types to json. To adopt it for your custom type just conform your type to `JSONConvertible` protocol and it is done (hopefully). Here is an example type: 16 | 17 | struct User: JSONConvertible { 18 | let name: String 19 | let age: Int 20 | } 21 | 22 | Now to convert it to JSON just call `toJSON()` method that is declared in `JSONConvertible` protocol. 23 | 24 | let user = User(name: "Nolan", age: 25) 25 | try { 26 | let userJSON = try user.toJSON() 27 | print("user converted to \(userJSON)") 28 | } catch let JSONConversionError.TypeIsNotConvertibleToJSON(type) { 29 | print("Error: \(type) is not convertible to JSON") 30 | } 31 | 32 | Here is more complicated example: 33 | 34 | struct User: JSONConvertible { 35 | let name: String 36 | let books: [Book] 37 | } 38 | 39 | struct Book: JSONConvertible { 40 | let name: String 41 | let author: String 42 | let publisher: String? 43 | } 44 | 45 | let books = [Book(name: "The Lord Of the Rings", author: "J.R.R. Tolkien", publisher: "George Allen"), Book(name: "When Nietzsche Wept", author: "Irvin D. Yalom", publisher: nil)] 46 | let user = User(name: "Cooper", books: books) 47 | 48 | do { 49 | let userJson = try user.toJSON() 50 | print("user json is \(userJson)") 51 | } catch let JSONConversionError.TypeIsNotConvertibleToJSON(type) { 52 | print("Error: \(type) is not convertible to JSON") 53 | } catch let error as NSError { 54 | print("unknown error \(error.localizedDescription)") 55 | } 56 | 57 | It prints: 58 | 59 | user json is { 60 | books = ( 61 | { 62 | author = "J.R.R. Tolkien"; 63 | name = "The Lord Of the Rings"; 64 | publisher = "George Allen"; 65 | }, 66 | { 67 | author = "Irvin D. Yalom"; 68 | name = "When Nietzsche Wept"; 69 | publisher = ""; 70 | } 71 | ); 72 | name = Cooper; 73 | } 74 | 75 | By default `toJSON` method produces key value pairs of the value using reflection api in Swift. But you can override this behavior in your custom type. For example: 76 | 77 | struct User: JSONConvertible { 78 | let name: String 79 | let role: Role 80 | } 81 | 82 | enum Role: JSONConvertible { 83 | case Pilot 84 | case Captain 85 | 86 | func toJSON() throws -> JSON { 87 | switch self { 88 | case .Pilot: return "pilot" 89 | case .Captain: return "captain" 90 | } 91 | } 92 | } 93 | 94 | let user = User(name: "Cooper", role: .Captain) 95 | do { 96 | let userJSON = try user.toJSON() 97 | print("user json = \(userJSON)") 98 | } catch let JSONConversionError.TypeIsNotConvertibleToJSON(type) { 99 | print("Error: \(type) is not convertible to JSON") 100 | } catch let error as NSError { 101 | print("unknown error \(error.localizedDescription)") 102 | } 103 | 104 | It prints: 105 | 106 | user json = { 107 | name = Cooper; 108 | role = captain; 109 | } 110 | --------------------------------------------------------------------------------