├── .gitignore ├── .gitmodules ├── Extras ├── TestHarness.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── TestHarness │ ├── TestHarness-Info.plist │ ├── TestHarness-Prefix.pch │ ├── TestHarnessAppDelegate.h │ ├── TestHarnessAppDelegate.m │ ├── en.lproj │ ├── Credits.rtf │ ├── InfoPlist.strings │ └── MainMenu.xib │ └── main.m ├── MIT-LICENSE └── Source └── libCloud ├── Cloud.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── nickpaulson.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── nickpaulson.xcuserdatad │ └── xcschemes │ ├── Cloud.xcscheme │ └── xcschememanagement.plist └── Cloud ├── API Parsing ├── CLAPIDeserializer.h ├── CLAPIDeserializer.m ├── CLAPISerializer.h └── CLAPISerializer.m ├── CLAPIEngine.h ├── CLAPIEngine.m ├── CLAPIEngineConstants.h ├── CLAPIEngineConstants.m ├── CLAPIEngineDelegate.h ├── CLAPITransaction.h ├── CLAPITransaction.m ├── Categories ├── NSMutableURLRequest+NPPOSTBody.h ├── NSMutableURLRequest+NPPOSTBody.m ├── NSString+NPAdditions.h ├── NSString+NPAdditions.m ├── NSString+NPMimeType.h └── NSString+NPMimeType.m ├── Cloud-Prefix.pch ├── Cloud.h └── Model ├── CLAccount.h ├── CLAccount.m ├── CLSocket.h ├── CLSocket.m ├── CLWebItem.h └── CLWebItem.m /.gitignore: -------------------------------------------------------------------------------- 1 | build/* 2 | *.pbxuser 3 | *.mode1v3 4 | *.xcodeproj/xcuserdata/* 5 | *.xcodeproj/project.xcworkspace/xcuserdata/* 6 | .DS_Store 7 | profile 8 | 9 | Extras/build/ 10 | Extras/*.xcodeproj/xcuserdata/* 11 | Extras/*.xcodeproj/project.xcworkspace/xcuserdata/* 12 | 13 | Source/libCloud/build/* 14 | Source/libCloud/*.xcodeproj/xcuserdata/* 15 | Source/libCloud/*.xcodeproj/project.xcworkspace/xcuserdata/* 16 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Source/libCloud/Cloud/Third Party/JSON"] 2 | path = Source/libCloud/Cloud/Third Party/JSON 3 | url = https://github.com/stig/json-framework.git 4 | [submodule "Source/libCloud/Cloud/Third Party/IFUnicodeURL"] 5 | path = Source/libCloud/Cloud/Third Party/IFUnicodeURL 6 | url = git@github.com:cloudapp/IFUnicodeURL.git 7 | -------------------------------------------------------------------------------- /Extras/TestHarness.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4BCB7450130B6D5800C3A701 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCB744F130B6D5800C3A701 /* Cocoa.framework */; }; 11 | 4BCB745A130B6D5800C3A701 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4BCB7458130B6D5800C3A701 /* InfoPlist.strings */; }; 12 | 4BCB745D130B6D5800C3A701 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BCB745C130B6D5800C3A701 /* main.m */; }; 13 | 4BCB7460130B6D5800C3A701 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 4BCB745E130B6D5800C3A701 /* Credits.rtf */; }; 14 | 4BCB7463130B6D5800C3A701 /* TestHarnessAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BCB7462130B6D5800C3A701 /* TestHarnessAppDelegate.m */; }; 15 | 4BCB7466130B6D5800C3A701 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BCB7464130B6D5800C3A701 /* MainMenu.xib */; }; 16 | 4BCB7473130B6D7D00C3A701 /* libCloud.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCB7472130B6D7D00C3A701 /* libCloud.a */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXContainerItemProxy section */ 20 | 4BCB74A7130B6EF900C3A701 /* PBXContainerItemProxy */ = { 21 | isa = PBXContainerItemProxy; 22 | containerPortal = 4BCB74A0130B6EF900C3A701 /* Cloud.xcodeproj */; 23 | proxyType = 2; 24 | remoteGlobalIDString = 4B1AB184130B69B900BD6A95; 25 | remoteInfo = Cloud; 26 | }; 27 | 4BCB74AA130B6F0800C3A701 /* PBXContainerItemProxy */ = { 28 | isa = PBXContainerItemProxy; 29 | containerPortal = 4BCB74A0130B6EF900C3A701 /* Cloud.xcodeproj */; 30 | proxyType = 1; 31 | remoteGlobalIDString = 4B1AB183130B69B900BD6A95; 32 | remoteInfo = Cloud; 33 | }; 34 | /* End PBXContainerItemProxy section */ 35 | 36 | /* Begin PBXFileReference section */ 37 | 4BCB744B130B6D5800C3A701 /* TestHarness.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestHarness.app; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | 4BCB744F130B6D5800C3A701 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 39 | 4BCB7452130B6D5800C3A701 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 40 | 4BCB7453130B6D5800C3A701 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 41 | 4BCB7454130B6D5800C3A701 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 42 | 4BCB7457130B6D5800C3A701 /* TestHarness-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "TestHarness-Info.plist"; sourceTree = ""; }; 43 | 4BCB7459130B6D5800C3A701 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 44 | 4BCB745B130B6D5800C3A701 /* TestHarness-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TestHarness-Prefix.pch"; sourceTree = ""; }; 45 | 4BCB745C130B6D5800C3A701 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 46 | 4BCB745F130B6D5800C3A701 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = ""; }; 47 | 4BCB7461130B6D5800C3A701 /* TestHarnessAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestHarnessAppDelegate.h; sourceTree = ""; }; 48 | 4BCB7462130B6D5800C3A701 /* TestHarnessAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestHarnessAppDelegate.m; sourceTree = ""; }; 49 | 4BCB7465130B6D5800C3A701 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; 50 | 4BCB7472130B6D7D00C3A701 /* libCloud.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libCloud.a; path = "../../../../../../Library/Developer/Xcode/DerivedData/Cloud-abtwsrtzrxyrskbxyjrwgmseiljc/Build/Products/Debug/libCloud.a"; sourceTree = ""; }; 51 | 4BCB74A0130B6EF900C3A701 /* Cloud.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Cloud.xcodeproj; path = ../../Source/libCloud/Cloud.xcodeproj; sourceTree = ""; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | 4BCB7448130B6D5800C3A701 /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | 4BCB7450130B6D5800C3A701 /* Cocoa.framework in Frameworks */, 60 | 4BCB7473130B6D7D00C3A701 /* libCloud.a in Frameworks */, 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXFrameworksBuildPhase section */ 65 | 66 | /* Begin PBXGroup section */ 67 | 4BCB7440130B6D5700C3A701 = { 68 | isa = PBXGroup; 69 | children = ( 70 | 4BCB74A0130B6EF900C3A701 /* Cloud.xcodeproj */, 71 | 4BCB7455130B6D5800C3A701 /* TestHarness */, 72 | 4BCB744E130B6D5800C3A701 /* Frameworks */, 73 | 4BCB744C130B6D5800C3A701 /* Products */, 74 | ); 75 | sourceTree = ""; 76 | }; 77 | 4BCB744C130B6D5800C3A701 /* Products */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | 4BCB744B130B6D5800C3A701 /* TestHarness.app */, 81 | ); 82 | name = Products; 83 | sourceTree = ""; 84 | }; 85 | 4BCB744E130B6D5800C3A701 /* Frameworks */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 4BCB7472130B6D7D00C3A701 /* libCloud.a */, 89 | 4BCB744F130B6D5800C3A701 /* Cocoa.framework */, 90 | 4BCB7451130B6D5800C3A701 /* Other Frameworks */, 91 | ); 92 | name = Frameworks; 93 | sourceTree = ""; 94 | }; 95 | 4BCB7451130B6D5800C3A701 /* Other Frameworks */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | 4BCB7452130B6D5800C3A701 /* AppKit.framework */, 99 | 4BCB7453130B6D5800C3A701 /* CoreData.framework */, 100 | 4BCB7454130B6D5800C3A701 /* Foundation.framework */, 101 | ); 102 | name = "Other Frameworks"; 103 | sourceTree = ""; 104 | }; 105 | 4BCB7455130B6D5800C3A701 /* TestHarness */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 4BCB7461130B6D5800C3A701 /* TestHarnessAppDelegate.h */, 109 | 4BCB7462130B6D5800C3A701 /* TestHarnessAppDelegate.m */, 110 | 4BCB7464130B6D5800C3A701 /* MainMenu.xib */, 111 | 4BCB7456130B6D5800C3A701 /* Supporting Files */, 112 | ); 113 | path = TestHarness; 114 | sourceTree = ""; 115 | }; 116 | 4BCB7456130B6D5800C3A701 /* Supporting Files */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | 4BCB7457130B6D5800C3A701 /* TestHarness-Info.plist */, 120 | 4BCB7458130B6D5800C3A701 /* InfoPlist.strings */, 121 | 4BCB745B130B6D5800C3A701 /* TestHarness-Prefix.pch */, 122 | 4BCB745C130B6D5800C3A701 /* main.m */, 123 | 4BCB745E130B6D5800C3A701 /* Credits.rtf */, 124 | ); 125 | name = "Supporting Files"; 126 | sourceTree = ""; 127 | }; 128 | 4BCB74A1130B6EF900C3A701 /* Products */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 4BCB74A8130B6EF900C3A701 /* libCloud.a */, 132 | ); 133 | name = Products; 134 | sourceTree = ""; 135 | }; 136 | /* End PBXGroup section */ 137 | 138 | /* Begin PBXNativeTarget section */ 139 | 4BCB744A130B6D5800C3A701 /* TestHarness */ = { 140 | isa = PBXNativeTarget; 141 | buildConfigurationList = 4BCB7469130B6D5800C3A701 /* Build configuration list for PBXNativeTarget "TestHarness" */; 142 | buildPhases = ( 143 | 4BCB7447130B6D5800C3A701 /* Sources */, 144 | 4BCB7448130B6D5800C3A701 /* Frameworks */, 145 | 4BCB7449130B6D5800C3A701 /* Resources */, 146 | ); 147 | buildRules = ( 148 | ); 149 | dependencies = ( 150 | 4BCB74AB130B6F0800C3A701 /* PBXTargetDependency */, 151 | ); 152 | name = TestHarness; 153 | productName = TestHarness; 154 | productReference = 4BCB744B130B6D5800C3A701 /* TestHarness.app */; 155 | productType = "com.apple.product-type.application"; 156 | }; 157 | /* End PBXNativeTarget section */ 158 | 159 | /* Begin PBXProject section */ 160 | 4BCB7442130B6D5700C3A701 /* Project object */ = { 161 | isa = PBXProject; 162 | attributes = { 163 | ORGANIZATIONNAME = Linebreak; 164 | }; 165 | buildConfigurationList = 4BCB7445130B6D5700C3A701 /* Build configuration list for PBXProject "TestHarness" */; 166 | compatibilityVersion = "Xcode 3.2"; 167 | developmentRegion = English; 168 | hasScannedForEncodings = 0; 169 | knownRegions = ( 170 | en, 171 | ); 172 | mainGroup = 4BCB7440130B6D5700C3A701; 173 | productRefGroup = 4BCB744C130B6D5800C3A701 /* Products */; 174 | projectDirPath = ""; 175 | projectReferences = ( 176 | { 177 | ProductGroup = 4BCB74A1130B6EF900C3A701 /* Products */; 178 | ProjectRef = 4BCB74A0130B6EF900C3A701 /* Cloud.xcodeproj */; 179 | }, 180 | ); 181 | projectRoot = ""; 182 | targets = ( 183 | 4BCB744A130B6D5800C3A701 /* TestHarness */, 184 | ); 185 | }; 186 | /* End PBXProject section */ 187 | 188 | /* Begin PBXReferenceProxy section */ 189 | 4BCB74A8130B6EF900C3A701 /* libCloud.a */ = { 190 | isa = PBXReferenceProxy; 191 | fileType = archive.ar; 192 | path = libCloud.a; 193 | remoteRef = 4BCB74A7130B6EF900C3A701 /* PBXContainerItemProxy */; 194 | sourceTree = BUILT_PRODUCTS_DIR; 195 | }; 196 | /* End PBXReferenceProxy section */ 197 | 198 | /* Begin PBXResourcesBuildPhase section */ 199 | 4BCB7449130B6D5800C3A701 /* Resources */ = { 200 | isa = PBXResourcesBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | 4BCB745A130B6D5800C3A701 /* InfoPlist.strings in Resources */, 204 | 4BCB7460130B6D5800C3A701 /* Credits.rtf in Resources */, 205 | 4BCB7466130B6D5800C3A701 /* MainMenu.xib in Resources */, 206 | ); 207 | runOnlyForDeploymentPostprocessing = 0; 208 | }; 209 | /* End PBXResourcesBuildPhase section */ 210 | 211 | /* Begin PBXSourcesBuildPhase section */ 212 | 4BCB7447130B6D5800C3A701 /* Sources */ = { 213 | isa = PBXSourcesBuildPhase; 214 | buildActionMask = 2147483647; 215 | files = ( 216 | 4BCB745D130B6D5800C3A701 /* main.m in Sources */, 217 | 4BCB7463130B6D5800C3A701 /* TestHarnessAppDelegate.m in Sources */, 218 | ); 219 | runOnlyForDeploymentPostprocessing = 0; 220 | }; 221 | /* End PBXSourcesBuildPhase section */ 222 | 223 | /* Begin PBXTargetDependency section */ 224 | 4BCB74AB130B6F0800C3A701 /* PBXTargetDependency */ = { 225 | isa = PBXTargetDependency; 226 | name = Cloud; 227 | targetProxy = 4BCB74AA130B6F0800C3A701 /* PBXContainerItemProxy */; 228 | }; 229 | /* End PBXTargetDependency section */ 230 | 231 | /* Begin PBXVariantGroup section */ 232 | 4BCB7458130B6D5800C3A701 /* InfoPlist.strings */ = { 233 | isa = PBXVariantGroup; 234 | children = ( 235 | 4BCB7459130B6D5800C3A701 /* en */, 236 | ); 237 | name = InfoPlist.strings; 238 | sourceTree = ""; 239 | }; 240 | 4BCB745E130B6D5800C3A701 /* Credits.rtf */ = { 241 | isa = PBXVariantGroup; 242 | children = ( 243 | 4BCB745F130B6D5800C3A701 /* en */, 244 | ); 245 | name = Credits.rtf; 246 | sourceTree = ""; 247 | }; 248 | 4BCB7464130B6D5800C3A701 /* MainMenu.xib */ = { 249 | isa = PBXVariantGroup; 250 | children = ( 251 | 4BCB7465130B6D5800C3A701 /* en */, 252 | ); 253 | name = MainMenu.xib; 254 | sourceTree = ""; 255 | }; 256 | /* End PBXVariantGroup section */ 257 | 258 | /* Begin XCBuildConfiguration section */ 259 | 4BCB7467130B6D5800C3A701 /* Debug */ = { 260 | isa = XCBuildConfiguration; 261 | buildSettings = { 262 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 263 | GCC_C_LANGUAGE_STANDARD = gnu99; 264 | GCC_OPTIMIZATION_LEVEL = 0; 265 | GCC_PREPROCESSOR_DEFINITIONS = DEBUG; 266 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 267 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 268 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 269 | GCC_WARN_UNUSED_VARIABLE = YES; 270 | MACOSX_DEPLOYMENT_TARGET = 10.6; 271 | ONLY_ACTIVE_ARCH = YES; 272 | SDKROOT = macosx; 273 | }; 274 | name = Debug; 275 | }; 276 | 4BCB7468130B6D5800C3A701 /* Release */ = { 277 | isa = XCBuildConfiguration; 278 | buildSettings = { 279 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 280 | GCC_C_LANGUAGE_STANDARD = gnu99; 281 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 282 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 283 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 284 | GCC_WARN_UNUSED_VARIABLE = YES; 285 | MACOSX_DEPLOYMENT_TARGET = 10.6; 286 | SDKROOT = macosx; 287 | }; 288 | name = Release; 289 | }; 290 | 4BCB746A130B6D5800C3A701 /* Debug */ = { 291 | isa = XCBuildConfiguration; 292 | buildSettings = { 293 | ALWAYS_SEARCH_USER_PATHS = NO; 294 | COPY_PHASE_STRIP = NO; 295 | GCC_DYNAMIC_NO_PIC = NO; 296 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 297 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 298 | GCC_PREFIX_HEADER = "TestHarness/TestHarness-Prefix.pch"; 299 | HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../Source/libCloud/Cloud/**"; 300 | INFOPLIST_FILE = "TestHarness/TestHarness-Info.plist"; 301 | LIBRARY_SEARCH_PATHS = ( 302 | "$(inherited)", 303 | "\"$(SRCROOT)/../../../../../../Library/Developer/Xcode/DerivedData/Cloud-abtwsrtzrxyrskbxyjrwgmseiljc/Build/Products/Debug\"", 304 | ); 305 | OTHER_LDFLAGS = "-ObjC"; 306 | PRODUCT_NAME = "$(TARGET_NAME)"; 307 | WRAPPER_EXTENSION = app; 308 | }; 309 | name = Debug; 310 | }; 311 | 4BCB746B130B6D5800C3A701 /* Release */ = { 312 | isa = XCBuildConfiguration; 313 | buildSettings = { 314 | ALWAYS_SEARCH_USER_PATHS = NO; 315 | COPY_PHASE_STRIP = YES; 316 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 317 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 318 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 319 | GCC_PREFIX_HEADER = "TestHarness/TestHarness-Prefix.pch"; 320 | HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../Source/libCloud/Cloud/**"; 321 | INFOPLIST_FILE = "TestHarness/TestHarness-Info.plist"; 322 | LIBRARY_SEARCH_PATHS = ( 323 | "$(inherited)", 324 | "\"$(SRCROOT)/../../../../../../Library/Developer/Xcode/DerivedData/Cloud-abtwsrtzrxyrskbxyjrwgmseiljc/Build/Products/Debug\"", 325 | ); 326 | OTHER_LDFLAGS = "-ObjC"; 327 | PRODUCT_NAME = "$(TARGET_NAME)"; 328 | WRAPPER_EXTENSION = app; 329 | }; 330 | name = Release; 331 | }; 332 | /* End XCBuildConfiguration section */ 333 | 334 | /* Begin XCConfigurationList section */ 335 | 4BCB7445130B6D5700C3A701 /* Build configuration list for PBXProject "TestHarness" */ = { 336 | isa = XCConfigurationList; 337 | buildConfigurations = ( 338 | 4BCB7467130B6D5800C3A701 /* Debug */, 339 | 4BCB7468130B6D5800C3A701 /* Release */, 340 | ); 341 | defaultConfigurationIsVisible = 0; 342 | defaultConfigurationName = Release; 343 | }; 344 | 4BCB7469130B6D5800C3A701 /* Build configuration list for PBXNativeTarget "TestHarness" */ = { 345 | isa = XCConfigurationList; 346 | buildConfigurations = ( 347 | 4BCB746A130B6D5800C3A701 /* Debug */, 348 | 4BCB746B130B6D5800C3A701 /* Release */, 349 | ); 350 | defaultConfigurationIsVisible = 0; 351 | defaultConfigurationName = Release; 352 | }; 353 | /* End XCConfigurationList section */ 354 | }; 355 | rootObject = 4BCB7442130B6D5700C3A701 /* Project object */; 356 | } 357 | -------------------------------------------------------------------------------- /Extras/TestHarness.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Extras/TestHarness/TestHarness-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.linebreak.Cloud.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /Extras/TestHarness/TestHarness-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'TestHarness' target in the 'TestHarness' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /Extras/TestHarness/TestHarnessAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // TestHarnessAppDelegate.h 3 | // TestHarness 4 | // 5 | // Created by Nick Paulson on 2/15/11. 6 | // Copyright 2011 Linebreak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TestHarnessAppDelegate : NSObject { 12 | @private 13 | NSWindow *window; 14 | } 15 | 16 | @property (assign) IBOutlet NSWindow *window; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Extras/TestHarness/TestHarnessAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // TestHarnessAppDelegate.m 3 | // TestHarness 4 | // 5 | // Created by Nick Paulson on 2/15/11. 6 | // Copyright 2011 Linebreak. All rights reserved. 7 | // 8 | 9 | #import "TestHarnessAppDelegate.h" 10 | #import 11 | 12 | @interface TestHarnessAppDelegate () 13 | 14 | @end 15 | 16 | @implementation TestHarnessAppDelegate 17 | 18 | @synthesize window; 19 | 20 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 21 | CLAPIEngine *engine = [CLAPIEngine engineWithDelegate:self]; 22 | engine.email = @"user@email.com"; 23 | engine.password = @"password"; 24 | 25 | /* 26 | --------Upload File-------- 27 | NSString *fileLocation = [@"~/Desktop/SomeFile.txt" stringByExpandingTildeInPath]; 28 | [engine uploadFileWithName:[fileLocation lastPathComponent] fileData:[NSData dataWithContentsOfFile:fileLocation] userInfo:@"Uploads rock!"]; 29 | */ 30 | 31 | /* 32 | --------Get Recent Items-------- 33 | [engine getItemListStartingAtPage:1 itemsPerPage:5 userInfo:nil]; 34 | */ 35 | } 36 | 37 | - (void)requestDidFailWithError:(NSError *)error connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo { 38 | NSLog(@"[FAIL]: %@, %@", connectionIdentifier, error); 39 | } 40 | 41 | - (void)fileUploadDidProgress:(CGFloat)percentageComplete connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo { 42 | NSLog(@"[UPLOAD PROGRESS]: %@, %f", connectionIdentifier, percentageComplete); 43 | } 44 | 45 | - (void)fileUploadDidSucceedWithResultingItem:(CLWebItem *)item connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo { 46 | NSLog(@"[UPLOAD SUCCESS]: %@, %@", connectionIdentifier, item); 47 | } 48 | 49 | - (void)itemListRetrievalSucceeded:(NSArray *)items connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo { 50 | NSLog(@"[ITEM LIST]: %@, %@", connectionIdentifier, items); 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Extras/TestHarness/en.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} 2 | {\colortbl;\red255\green255\blue255;} 3 | \paperw9840\paperh8400 4 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 5 | 6 | \f0\b\fs24 \cf0 Engineering: 7 | \b0 \ 8 | Some people\ 9 | \ 10 | 11 | \b Human Interface Design: 12 | \b0 \ 13 | Some other people\ 14 | \ 15 | 16 | \b Testing: 17 | \b0 \ 18 | Hopefully not nobody\ 19 | \ 20 | 21 | \b Documentation: 22 | \b0 \ 23 | Whoever\ 24 | \ 25 | 26 | \b With special thanks to: 27 | \b0 \ 28 | Mom\ 29 | } 30 | -------------------------------------------------------------------------------- /Extras/TestHarness/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Extras/TestHarness/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // TestHarness 4 | // 5 | // Created by Nick Paulson on 2/15/11. 6 | // Copyright 2011 Linebreak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **)argv); 14 | } 15 | -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Linebreak S.L. 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 | 21 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4B08ABFB1391F7E600325181 /* adapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABDF1391F7E600325181 /* adapter.h */; }; 11 | 4B08ABFC1391F7E600325181 /* nameprep.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B08ABE01391F7E600325181 /* nameprep.c */; }; 12 | 4B08ABFD1391F7E600325181 /* nameprep.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABE11391F7E600325181 /* nameprep.h */; }; 13 | 4B08ABFE1391F7E600325181 /* puny.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B08ABE21391F7E600325181 /* puny.c */; }; 14 | 4B08ABFF1391F7E600325181 /* puny.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABE31391F7E600325181 /* puny.h */; }; 15 | 4B08AC001391F7E600325181 /* race.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B08ABE41391F7E600325181 /* race.c */; }; 16 | 4B08AC011391F7E600325181 /* race.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABE51391F7E600325181 /* race.h */; }; 17 | 4B08AC021391F7E600325181 /* nameprep_bidi_lcat.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABE71391F7E600325181 /* nameprep_bidi_lcat.h */; }; 18 | 4B08AC031391F7E600325181 /* nameprep_bidi_randalcat.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABE81391F7E600325181 /* nameprep_bidi_randalcat.h */; }; 19 | 4B08AC041391F7E600325181 /* nameprep_charmap.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABE91391F7E600325181 /* nameprep_charmap.h */; }; 20 | 4B08AC051391F7E600325181 /* nameprep_compatible.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABEA1391F7E600325181 /* nameprep_compatible.h */; }; 21 | 4B08AC061391F7E600325181 /* nameprep_compose.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABEB1391F7E600325181 /* nameprep_compose.h */; }; 22 | 4B08AC071391F7E600325181 /* nameprep_cononical.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABEC1391F7E600325181 /* nameprep_cononical.h */; }; 23 | 4B08AC081391F7E600325181 /* nameprep_data.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABED1391F7E600325181 /* nameprep_data.h */; }; 24 | 4B08AC091391F7E600325181 /* nameprep_datastructures.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABEE1391F7E600325181 /* nameprep_datastructures.h */; }; 25 | 4B08AC0A1391F7E600325181 /* nameprep_decompose.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABEF1391F7E600325181 /* nameprep_decompose.h */; }; 26 | 4B08AC0B1391F7E600325181 /* nameprep_lookups.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABF01391F7E600325181 /* nameprep_lookups.h */; }; 27 | 4B08AC0C1391F7E600325181 /* nameprep_prohibit.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABF11391F7E600325181 /* nameprep_prohibit.h */; }; 28 | 4B08AC0D1391F7E600325181 /* nameprep_prohibit_allowunassigned.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABF21391F7E600325181 /* nameprep_prohibit_allowunassigned.h */; }; 29 | 4B08AC0E1391F7E600325181 /* toxxx.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B08ABF31391F7E600325181 /* toxxx.c */; }; 30 | 4B08AC0F1391F7E600325181 /* toxxx.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABF41391F7E600325181 /* toxxx.h */; }; 31 | 4B08AC101391F7E600325181 /* util.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B08ABF51391F7E600325181 /* util.c */; }; 32 | 4B08AC111391F7E600325181 /* util.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABF61391F7E600325181 /* util.h */; }; 33 | 4B08AC121391F7E600325181 /* xcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABF71391F7E600325181 /* xcode.h */; }; 34 | 4B08AC131391F7E600325181 /* xcode_config.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABF81391F7E600325181 /* xcode_config.h */; }; 35 | 4B08AC141391F7E600325181 /* NSURL+IFUnicodeURL.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B08ABF91391F7E600325181 /* NSURL+IFUnicodeURL.h */; }; 36 | 4B08AC151391F7E600325181 /* NSURL+IFUnicodeURL.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B08ABFA1391F7E600325181 /* NSURL+IFUnicodeURL.m */; }; 37 | 4B1AB188130B69B900BD6A95 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1AB187130B69B900BD6A95 /* Cocoa.framework */; }; 38 | 4B1AB319130B69D100BD6A95 /* CLAPIDeserializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB196130B69CF00BD6A95 /* CLAPIDeserializer.h */; }; 39 | 4B1AB31A130B69D100BD6A95 /* CLAPIDeserializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB197130B69CF00BD6A95 /* CLAPIDeserializer.m */; }; 40 | 4B1AB31B130B69D100BD6A95 /* CLAPISerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB198130B69CF00BD6A95 /* CLAPISerializer.h */; }; 41 | 4B1AB31C130B69D100BD6A95 /* CLAPISerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB199130B69CF00BD6A95 /* CLAPISerializer.m */; }; 42 | 4B1AB31D130B69D100BD6A95 /* NSMutableURLRequest+NPPOSTBody.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB19B130B69CF00BD6A95 /* NSMutableURLRequest+NPPOSTBody.h */; }; 43 | 4B1AB31E130B69D100BD6A95 /* NSMutableURLRequest+NPPOSTBody.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB19C130B69CF00BD6A95 /* NSMutableURLRequest+NPPOSTBody.m */; }; 44 | 4B1AB31F130B69D100BD6A95 /* NSString+NPAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB19D130B69CF00BD6A95 /* NSString+NPAdditions.h */; }; 45 | 4B1AB320130B69D100BD6A95 /* NSString+NPAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB19E130B69CF00BD6A95 /* NSString+NPAdditions.m */; }; 46 | 4B1AB321130B69D100BD6A95 /* NSString+NPMimeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB19F130B69CF00BD6A95 /* NSString+NPMimeType.h */; }; 47 | 4B1AB322130B69D100BD6A95 /* NSString+NPMimeType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB1A0130B69CF00BD6A95 /* NSString+NPMimeType.m */; }; 48 | 4B1AB323130B69D100BD6A95 /* CLAPIEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB1A1130B69CF00BD6A95 /* CLAPIEngine.h */; }; 49 | 4B1AB324130B69D100BD6A95 /* CLAPIEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB1A2130B69CF00BD6A95 /* CLAPIEngine.m */; }; 50 | 4B1AB326130B69D100BD6A95 /* CLAPIEngineDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB1A4130B69CF00BD6A95 /* CLAPIEngineDelegate.h */; }; 51 | 4B1AB327130B69D100BD6A95 /* CLAPITransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB1A5130B69CF00BD6A95 /* CLAPITransaction.h */; }; 52 | 4B1AB328130B69D100BD6A95 /* CLAPITransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB1A6130B69CF00BD6A95 /* CLAPITransaction.m */; }; 53 | 4B1AB329130B69D100BD6A95 /* CLAccount.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB1A8130B69CF00BD6A95 /* CLAccount.h */; }; 54 | 4B1AB32A130B69D100BD6A95 /* CLAccount.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB1A9130B69CF00BD6A95 /* CLAccount.m */; }; 55 | 4B1AB32B130B69D100BD6A95 /* CLWebItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB1AA130B69CF00BD6A95 /* CLWebItem.h */; }; 56 | 4B1AB32C130B69D100BD6A95 /* CLWebItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB1AB130B69CF00BD6A95 /* CLWebItem.m */; }; 57 | 4B1AB532130B6AEA00BD6A95 /* JSON.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB51F130B6AEA00BD6A95 /* JSON.h */; }; 58 | 4B1AB533130B6AEA00BD6A95 /* NSObject+JSON.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB520130B6AEA00BD6A95 /* NSObject+JSON.h */; }; 59 | 4B1AB534130B6AEA00BD6A95 /* NSObject+JSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB521130B6AEA00BD6A95 /* NSObject+JSON.m */; }; 60 | 4B1AB535130B6AEA00BD6A95 /* SBJsonParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB522130B6AEA00BD6A95 /* SBJsonParser.h */; }; 61 | 4B1AB536130B6AEA00BD6A95 /* SBJsonParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB523130B6AEA00BD6A95 /* SBJsonParser.m */; }; 62 | 4B1AB537130B6AEA00BD6A95 /* SBJsonStreamParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB524130B6AEA00BD6A95 /* SBJsonStreamParser.h */; }; 63 | 4B1AB538130B6AEA00BD6A95 /* SBJsonStreamParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB525130B6AEA00BD6A95 /* SBJsonStreamParser.m */; }; 64 | 4B1AB539130B6AEA00BD6A95 /* SBJsonStreamParserAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB526130B6AEA00BD6A95 /* SBJsonStreamParserAdapter.h */; }; 65 | 4B1AB53A130B6AEA00BD6A95 /* SBJsonStreamParserAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB527130B6AEA00BD6A95 /* SBJsonStreamParserAdapter.m */; }; 66 | 4B1AB53B130B6AEA00BD6A95 /* SBJsonStreamParserState.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB528130B6AEA00BD6A95 /* SBJsonStreamParserState.h */; }; 67 | 4B1AB53C130B6AEA00BD6A95 /* SBJsonStreamParserState.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB529130B6AEA00BD6A95 /* SBJsonStreamParserState.m */; }; 68 | 4B1AB53D130B6AEA00BD6A95 /* SBJsonStreamWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB52A130B6AEA00BD6A95 /* SBJsonStreamWriter.h */; }; 69 | 4B1AB53E130B6AEA00BD6A95 /* SBJsonStreamWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB52B130B6AEA00BD6A95 /* SBJsonStreamWriter.m */; }; 70 | 4B1AB53F130B6AEA00BD6A95 /* SBJsonStreamWriterState.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB52C130B6AEA00BD6A95 /* SBJsonStreamWriterState.h */; }; 71 | 4B1AB540130B6AEA00BD6A95 /* SBJsonStreamWriterState.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB52D130B6AEA00BD6A95 /* SBJsonStreamWriterState.m */; }; 72 | 4B1AB541130B6AEA00BD6A95 /* SBJsonTokeniser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB52E130B6AEA00BD6A95 /* SBJsonTokeniser.h */; }; 73 | 4B1AB542130B6AEA00BD6A95 /* SBJsonTokeniser.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB52F130B6AEA00BD6A95 /* SBJsonTokeniser.m */; }; 74 | 4B1AB543130B6AEA00BD6A95 /* SBJsonWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB530130B6AEA00BD6A95 /* SBJsonWriter.h */; }; 75 | 4B1AB544130B6AEA00BD6A95 /* SBJsonWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1AB531130B6AEA00BD6A95 /* SBJsonWriter.m */; }; 76 | 4B1AB554130B6BE200BD6A95 /* Cloud.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1AB553130B6BE200BD6A95 /* Cloud.h */; settings = {ATTRIBUTES = (); }; }; 77 | 8CADDD3213715AFD00CBDDD1 /* CLAPIEngineConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CADDD3013715AFD00CBDDD1 /* CLAPIEngineConstants.h */; }; 78 | 8CADDD3313715AFD00CBDDD1 /* CLAPIEngineConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CADDD3113715AFD00CBDDD1 /* CLAPIEngineConstants.m */; }; 79 | 8CDB51DF1310924E00FDF09B /* CLSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CDB51DD1310924E00FDF09B /* CLSocket.h */; }; 80 | 8CDB51E01310924E00FDF09B /* CLSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CDB51DE1310924E00FDF09B /* CLSocket.m */; }; 81 | /* End PBXBuildFile section */ 82 | 83 | /* Begin PBXFileReference section */ 84 | 4B08ABDF1391F7E600325181 /* adapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adapter.h; sourceTree = ""; }; 85 | 4B08ABE01391F7E600325181 /* nameprep.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nameprep.c; sourceTree = ""; }; 86 | 4B08ABE11391F7E600325181 /* nameprep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nameprep.h; sourceTree = ""; }; 87 | 4B08ABE21391F7E600325181 /* puny.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = puny.c; sourceTree = ""; }; 88 | 4B08ABE31391F7E600325181 /* puny.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = puny.h; sourceTree = ""; }; 89 | 4B08ABE41391F7E600325181 /* race.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = race.c; sourceTree = ""; }; 90 | 4B08ABE51391F7E600325181 /* race.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = race.h; sourceTree = ""; }; 91 | 4B08ABE71391F7E600325181 /* nameprep_bidi_lcat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nameprep_bidi_lcat.h; sourceTree = ""; }; 92 | 4B08ABE81391F7E600325181 /* nameprep_bidi_randalcat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nameprep_bidi_randalcat.h; sourceTree = ""; }; 93 | 4B08ABE91391F7E600325181 /* nameprep_charmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nameprep_charmap.h; sourceTree = ""; }; 94 | 4B08ABEA1391F7E600325181 /* nameprep_compatible.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nameprep_compatible.h; sourceTree = ""; }; 95 | 4B08ABEB1391F7E600325181 /* nameprep_compose.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nameprep_compose.h; sourceTree = ""; }; 96 | 4B08ABEC1391F7E600325181 /* nameprep_cononical.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nameprep_cononical.h; sourceTree = ""; }; 97 | 4B08ABED1391F7E600325181 /* nameprep_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nameprep_data.h; sourceTree = ""; }; 98 | 4B08ABEE1391F7E600325181 /* nameprep_datastructures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nameprep_datastructures.h; sourceTree = ""; }; 99 | 4B08ABEF1391F7E600325181 /* nameprep_decompose.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nameprep_decompose.h; sourceTree = ""; }; 100 | 4B08ABF01391F7E600325181 /* nameprep_lookups.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nameprep_lookups.h; sourceTree = ""; }; 101 | 4B08ABF11391F7E600325181 /* nameprep_prohibit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nameprep_prohibit.h; sourceTree = ""; }; 102 | 4B08ABF21391F7E600325181 /* nameprep_prohibit_allowunassigned.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nameprep_prohibit_allowunassigned.h; sourceTree = ""; }; 103 | 4B08ABF31391F7E600325181 /* toxxx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = toxxx.c; sourceTree = ""; }; 104 | 4B08ABF41391F7E600325181 /* toxxx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = toxxx.h; sourceTree = ""; }; 105 | 4B08ABF51391F7E600325181 /* util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = util.c; sourceTree = ""; }; 106 | 4B08ABF61391F7E600325181 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = ""; }; 107 | 4B08ABF71391F7E600325181 /* xcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xcode.h; sourceTree = ""; }; 108 | 4B08ABF81391F7E600325181 /* xcode_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xcode_config.h; sourceTree = ""; }; 109 | 4B08ABF91391F7E600325181 /* NSURL+IFUnicodeURL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+IFUnicodeURL.h"; sourceTree = ""; }; 110 | 4B08ABFA1391F7E600325181 /* NSURL+IFUnicodeURL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+IFUnicodeURL.m"; sourceTree = ""; }; 111 | 4B1AB184130B69B900BD6A95 /* libCloud.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCloud.a; sourceTree = BUILT_PRODUCTS_DIR; }; 112 | 4B1AB187130B69B900BD6A95 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 113 | 4B1AB18A130B69B900BD6A95 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 114 | 4B1AB18B130B69B900BD6A95 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 115 | 4B1AB18C130B69B900BD6A95 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 116 | 4B1AB18F130B69B900BD6A95 /* Cloud-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Cloud-Prefix.pch"; sourceTree = ""; }; 117 | 4B1AB196130B69CF00BD6A95 /* CLAPIDeserializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLAPIDeserializer.h; sourceTree = ""; }; 118 | 4B1AB197130B69CF00BD6A95 /* CLAPIDeserializer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CLAPIDeserializer.m; sourceTree = ""; }; 119 | 4B1AB198130B69CF00BD6A95 /* CLAPISerializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLAPISerializer.h; sourceTree = ""; }; 120 | 4B1AB199130B69CF00BD6A95 /* CLAPISerializer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CLAPISerializer.m; sourceTree = ""; }; 121 | 4B1AB19B130B69CF00BD6A95 /* NSMutableURLRequest+NPPOSTBody.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableURLRequest+NPPOSTBody.h"; sourceTree = ""; }; 122 | 4B1AB19C130B69CF00BD6A95 /* NSMutableURLRequest+NPPOSTBody.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableURLRequest+NPPOSTBody.m"; sourceTree = ""; }; 123 | 4B1AB19D130B69CF00BD6A95 /* NSString+NPAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+NPAdditions.h"; sourceTree = ""; }; 124 | 4B1AB19E130B69CF00BD6A95 /* NSString+NPAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+NPAdditions.m"; sourceTree = ""; }; 125 | 4B1AB19F130B69CF00BD6A95 /* NSString+NPMimeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+NPMimeType.h"; sourceTree = ""; }; 126 | 4B1AB1A0130B69CF00BD6A95 /* NSString+NPMimeType.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+NPMimeType.m"; sourceTree = ""; }; 127 | 4B1AB1A1130B69CF00BD6A95 /* CLAPIEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLAPIEngine.h; sourceTree = ""; }; 128 | 4B1AB1A2130B69CF00BD6A95 /* CLAPIEngine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CLAPIEngine.m; sourceTree = ""; }; 129 | 4B1AB1A4130B69CF00BD6A95 /* CLAPIEngineDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLAPIEngineDelegate.h; sourceTree = ""; }; 130 | 4B1AB1A5130B69CF00BD6A95 /* CLAPITransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLAPITransaction.h; sourceTree = ""; }; 131 | 4B1AB1A6130B69CF00BD6A95 /* CLAPITransaction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CLAPITransaction.m; sourceTree = ""; }; 132 | 4B1AB1A8130B69CF00BD6A95 /* CLAccount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLAccount.h; sourceTree = ""; }; 133 | 4B1AB1A9130B69CF00BD6A95 /* CLAccount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CLAccount.m; sourceTree = ""; }; 134 | 4B1AB1AA130B69CF00BD6A95 /* CLWebItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLWebItem.h; sourceTree = ""; }; 135 | 4B1AB1AB130B69CF00BD6A95 /* CLWebItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CLWebItem.m; sourceTree = ""; }; 136 | 4B1AB51F130B6AEA00BD6A95 /* JSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSON.h; sourceTree = ""; }; 137 | 4B1AB520130B6AEA00BD6A95 /* NSObject+JSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+JSON.h"; sourceTree = ""; }; 138 | 4B1AB521130B6AEA00BD6A95 /* NSObject+JSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+JSON.m"; sourceTree = ""; }; 139 | 4B1AB522130B6AEA00BD6A95 /* SBJsonParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonParser.h; sourceTree = ""; }; 140 | 4B1AB523130B6AEA00BD6A95 /* SBJsonParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonParser.m; sourceTree = ""; }; 141 | 4B1AB524130B6AEA00BD6A95 /* SBJsonStreamParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonStreamParser.h; sourceTree = ""; }; 142 | 4B1AB525130B6AEA00BD6A95 /* SBJsonStreamParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonStreamParser.m; sourceTree = ""; }; 143 | 4B1AB526130B6AEA00BD6A95 /* SBJsonStreamParserAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonStreamParserAdapter.h; sourceTree = ""; }; 144 | 4B1AB527130B6AEA00BD6A95 /* SBJsonStreamParserAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonStreamParserAdapter.m; sourceTree = ""; }; 145 | 4B1AB528130B6AEA00BD6A95 /* SBJsonStreamParserState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonStreamParserState.h; sourceTree = ""; }; 146 | 4B1AB529130B6AEA00BD6A95 /* SBJsonStreamParserState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonStreamParserState.m; sourceTree = ""; }; 147 | 4B1AB52A130B6AEA00BD6A95 /* SBJsonStreamWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonStreamWriter.h; sourceTree = ""; }; 148 | 4B1AB52B130B6AEA00BD6A95 /* SBJsonStreamWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonStreamWriter.m; sourceTree = ""; }; 149 | 4B1AB52C130B6AEA00BD6A95 /* SBJsonStreamWriterState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonStreamWriterState.h; sourceTree = ""; }; 150 | 4B1AB52D130B6AEA00BD6A95 /* SBJsonStreamWriterState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonStreamWriterState.m; sourceTree = ""; }; 151 | 4B1AB52E130B6AEA00BD6A95 /* SBJsonTokeniser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonTokeniser.h; sourceTree = ""; }; 152 | 4B1AB52F130B6AEA00BD6A95 /* SBJsonTokeniser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonTokeniser.m; sourceTree = ""; }; 153 | 4B1AB530130B6AEA00BD6A95 /* SBJsonWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonWriter.h; sourceTree = ""; }; 154 | 4B1AB531130B6AEA00BD6A95 /* SBJsonWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonWriter.m; sourceTree = ""; }; 155 | 4B1AB553130B6BE200BD6A95 /* Cloud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cloud.h; sourceTree = ""; }; 156 | 8CADDD3013715AFD00CBDDD1 /* CLAPIEngineConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLAPIEngineConstants.h; sourceTree = ""; }; 157 | 8CADDD3113715AFD00CBDDD1 /* CLAPIEngineConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CLAPIEngineConstants.m; sourceTree = ""; }; 158 | 8CDB51DD1310924E00FDF09B /* CLSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLSocket.h; sourceTree = ""; }; 159 | 8CDB51DE1310924E00FDF09B /* CLSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CLSocket.m; sourceTree = ""; }; 160 | /* End PBXFileReference section */ 161 | 162 | /* Begin PBXFrameworksBuildPhase section */ 163 | 4B1AB181130B69B900BD6A95 /* Frameworks */ = { 164 | isa = PBXFrameworksBuildPhase; 165 | buildActionMask = 2147483647; 166 | files = ( 167 | 4B1AB188130B69B900BD6A95 /* Cocoa.framework in Frameworks */, 168 | ); 169 | runOnlyForDeploymentPostprocessing = 0; 170 | }; 171 | /* End PBXFrameworksBuildPhase section */ 172 | 173 | /* Begin PBXGroup section */ 174 | 4B08ABDD1391F7E600325181 /* IFUnicodeURL */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | 4B08ABDE1391F7E600325181 /* IDNSDK */, 178 | 4B08ABF91391F7E600325181 /* NSURL+IFUnicodeURL.h */, 179 | 4B08ABFA1391F7E600325181 /* NSURL+IFUnicodeURL.m */, 180 | ); 181 | name = IFUnicodeURL; 182 | path = IFUnicodeURL/IFUnicodeURL; 183 | sourceTree = ""; 184 | }; 185 | 4B08ABDE1391F7E600325181 /* IDNSDK */ = { 186 | isa = PBXGroup; 187 | children = ( 188 | 4B08ABDF1391F7E600325181 /* adapter.h */, 189 | 4B08ABE01391F7E600325181 /* nameprep.c */, 190 | 4B08ABE11391F7E600325181 /* nameprep.h */, 191 | 4B08ABE21391F7E600325181 /* puny.c */, 192 | 4B08ABE31391F7E600325181 /* puny.h */, 193 | 4B08ABE41391F7E600325181 /* race.c */, 194 | 4B08ABE51391F7E600325181 /* race.h */, 195 | 4B08ABE61391F7E600325181 /* staticdata */, 196 | 4B08ABF31391F7E600325181 /* toxxx.c */, 197 | 4B08ABF41391F7E600325181 /* toxxx.h */, 198 | 4B08ABF51391F7E600325181 /* util.c */, 199 | 4B08ABF61391F7E600325181 /* util.h */, 200 | 4B08ABF71391F7E600325181 /* xcode.h */, 201 | 4B08ABF81391F7E600325181 /* xcode_config.h */, 202 | ); 203 | path = IDNSDK; 204 | sourceTree = ""; 205 | }; 206 | 4B08ABE61391F7E600325181 /* staticdata */ = { 207 | isa = PBXGroup; 208 | children = ( 209 | 4B08ABE71391F7E600325181 /* nameprep_bidi_lcat.h */, 210 | 4B08ABE81391F7E600325181 /* nameprep_bidi_randalcat.h */, 211 | 4B08ABE91391F7E600325181 /* nameprep_charmap.h */, 212 | 4B08ABEA1391F7E600325181 /* nameprep_compatible.h */, 213 | 4B08ABEB1391F7E600325181 /* nameprep_compose.h */, 214 | 4B08ABEC1391F7E600325181 /* nameprep_cononical.h */, 215 | 4B08ABED1391F7E600325181 /* nameprep_data.h */, 216 | 4B08ABEE1391F7E600325181 /* nameprep_datastructures.h */, 217 | 4B08ABEF1391F7E600325181 /* nameprep_decompose.h */, 218 | 4B08ABF01391F7E600325181 /* nameprep_lookups.h */, 219 | 4B08ABF11391F7E600325181 /* nameprep_prohibit.h */, 220 | 4B08ABF21391F7E600325181 /* nameprep_prohibit_allowunassigned.h */, 221 | ); 222 | path = staticdata; 223 | sourceTree = ""; 224 | }; 225 | 4B1AB179130B69B900BD6A95 = { 226 | isa = PBXGroup; 227 | children = ( 228 | 4B1AB18D130B69B900BD6A95 /* Cloud */, 229 | 4B1AB186130B69B900BD6A95 /* Frameworks */, 230 | 4B1AB185130B69B900BD6A95 /* Products */, 231 | ); 232 | sourceTree = ""; 233 | }; 234 | 4B1AB185130B69B900BD6A95 /* Products */ = { 235 | isa = PBXGroup; 236 | children = ( 237 | 4B1AB184130B69B900BD6A95 /* libCloud.a */, 238 | ); 239 | name = Products; 240 | sourceTree = ""; 241 | }; 242 | 4B1AB186130B69B900BD6A95 /* Frameworks */ = { 243 | isa = PBXGroup; 244 | children = ( 245 | 4B1AB187130B69B900BD6A95 /* Cocoa.framework */, 246 | 4B1AB189130B69B900BD6A95 /* Other Frameworks */, 247 | ); 248 | name = Frameworks; 249 | sourceTree = ""; 250 | }; 251 | 4B1AB189130B69B900BD6A95 /* Other Frameworks */ = { 252 | isa = PBXGroup; 253 | children = ( 254 | 4B1AB18A130B69B900BD6A95 /* AppKit.framework */, 255 | 4B1AB18B130B69B900BD6A95 /* CoreData.framework */, 256 | 4B1AB18C130B69B900BD6A95 /* Foundation.framework */, 257 | ); 258 | name = "Other Frameworks"; 259 | sourceTree = ""; 260 | }; 261 | 4B1AB18D130B69B900BD6A95 /* Cloud */ = { 262 | isa = PBXGroup; 263 | children = ( 264 | 4B1AB553130B6BE200BD6A95 /* Cloud.h */, 265 | 4B1AB195130B69CF00BD6A95 /* API Parsing */, 266 | 4B1AB19A130B69CF00BD6A95 /* Categories */, 267 | 4B1AB1A1130B69CF00BD6A95 /* CLAPIEngine.h */, 268 | 4B1AB1A2130B69CF00BD6A95 /* CLAPIEngine.m */, 269 | 8CADDD3013715AFD00CBDDD1 /* CLAPIEngineConstants.h */, 270 | 8CADDD3113715AFD00CBDDD1 /* CLAPIEngineConstants.m */, 271 | 4B1AB1A4130B69CF00BD6A95 /* CLAPIEngineDelegate.h */, 272 | 4B1AB1A5130B69CF00BD6A95 /* CLAPITransaction.h */, 273 | 4B1AB1A6130B69CF00BD6A95 /* CLAPITransaction.m */, 274 | 4B1AB1A7130B69CF00BD6A95 /* Model */, 275 | 4B1AB1AC130B69CF00BD6A95 /* Third Party */, 276 | 4B1AB18E130B69B900BD6A95 /* Supporting Files */, 277 | ); 278 | path = Cloud; 279 | sourceTree = ""; 280 | }; 281 | 4B1AB18E130B69B900BD6A95 /* Supporting Files */ = { 282 | isa = PBXGroup; 283 | children = ( 284 | 4B1AB18F130B69B900BD6A95 /* Cloud-Prefix.pch */, 285 | ); 286 | name = "Supporting Files"; 287 | sourceTree = ""; 288 | }; 289 | 4B1AB195130B69CF00BD6A95 /* API Parsing */ = { 290 | isa = PBXGroup; 291 | children = ( 292 | 4B1AB196130B69CF00BD6A95 /* CLAPIDeserializer.h */, 293 | 4B1AB197130B69CF00BD6A95 /* CLAPIDeserializer.m */, 294 | 4B1AB198130B69CF00BD6A95 /* CLAPISerializer.h */, 295 | 4B1AB199130B69CF00BD6A95 /* CLAPISerializer.m */, 296 | ); 297 | path = "API Parsing"; 298 | sourceTree = ""; 299 | }; 300 | 4B1AB19A130B69CF00BD6A95 /* Categories */ = { 301 | isa = PBXGroup; 302 | children = ( 303 | 4B1AB19B130B69CF00BD6A95 /* NSMutableURLRequest+NPPOSTBody.h */, 304 | 4B1AB19C130B69CF00BD6A95 /* NSMutableURLRequest+NPPOSTBody.m */, 305 | 4B1AB19D130B69CF00BD6A95 /* NSString+NPAdditions.h */, 306 | 4B1AB19E130B69CF00BD6A95 /* NSString+NPAdditions.m */, 307 | 4B1AB19F130B69CF00BD6A95 /* NSString+NPMimeType.h */, 308 | 4B1AB1A0130B69CF00BD6A95 /* NSString+NPMimeType.m */, 309 | ); 310 | path = Categories; 311 | sourceTree = ""; 312 | }; 313 | 4B1AB1A7130B69CF00BD6A95 /* Model */ = { 314 | isa = PBXGroup; 315 | children = ( 316 | 4B1AB1A8130B69CF00BD6A95 /* CLAccount.h */, 317 | 4B1AB1A9130B69CF00BD6A95 /* CLAccount.m */, 318 | 4B1AB1AA130B69CF00BD6A95 /* CLWebItem.h */, 319 | 4B1AB1AB130B69CF00BD6A95 /* CLWebItem.m */, 320 | 8CDB51DD1310924E00FDF09B /* CLSocket.h */, 321 | 8CDB51DE1310924E00FDF09B /* CLSocket.m */, 322 | ); 323 | path = Model; 324 | sourceTree = ""; 325 | }; 326 | 4B1AB1AC130B69CF00BD6A95 /* Third Party */ = { 327 | isa = PBXGroup; 328 | children = ( 329 | 4B08ABDD1391F7E600325181 /* IFUnicodeURL */, 330 | 4B1AB51E130B6AEA00BD6A95 /* JSON */, 331 | ); 332 | path = "Third Party"; 333 | sourceTree = ""; 334 | }; 335 | 4B1AB51E130B6AEA00BD6A95 /* JSON */ = { 336 | isa = PBXGroup; 337 | children = ( 338 | 4B1AB51F130B6AEA00BD6A95 /* JSON.h */, 339 | 4B1AB520130B6AEA00BD6A95 /* NSObject+JSON.h */, 340 | 4B1AB521130B6AEA00BD6A95 /* NSObject+JSON.m */, 341 | 4B1AB522130B6AEA00BD6A95 /* SBJsonParser.h */, 342 | 4B1AB523130B6AEA00BD6A95 /* SBJsonParser.m */, 343 | 4B1AB524130B6AEA00BD6A95 /* SBJsonStreamParser.h */, 344 | 4B1AB525130B6AEA00BD6A95 /* SBJsonStreamParser.m */, 345 | 4B1AB526130B6AEA00BD6A95 /* SBJsonStreamParserAdapter.h */, 346 | 4B1AB527130B6AEA00BD6A95 /* SBJsonStreamParserAdapter.m */, 347 | 4B1AB528130B6AEA00BD6A95 /* SBJsonStreamParserState.h */, 348 | 4B1AB529130B6AEA00BD6A95 /* SBJsonStreamParserState.m */, 349 | 4B1AB52A130B6AEA00BD6A95 /* SBJsonStreamWriter.h */, 350 | 4B1AB52B130B6AEA00BD6A95 /* SBJsonStreamWriter.m */, 351 | 4B1AB52C130B6AEA00BD6A95 /* SBJsonStreamWriterState.h */, 352 | 4B1AB52D130B6AEA00BD6A95 /* SBJsonStreamWriterState.m */, 353 | 4B1AB52E130B6AEA00BD6A95 /* SBJsonTokeniser.h */, 354 | 4B1AB52F130B6AEA00BD6A95 /* SBJsonTokeniser.m */, 355 | 4B1AB530130B6AEA00BD6A95 /* SBJsonWriter.h */, 356 | 4B1AB531130B6AEA00BD6A95 /* SBJsonWriter.m */, 357 | ); 358 | name = JSON; 359 | path = JSON/Classes; 360 | sourceTree = ""; 361 | }; 362 | /* End PBXGroup section */ 363 | 364 | /* Begin PBXHeadersBuildPhase section */ 365 | 4B1AB182130B69B900BD6A95 /* Headers */ = { 366 | isa = PBXHeadersBuildPhase; 367 | buildActionMask = 2147483647; 368 | files = ( 369 | 4B1AB554130B6BE200BD6A95 /* Cloud.h in Headers */, 370 | 4B1AB319130B69D100BD6A95 /* CLAPIDeserializer.h in Headers */, 371 | 4B1AB31B130B69D100BD6A95 /* CLAPISerializer.h in Headers */, 372 | 4B1AB31D130B69D100BD6A95 /* NSMutableURLRequest+NPPOSTBody.h in Headers */, 373 | 4B1AB31F130B69D100BD6A95 /* NSString+NPAdditions.h in Headers */, 374 | 4B1AB321130B69D100BD6A95 /* NSString+NPMimeType.h in Headers */, 375 | 4B1AB323130B69D100BD6A95 /* CLAPIEngine.h in Headers */, 376 | 4B1AB326130B69D100BD6A95 /* CLAPIEngineDelegate.h in Headers */, 377 | 4B1AB327130B69D100BD6A95 /* CLAPITransaction.h in Headers */, 378 | 4B1AB329130B69D100BD6A95 /* CLAccount.h in Headers */, 379 | 4B1AB32B130B69D100BD6A95 /* CLWebItem.h in Headers */, 380 | 4B1AB532130B6AEA00BD6A95 /* JSON.h in Headers */, 381 | 4B1AB533130B6AEA00BD6A95 /* NSObject+JSON.h in Headers */, 382 | 4B1AB535130B6AEA00BD6A95 /* SBJsonParser.h in Headers */, 383 | 4B1AB537130B6AEA00BD6A95 /* SBJsonStreamParser.h in Headers */, 384 | 4B1AB539130B6AEA00BD6A95 /* SBJsonStreamParserAdapter.h in Headers */, 385 | 4B1AB53B130B6AEA00BD6A95 /* SBJsonStreamParserState.h in Headers */, 386 | 4B1AB53D130B6AEA00BD6A95 /* SBJsonStreamWriter.h in Headers */, 387 | 4B1AB53F130B6AEA00BD6A95 /* SBJsonStreamWriterState.h in Headers */, 388 | 4B1AB541130B6AEA00BD6A95 /* SBJsonTokeniser.h in Headers */, 389 | 4B1AB543130B6AEA00BD6A95 /* SBJsonWriter.h in Headers */, 390 | 8CDB51DF1310924E00FDF09B /* CLSocket.h in Headers */, 391 | 8CADDD3213715AFD00CBDDD1 /* CLAPIEngineConstants.h in Headers */, 392 | 4B08ABFB1391F7E600325181 /* adapter.h in Headers */, 393 | 4B08ABFD1391F7E600325181 /* nameprep.h in Headers */, 394 | 4B08ABFF1391F7E600325181 /* puny.h in Headers */, 395 | 4B08AC011391F7E600325181 /* race.h in Headers */, 396 | 4B08AC021391F7E600325181 /* nameprep_bidi_lcat.h in Headers */, 397 | 4B08AC031391F7E600325181 /* nameprep_bidi_randalcat.h in Headers */, 398 | 4B08AC041391F7E600325181 /* nameprep_charmap.h in Headers */, 399 | 4B08AC051391F7E600325181 /* nameprep_compatible.h in Headers */, 400 | 4B08AC061391F7E600325181 /* nameprep_compose.h in Headers */, 401 | 4B08AC071391F7E600325181 /* nameprep_cononical.h in Headers */, 402 | 4B08AC081391F7E600325181 /* nameprep_data.h in Headers */, 403 | 4B08AC091391F7E600325181 /* nameprep_datastructures.h in Headers */, 404 | 4B08AC0A1391F7E600325181 /* nameprep_decompose.h in Headers */, 405 | 4B08AC0B1391F7E600325181 /* nameprep_lookups.h in Headers */, 406 | 4B08AC0C1391F7E600325181 /* nameprep_prohibit.h in Headers */, 407 | 4B08AC0D1391F7E600325181 /* nameprep_prohibit_allowunassigned.h in Headers */, 408 | 4B08AC0F1391F7E600325181 /* toxxx.h in Headers */, 409 | 4B08AC111391F7E600325181 /* util.h in Headers */, 410 | 4B08AC121391F7E600325181 /* xcode.h in Headers */, 411 | 4B08AC131391F7E600325181 /* xcode_config.h in Headers */, 412 | 4B08AC141391F7E600325181 /* NSURL+IFUnicodeURL.h in Headers */, 413 | ); 414 | runOnlyForDeploymentPostprocessing = 0; 415 | }; 416 | /* End PBXHeadersBuildPhase section */ 417 | 418 | /* Begin PBXNativeTarget section */ 419 | 4B1AB183130B69B900BD6A95 /* Cloud */ = { 420 | isa = PBXNativeTarget; 421 | buildConfigurationList = 4B1AB192130B69B900BD6A95 /* Build configuration list for PBXNativeTarget "Cloud" */; 422 | buildPhases = ( 423 | 4B1AB180130B69B900BD6A95 /* Sources */, 424 | 4B1AB181130B69B900BD6A95 /* Frameworks */, 425 | 4B1AB182130B69B900BD6A95 /* Headers */, 426 | ); 427 | buildRules = ( 428 | ); 429 | dependencies = ( 430 | ); 431 | name = Cloud; 432 | productName = Cloud; 433 | productReference = 4B1AB184130B69B900BD6A95 /* libCloud.a */; 434 | productType = "com.apple.product-type.library.static"; 435 | }; 436 | /* End PBXNativeTarget section */ 437 | 438 | /* Begin PBXProject section */ 439 | 4B1AB17B130B69B900BD6A95 /* Project object */ = { 440 | isa = PBXProject; 441 | attributes = { 442 | LastUpgradeCheck = 0420; 443 | ORGANIZATIONNAME = Linebreak; 444 | }; 445 | buildConfigurationList = 4B1AB17E130B69B900BD6A95 /* Build configuration list for PBXProject "Cloud" */; 446 | compatibilityVersion = "Xcode 3.2"; 447 | developmentRegion = English; 448 | hasScannedForEncodings = 0; 449 | knownRegions = ( 450 | en, 451 | English, 452 | ); 453 | mainGroup = 4B1AB179130B69B900BD6A95; 454 | productRefGroup = 4B1AB185130B69B900BD6A95 /* Products */; 455 | projectDirPath = ""; 456 | projectRoot = ""; 457 | targets = ( 458 | 4B1AB183130B69B900BD6A95 /* Cloud */, 459 | ); 460 | }; 461 | /* End PBXProject section */ 462 | 463 | /* Begin PBXSourcesBuildPhase section */ 464 | 4B1AB180130B69B900BD6A95 /* Sources */ = { 465 | isa = PBXSourcesBuildPhase; 466 | buildActionMask = 2147483647; 467 | files = ( 468 | 4B1AB31A130B69D100BD6A95 /* CLAPIDeserializer.m in Sources */, 469 | 4B1AB31C130B69D100BD6A95 /* CLAPISerializer.m in Sources */, 470 | 4B1AB31E130B69D100BD6A95 /* NSMutableURLRequest+NPPOSTBody.m in Sources */, 471 | 4B1AB320130B69D100BD6A95 /* NSString+NPAdditions.m in Sources */, 472 | 4B1AB322130B69D100BD6A95 /* NSString+NPMimeType.m in Sources */, 473 | 4B1AB324130B69D100BD6A95 /* CLAPIEngine.m in Sources */, 474 | 4B1AB328130B69D100BD6A95 /* CLAPITransaction.m in Sources */, 475 | 4B1AB32A130B69D100BD6A95 /* CLAccount.m in Sources */, 476 | 4B1AB32C130B69D100BD6A95 /* CLWebItem.m in Sources */, 477 | 4B1AB534130B6AEA00BD6A95 /* NSObject+JSON.m in Sources */, 478 | 4B1AB536130B6AEA00BD6A95 /* SBJsonParser.m in Sources */, 479 | 4B1AB538130B6AEA00BD6A95 /* SBJsonStreamParser.m in Sources */, 480 | 4B1AB53A130B6AEA00BD6A95 /* SBJsonStreamParserAdapter.m in Sources */, 481 | 4B1AB53C130B6AEA00BD6A95 /* SBJsonStreamParserState.m in Sources */, 482 | 4B1AB53E130B6AEA00BD6A95 /* SBJsonStreamWriter.m in Sources */, 483 | 4B1AB540130B6AEA00BD6A95 /* SBJsonStreamWriterState.m in Sources */, 484 | 4B1AB542130B6AEA00BD6A95 /* SBJsonTokeniser.m in Sources */, 485 | 4B1AB544130B6AEA00BD6A95 /* SBJsonWriter.m in Sources */, 486 | 8CDB51E01310924E00FDF09B /* CLSocket.m in Sources */, 487 | 8CADDD3313715AFD00CBDDD1 /* CLAPIEngineConstants.m in Sources */, 488 | 4B08ABFC1391F7E600325181 /* nameprep.c in Sources */, 489 | 4B08ABFE1391F7E600325181 /* puny.c in Sources */, 490 | 4B08AC001391F7E600325181 /* race.c in Sources */, 491 | 4B08AC0E1391F7E600325181 /* toxxx.c in Sources */, 492 | 4B08AC101391F7E600325181 /* util.c in Sources */, 493 | 4B08AC151391F7E600325181 /* NSURL+IFUnicodeURL.m in Sources */, 494 | ); 495 | runOnlyForDeploymentPostprocessing = 0; 496 | }; 497 | /* End PBXSourcesBuildPhase section */ 498 | 499 | /* Begin XCBuildConfiguration section */ 500 | 4B1AB190130B69B900BD6A95 /* Debug */ = { 501 | isa = XCBuildConfiguration; 502 | buildSettings = { 503 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 504 | GCC_C_LANGUAGE_STANDARD = gnu99; 505 | GCC_OPTIMIZATION_LEVEL = 0; 506 | GCC_PREPROCESSOR_DEFINITIONS = DEBUG; 507 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 508 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 509 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 510 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 511 | GCC_WARN_UNUSED_VARIABLE = YES; 512 | MACOSX_DEPLOYMENT_TARGET = 10.6; 513 | ONLY_ACTIVE_ARCH = YES; 514 | SDKROOT = macosx; 515 | }; 516 | name = Debug; 517 | }; 518 | 4B1AB191130B69B900BD6A95 /* Release */ = { 519 | isa = XCBuildConfiguration; 520 | buildSettings = { 521 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 522 | GCC_C_LANGUAGE_STANDARD = gnu99; 523 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 524 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 525 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 526 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 527 | GCC_WARN_UNUSED_VARIABLE = YES; 528 | MACOSX_DEPLOYMENT_TARGET = 10.6; 529 | SDKROOT = macosx; 530 | }; 531 | name = Release; 532 | }; 533 | 4B1AB193130B69B900BD6A95 /* Debug */ = { 534 | isa = XCBuildConfiguration; 535 | buildSettings = { 536 | ALWAYS_SEARCH_USER_PATHS = NO; 537 | COPY_PHASE_STRIP = NO; 538 | GCC_DYNAMIC_NO_PIC = NO; 539 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 540 | GCC_ENABLE_OBJC_GC = unsupported; 541 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 542 | GCC_PREFIX_HEADER = "Cloud/Cloud-Prefix.pch"; 543 | MACOSX_DEPLOYMENT_TARGET = 10.5; 544 | PRODUCT_NAME = "$(TARGET_NAME)"; 545 | SKIP_INSTALL = YES; 546 | }; 547 | name = Debug; 548 | }; 549 | 4B1AB194130B69B900BD6A95 /* Release */ = { 550 | isa = XCBuildConfiguration; 551 | buildSettings = { 552 | ALWAYS_SEARCH_USER_PATHS = NO; 553 | COPY_PHASE_STRIP = YES; 554 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 555 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 556 | GCC_ENABLE_OBJC_GC = unsupported; 557 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 558 | GCC_PREFIX_HEADER = "Cloud/Cloud-Prefix.pch"; 559 | MACOSX_DEPLOYMENT_TARGET = 10.5; 560 | PRODUCT_NAME = "$(TARGET_NAME)"; 561 | SKIP_INSTALL = YES; 562 | }; 563 | name = Release; 564 | }; 565 | /* End XCBuildConfiguration section */ 566 | 567 | /* Begin XCConfigurationList section */ 568 | 4B1AB17E130B69B900BD6A95 /* Build configuration list for PBXProject "Cloud" */ = { 569 | isa = XCConfigurationList; 570 | buildConfigurations = ( 571 | 4B1AB190130B69B900BD6A95 /* Debug */, 572 | 4B1AB191130B69B900BD6A95 /* Release */, 573 | ); 574 | defaultConfigurationIsVisible = 0; 575 | defaultConfigurationName = Release; 576 | }; 577 | 4B1AB192130B69B900BD6A95 /* Build configuration list for PBXNativeTarget "Cloud" */ = { 578 | isa = XCConfigurationList; 579 | buildConfigurations = ( 580 | 4B1AB193130B69B900BD6A95 /* Debug */, 581 | 4B1AB194130B69B900BD6A95 /* Release */, 582 | ); 583 | defaultConfigurationIsVisible = 0; 584 | defaultConfigurationName = Release; 585 | }; 586 | /* End XCConfigurationList section */ 587 | }; 588 | rootObject = 4B1AB17B130B69B900BD6A95 /* Project object */; 589 | } 590 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud.xcodeproj/xcuserdata/nickpaulson.xcuserdatad/xcschemes/Cloud.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 14 | 20 | 21 | 22 | 23 | 24 | 29 | 30 | 31 | 32 | 40 | 41 | 42 | 43 | 50 | 51 | 53 | 54 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud.xcodeproj/xcuserdata/nickpaulson.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Cloud.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 4B1AB183130B69B900BD6A95 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/API Parsing/CLAPIDeserializer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLAPIDeserializer.h 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 12/29/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CLAPIEngineConstants.h" 11 | 12 | 13 | @class CLWebItem, CLAccount, CLSocket; 14 | 15 | 16 | @interface CLAPIDeserializer : NSObject { 17 | 18 | } 19 | 20 | + (NSArray *)webItemArrayWithJSONArrayData:(NSData *)jsonData; 21 | + (NSArray *)webItemArrayWithAPIArray:(NSArray *)arrayOfAPIDicts; 22 | + (CLWebItem *)webItemWithJSONDictionaryData:(NSData *)jsonData; 23 | + (CLWebItem *)webItemWithAPIDictionary:(NSDictionary *)jsonDict; 24 | + (CLAccount *)accountWithJSONDictionaryData:(NSData *)jsonData; 25 | + (CLAccount *)accountWithAPIDictionary:(NSDictionary *)accountDict; 26 | + (CLSocket *)socketWithJSONDictionaryData:(NSData *)jsonData; 27 | + (CLSocket *)socketWithJSONDictionary:(NSDictionary *)jsonDict; 28 | + (CLWebItemType)webItemTypeForTypeString:(NSString *)typeString; 29 | + (NSURLRequest *)URLRequestWithS3ParametersDictionaryData:(NSData *)jsonData fileName:(NSString *)fileName fileData:(NSData *)fileData; 30 | + (NSURLRequest *)URLRequestWithS3ParametersDictionary:(NSDictionary *)s3Dict fileName:(NSString *)fileName fileData:(NSData *)fileData; 31 | + (NSArray *)productsWithJSONArrayData:(NSData *)jsonData; 32 | 33 | + (NSDictionary *)dictionaryFromJSONData:(NSData *)data; 34 | + (NSArray *)arrayFromJSONData:(NSData *)data; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/API Parsing/CLAPIDeserializer.m: -------------------------------------------------------------------------------- 1 | // 2 | // CLAPIDeserializer.m 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 12/29/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import "CLAPIDeserializer.h" 10 | #import "CLWebItem.h" 11 | #import "CLAccount.h" 12 | #import "CLSocket.h" 13 | #import "JSON.h" 14 | #import "NSMutableURLRequest+NPPOSTBody.h" 15 | #import "NSString+NPMimeType.h" 16 | #import "NSURL+IFUnicodeURL.h" 17 | 18 | 19 | @interface CLAPIDeserializer (Private) 20 | 21 | + (id)_normalizedObjectFromDictionary:(NSDictionary *)dict forKey:(NSString *)key; // NSNull -> nil 22 | + (NSDate *)_dateAndTimeFromDictionary:(NSDictionary *)dict forKey:(NSString *)key; 23 | + (NSDate *)_dateFromDictionary:(NSDictionary *)dict forKey:(NSString *)key; 24 | + (NSURL *)_URLFromDictionary:(NSDictionary *)dict forKey:(NSString *)key; 25 | + (NSURL *)_unicodeURLFromDictionary:(NSDictionary *)dict forKey:(NSString *)key; 26 | 27 | @end 28 | 29 | 30 | @implementation CLAPIDeserializer 31 | 32 | + (CLAccount *)accountWithJSONDictionaryData:(NSData *)jsonData 33 | { 34 | NSDictionary *dict = [self dictionaryFromJSONData:jsonData]; 35 | if (dict == nil) 36 | return nil; 37 | 38 | return [self accountWithAPIDictionary:dict]; 39 | } 40 | 41 | + (CLAccount *)accountWithAPIDictionary:(NSDictionary *)accountDict 42 | { 43 | CLAccount *account = [CLAccount accountWithEmail:[self _normalizedObjectFromDictionary:accountDict forKey:@"email"]]; 44 | account.domain = [self _unicodeURLFromDictionary:accountDict forKey:@"domain"]; 45 | account.domainHomePage = [self _unicodeURLFromDictionary:accountDict forKey:@"domain_home_page"]; 46 | account.uploadsArePrivate = [[self _normalizedObjectFromDictionary:accountDict forKey:@"private_items"] boolValue]; 47 | account.type = [[self _normalizedObjectFromDictionary:accountDict forKey:@"subscribed"] boolValue] ? CLAccountTypePro : CLAccountTypeFree; 48 | account.subscriptionExpiresAt = [self _dateFromDictionary:accountDict forKey:@"subscription_expires_at"]; 49 | account.alphaUser = [[self _normalizedObjectFromDictionary:accountDict forKey:@"alpha"] boolValue]; 50 | 51 | // Socket 52 | NSDictionary *socketDict = [self _normalizedObjectFromDictionary:accountDict forKey:@"socket"]; 53 | account.socket = [self socketWithJSONDictionary:socketDict]; 54 | 55 | return account; 56 | } 57 | 58 | + (CLSocket *)socketWithJSONDictionaryData:(NSData *)jsonData 59 | { 60 | NSDictionary *dict = [self dictionaryFromJSONData:jsonData]; 61 | if (dict == nil) 62 | return nil; 63 | 64 | return [self socketWithJSONDictionary:dict]; 65 | } 66 | 67 | + (CLSocket *)socketWithJSONDictionary:(NSDictionary *)jsonDict 68 | { 69 | if (jsonDict == nil) { 70 | return nil; 71 | } 72 | 73 | CLSocket *socket = [[[CLSocket alloc] init] autorelease]; 74 | socket.APIKey = [self _normalizedObjectFromDictionary:jsonDict forKey:@"api_key"]; 75 | socket.appID = [[self _normalizedObjectFromDictionary:jsonDict forKey:@"app_id"] intValue]; 76 | socket.authURL = [self _URLFromDictionary:jsonDict forKey:@"auth_url"]; 77 | 78 | // Channels 79 | NSDictionary *channels = [self _normalizedObjectFromDictionary:jsonDict forKey:@"channels"]; 80 | if (channels != nil && [channels isKindOfClass:[NSDictionary class]]) { 81 | socket.channels = channels; 82 | } else { 83 | socket.channels = nil; 84 | } 85 | 86 | return socket; 87 | } 88 | 89 | + (NSArray *)webItemArrayWithJSONArrayData:(NSData *)jsonData 90 | { 91 | NSArray *array = [self arrayFromJSONData:jsonData]; 92 | if (array == nil) 93 | return nil; 94 | 95 | return [self webItemArrayWithAPIArray:array]; 96 | } 97 | 98 | + (NSArray *)webItemArrayWithAPIArray:(NSArray *)arrayOfAPIDicts 99 | { 100 | NSMutableArray *retArray = [NSMutableArray arrayWithCapacity:[arrayOfAPIDicts count]]; 101 | for (NSDictionary *apiDict in arrayOfAPIDicts) { 102 | [retArray addObject:[self webItemWithAPIDictionary:apiDict]]; 103 | } 104 | 105 | return [NSArray arrayWithArray:retArray]; 106 | } 107 | 108 | + (CLWebItem *)webItemWithJSONDictionaryData:(NSData *)jsonData 109 | { 110 | NSDictionary *dict = [self dictionaryFromJSONData:jsonData]; 111 | if (dict == nil) 112 | return nil; 113 | 114 | return [self webItemWithAPIDictionary:dict]; 115 | } 116 | 117 | + (CLWebItem *)webItemWithAPIDictionary:(NSDictionary *)jsonDict 118 | { 119 | CLWebItem *webItem = [CLWebItem webItem]; 120 | 121 | webItem.name = [self _normalizedObjectFromDictionary:jsonDict forKey:@"name"]; 122 | webItem.type = [self webItemTypeForTypeString:[self _normalizedObjectFromDictionary:jsonDict forKey:@"item_type"]]; 123 | webItem.viewCount = [[self _normalizedObjectFromDictionary:jsonDict forKey:@"view_counter"] integerValue]; 124 | 125 | if (webItem.type == CLWebItemTypeBookmark) { 126 | webItem.remoteURL = [self _unicodeURLFromDictionary:jsonDict forKey:@"redirect_url"]; 127 | if (webItem.name == nil) { 128 | // Use the remote URL if the item has no name 129 | webItem.name = [webItem.remoteURL unicodeAbsoluteString]; 130 | } 131 | } else { 132 | webItem.remoteURL = [self _URLFromDictionary:jsonDict forKey:@"remote_url"]; 133 | } 134 | 135 | webItem.URL = [self _unicodeURLFromDictionary:jsonDict forKey:@"url"]; 136 | webItem.href = [self _URLFromDictionary:jsonDict forKey:@"href"]; 137 | webItem.iconURL = [self _URLFromDictionary:jsonDict forKey:@"icon"]; 138 | webItem.private = [[self _normalizedObjectFromDictionary:jsonDict forKey:@"private"] boolValue]; 139 | webItem.createdAt = [self _dateAndTimeFromDictionary:jsonDict forKey:@"created_at"]; 140 | webItem.updatedAt = [self _dateAndTimeFromDictionary:jsonDict forKey:@"updated_at"]; 141 | webItem.deletedAt = [self _dateAndTimeFromDictionary:jsonDict forKey:@"deleted_at"]; 142 | webItem.trashed = webItem.deletedAt == nil ? NO : YES; 143 | 144 | return webItem; 145 | } 146 | 147 | + (CLWebItemType)webItemTypeForTypeString:(NSString *)typeString 148 | { 149 | typeString = [typeString lowercaseString]; 150 | CLWebItemType retType = CLWebItemTypeUnknown; 151 | 152 | if ([typeString isEqualToString:@"archive"]) { 153 | retType = CLWebItemTypeArchive; 154 | } else if ([typeString isEqualToString:@"audio"]) { 155 | retType = CLWebItemTypeAudio; 156 | } else if ([typeString isEqualToString:@"video"]) { 157 | retType = CLWebItemTypeVideo; 158 | } else if ([typeString isEqualToString:@"text"]) { 159 | retType = CLWebItemTypeText; 160 | } else if ([typeString isEqualToString:@"bookmark"]) { 161 | retType = CLWebItemTypeBookmark; 162 | } else if ([typeString isEqualToString:@"image"]) { 163 | retType = CLWebItemTypeImage; 164 | } 165 | 166 | return retType; 167 | } 168 | 169 | + (NSURLRequest *)URLRequestWithS3ParametersDictionaryData:(NSData *)jsonData fileName:(NSString *)fileName fileData:(NSData *)fileData 170 | { 171 | NSDictionary *dict = [self dictionaryFromJSONData:jsonData]; 172 | if (dict == nil) 173 | return nil; 174 | 175 | return [self URLRequestWithS3ParametersDictionary:dict fileName:fileName fileData:fileData]; 176 | } 177 | 178 | + (NSURLRequest *)URLRequestWithS3ParametersDictionary:(NSDictionary *)s3Dict fileName:(NSString *)fileName fileData:(NSData *)fileData 179 | { 180 | // Make sure to combine any decomposed pieces of any unicode characters (may be diacritical marks) into precomposed characters 181 | fileName = [fileName precomposedStringWithCanonicalMapping]; 182 | 183 | NSURL *postURL = [self _URLFromDictionary:s3Dict forKey:@"url"]; 184 | NSDictionary *actualParams = [self _normalizedObjectFromDictionary:s3Dict forKey:@"params"]; 185 | if ([[postURL absoluteString] length] == 0 || [[actualParams allKeys] count] == 0) 186 | return nil; 187 | 188 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:postURL]; 189 | [request setHTTPMethod:@"POST"]; 190 | [request addValue:@"application/json" forHTTPHeaderField:@"Accept"]; 191 | [request addValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@; charset=UTF-8", NPHTTPBoundary] forHTTPHeaderField:@"Content-Type"]; 192 | 193 | for (NSString *currKey in [actualParams allKeys]) { 194 | [request addToHTTPBodyValue:[actualParams objectForKey:currKey] forKey:currKey]; 195 | } 196 | 197 | [request addToHTTPBodyFileData:fileData fileName:fileName mimeType:[fileName mimeType] forKey:@"file"]; 198 | [request finalizeHTTPBody]; 199 | 200 | return request; 201 | } 202 | 203 | + (NSArray *)productsWithJSONArrayData:(NSData *)jsonData 204 | { 205 | NSArray *array = [self arrayFromJSONData:jsonData]; 206 | return array; 207 | } 208 | 209 | #pragma mark - 210 | #pragma mark General 211 | 212 | + (NSDictionary *)dictionaryFromJSONData:(NSData *)data 213 | { 214 | if (data == nil || [data length] == 0) 215 | return nil; 216 | 217 | NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 218 | id object = [jsonString JSONValue]; 219 | [jsonString release]; 220 | 221 | if (object == nil || ![object isKindOfClass:[NSDictionary class]]) 222 | return nil; 223 | 224 | return object; 225 | } 226 | 227 | + (NSArray *)arrayFromJSONData:(NSData *)data 228 | { 229 | if (data == nil || [data length] == 0) 230 | return nil; 231 | 232 | NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 233 | id object = [jsonString JSONValue]; 234 | [jsonString release]; 235 | 236 | if (object == nil || ![object isKindOfClass:[NSArray class]]) 237 | return nil; 238 | 239 | return object; 240 | } 241 | 242 | #pragma mark - 243 | #pragma mark Private 244 | 245 | + (id)_normalizedObjectFromDictionary:(NSDictionary *)dict forKey:(NSString *)key 246 | { 247 | id object = [dict objectForKey:key]; 248 | if (object == [NSNull null]) 249 | return nil; 250 | 251 | return object; 252 | } 253 | 254 | + (NSDate *)_dateAndTimeFromDictionary:(NSDictionary *)dict forKey:(NSString *)key 255 | { 256 | // Date parsing 257 | static NSDateFormatter *dateFormatter = nil; 258 | if (dateFormatter == nil) { 259 | dateFormatter = [[NSDateFormatter alloc] init]; 260 | 261 | // Set locale to US to avoid formatting issues 262 | NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"US"]; 263 | [dateFormatter setLocale:locale]; 264 | [locale release]; 265 | 266 | [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; // GMT timezone 267 | [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; // example: 2010-06-21T12:51:06Z 268 | } 269 | 270 | NSString *dateString = [dict objectForKey:key]; 271 | if (dateString == nil || ![dateString isKindOfClass:[NSString class]]) { 272 | // Invalid date 273 | return nil; 274 | } 275 | 276 | return [dateFormatter dateFromString:dateString]; 277 | } 278 | 279 | + (NSDate *)_dateFromDictionary:(NSDictionary *)dict forKey:(NSString *)key 280 | { 281 | // Date parsing 282 | static NSDateFormatter *dateFormatter = nil; 283 | if (dateFormatter == nil) { 284 | dateFormatter = [[NSDateFormatter alloc] init]; 285 | 286 | // Set locale to US to avoid formatting issues 287 | NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"US"]; 288 | [dateFormatter setLocale:locale]; 289 | [locale release]; 290 | 291 | [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; // GMT timezone 292 | [dateFormatter setDateFormat:@"yyyy-MM-dd"]; // example: 2010-06-21T12:51:06Z 293 | } 294 | 295 | NSString *dateString = [dict objectForKey:key]; 296 | if (dateString == nil || ![dateString isKindOfClass:[NSString class]]) { 297 | // Invalid date 298 | return nil; 299 | } 300 | 301 | return [dateFormatter dateFromString:dateString]; 302 | } 303 | 304 | + (NSURL *)_URLFromDictionary:(NSDictionary *)dict forKey:(NSString *)key 305 | { 306 | NSString *string = [dict objectForKey:key]; 307 | if (string == nil || ![string isKindOfClass:[NSString class]]) 308 | return nil; 309 | 310 | return [NSURL URLWithString:string]; 311 | } 312 | 313 | + (NSURL *)_unicodeURLFromDictionary:(NSDictionary *)dict forKey:(NSString *)key 314 | { 315 | NSString *string = [dict objectForKey:key]; 316 | if (string == nil || ![string isKindOfClass:[NSString class]]) 317 | return nil; 318 | 319 | return [NSURL URLWithUnicodeString:string]; 320 | } 321 | 322 | @end 323 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/API Parsing/CLAPISerializer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLAPISerializer.h 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 12/29/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CLAPIEngineConstants.h" 11 | 12 | 13 | @interface CLAPISerializer : NSObject { 14 | 15 | } 16 | 17 | + (NSString *)webItemTypeStringForType:(CLWebItemType)theType; 18 | + (NSData *)accountWithEmail:(NSString *)email password:(NSString *)password acceptTerms:(BOOL)acceptTerms; 19 | + (NSData *)itemWithName:(NSString *)newName; 20 | + (NSData *)itemWithPrivate:(BOOL)isPrivate; 21 | + (NSData *)itemForRestore; 22 | + (NSData *)bookmarkWithURL:(NSURL *)URL name:(NSString *)name; 23 | + (NSData *)bookmarkWithURL:(NSURL *)URL name:(NSString *)name private:(BOOL)private; 24 | + (NSData *)receiptWithBase64String:(NSString *)base64String; 25 | 26 | + (NSData *)JSONDataFromDictionary:(NSDictionary *)dict; 27 | + (NSData *)JSONDataFromArray:(NSArray *)array; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/API Parsing/CLAPISerializer.m: -------------------------------------------------------------------------------- 1 | // 2 | // CLAPISerializer.m 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 12/29/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import "CLAPISerializer.h" 10 | #import "JSON.h" 11 | 12 | 13 | @implementation CLAPISerializer 14 | 15 | + (NSString *)webItemTypeStringForType:(CLWebItemType)theType 16 | { 17 | NSString *retString = nil; 18 | switch (theType) { 19 | case CLWebItemTypeArchive: 20 | retString = @"archive"; 21 | break; 22 | case CLWebItemTypeAudio: 23 | retString = @"audio"; 24 | break; 25 | case CLWebItemTypeVideo: 26 | retString = @"video"; 27 | break; 28 | case CLWebItemTypeText: 29 | retString = @"text"; 30 | break; 31 | case CLWebItemTypeBookmark: 32 | retString = @"bookmark"; 33 | break; 34 | case CLWebItemTypeImage: 35 | retString = @"image"; 36 | break; 37 | case CLWebItemTypeUnknown: 38 | default: 39 | retString = @"unknown"; 40 | break; 41 | } 42 | return retString; 43 | } 44 | 45 | + (NSData *)accountWithEmail:(NSString *)email password:(NSString *)password acceptTerms:(BOOL)acceptTerms 46 | { 47 | if (email == nil || password == nil) 48 | return nil; 49 | 50 | NSNumber *acceptTermsObj = [NSNumber numberWithBool:acceptTerms]; 51 | NSDictionary *user = [NSDictionary dictionaryWithObjectsAndKeys:email, @"email", 52 | password, @"password", 53 | acceptTermsObj, @"accept_tos", nil]; 54 | NSDictionary *dict = [NSDictionary dictionaryWithObject:user forKey:@"user"]; 55 | 56 | return [self JSONDataFromDictionary:dict]; 57 | } 58 | 59 | + (NSData *)itemWithName:(NSString *)newName 60 | { 61 | if (newName == nil) 62 | return nil; 63 | 64 | NSDictionary *item = [NSDictionary dictionaryWithObject:newName forKey:@"name"]; 65 | NSDictionary *dict = [NSDictionary dictionaryWithObject:item forKey:@"item"]; 66 | 67 | return [self JSONDataFromDictionary:dict]; 68 | } 69 | 70 | + (NSData *)itemWithPrivate:(BOOL)isPrivate 71 | { 72 | NSDictionary *item = [NSDictionary dictionaryWithObject:isPrivate ? @"true" : @"false" forKey:@"private"]; 73 | NSDictionary *dict = [NSDictionary dictionaryWithObject:item forKey:@"item"]; 74 | 75 | return [self JSONDataFromDictionary:dict]; 76 | } 77 | 78 | + (NSData *)itemForRestore 79 | { 80 | NSDictionary *item = [NSDictionary dictionaryWithObject:[NSNull null] forKey:@"deleted_at"]; 81 | NSDictionary *container = [NSDictionary dictionaryWithObjectsAndKeys:item, @"item", 82 | [NSNumber numberWithBool:YES], @"deleted", nil]; 83 | return [self JSONDataFromDictionary:container]; 84 | } 85 | 86 | + (NSData *)bookmarkWithURL:(NSURL *)URL name:(NSString *)name 87 | { 88 | if (URL == nil || name == nil) 89 | return nil; 90 | 91 | NSDictionary *item = [NSDictionary dictionaryWithObjectsAndKeys:[URL absoluteString], @"redirect_url", 92 | name, @"name", nil]; 93 | NSDictionary *dict = [NSDictionary dictionaryWithObject:item forKey:@"item"]; 94 | return [self JSONDataFromDictionary:dict]; 95 | } 96 | 97 | + (NSData *)bookmarkWithURL:(NSURL *)URL name:(NSString *)name private:(BOOL)private 98 | { 99 | if (URL == nil || name == nil) 100 | return nil; 101 | 102 | NSString *privateString = private ? @"true" : @"false"; 103 | NSDictionary *item = [NSDictionary dictionaryWithObjectsAndKeys:[URL absoluteString], @"redirect_url", 104 | name, @"name", privateString, @"private", nil]; 105 | NSDictionary *dict = [NSDictionary dictionaryWithObject:item forKey:@"item"]; 106 | return [self JSONDataFromDictionary:dict]; 107 | } 108 | 109 | + (NSData *)receiptWithBase64String:(NSString *)base64String 110 | { 111 | NSDictionary *receipt = [NSDictionary dictionaryWithObject:base64String 112 | forKey:@"receipt-data"]; 113 | return [self JSONDataFromDictionary:receipt]; 114 | } 115 | 116 | #pragma mark - 117 | #pragma mark General 118 | 119 | + (NSData *)JSONDataFromDictionary:(NSDictionary *)dict 120 | { 121 | if (dict == nil || ![dict isKindOfClass:[NSDictionary class]]) 122 | return nil; 123 | 124 | NSString *jsonString = [dict JSONRepresentation]; 125 | if (jsonString == nil) 126 | return nil; 127 | 128 | return [jsonString dataUsingEncoding:NSUTF8StringEncoding]; 129 | } 130 | 131 | + (NSData *)JSONDataFromArray:(NSArray *)array 132 | { 133 | if (array == nil || ![array isKindOfClass:[NSArray class]]) 134 | return nil; 135 | 136 | NSString *jsonString = [array JSONRepresentation]; 137 | if (jsonString == nil) 138 | return nil; 139 | 140 | return [jsonString dataUsingEncoding:NSUTF8StringEncoding]; 141 | } 142 | 143 | @end 144 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/CLAPIEngine.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLAPIEngine.h 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 7/20/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CLAPIEngineDelegate.h" 11 | #import "CLAPIEngineConstants.h" 12 | #import "CLWebItem.h" 13 | #import "CLAccount.h" 14 | 15 | // Upload options 16 | extern NSString *const CLAPIEngineUploadOptionPrivacyKey; // Value is CLAPIEnginePrivacyOptionPrivate or CLAPIEnginePrivacyOptionPublic 17 | 18 | extern NSString *const CLAPIEnginePrivacyOptionPrivate; 19 | extern NSString *const CLAPIEnginePrivacyOptionPublic; 20 | 21 | @interface CLAPIEngine : NSObject { 22 | NSString *_email; 23 | NSString *_password; 24 | NSURL *_baseURL; 25 | id _delegate; 26 | 27 | NSMutableSet *_transactions; 28 | 29 | BOOL _clearsCookies; 30 | } 31 | 32 | @property (nonatomic, readwrite, copy) NSString *email; 33 | @property (nonatomic, readwrite, copy) NSString *password; 34 | @property (nonatomic, readwrite, assign) id delegate; 35 | @property (nonatomic, readwrite, retain) NSURL *baseURL; 36 | @property (nonatomic, readwrite, retain) NSMutableSet *transactions; 37 | 38 | // This property makes the engine clear the cookies before making a new connection. 39 | // This can be helpful when credentials are "stuck." 40 | @property (nonatomic, readwrite, assign) BOOL clearsCookies; 41 | 42 | - (id)initWithDelegate:(id)aDelegate; 43 | + (id)engine; 44 | + (id)engineWithDelegate:(id)aDelegate; 45 | 46 | // Returns whether or not the email/password fields are complete. 47 | - (BOOL)isReady; 48 | 49 | // Base URL for connections, usually http://my.cl.ly/ 50 | + (NSURL *)defaultBaseURL; 51 | 52 | // Cancel the connection with identifier 53 | - (void)cancelConnection:(NSString *)connectionIdentifier; 54 | 55 | // Cancel all connections 56 | - (void)cancelAllConnections; 57 | 58 | - (id)userInfoForConnectionIdentifier:(NSString *)identifier; 59 | - (CLAPIRequestType)requestTypeForConnectionIdentifier:(NSString *)identifier; 60 | 61 | - (NSString *)createAccountWithEmail:(NSString *)accountEmail password:(NSString *)accountPassword acceptTerms:(BOOL)acceptTerms userInfo:(id)userInfo; 62 | - (NSString *)changePrivacyOfItem:(CLWebItem *)webItem toPrivate:(BOOL)isPrivate userInfo:(id)userInfo; 63 | - (NSString *)changePrivacyOfItemAtHref:(NSURL *)href toPrivate:(BOOL)isPrivate userInfo:(id)userInfo; 64 | - (NSString *)changeNameOfItem:(CLWebItem *)webItem toName:(NSString *)newName userInfo:(id)userInfo; 65 | - (NSString *)changeNameOfItemAtHref:(NSURL *)href toName:(NSString *)newName userInfo:(id)userInfo; 66 | - (NSString *)getAccountInformationWithUserInfo:(id)userInfo; 67 | - (NSString *)getItemInformation:(CLWebItem *)item userInfo:(id)userInfo; 68 | - (NSString *)getItemInformationAtURL:(NSURL *)itemURL userInfo:(id)userInfo; 69 | - (NSString *)bookmarkLinkWithURL:(NSURL *)URL name:(NSString *)name userInfo:(id)userInfo; 70 | - (NSString *)uploadFileWithName:(NSString *)fileName fileData:(NSData *)fileData userInfo:(id)userInfo; 71 | - (NSString *)bookmarkLinkWithURL:(NSURL *)URL name:(NSString *)name options:(NSDictionary *)options userInfo:(id)userInfo; 72 | - (NSString *)uploadFileWithName:(NSString *)fileName fileData:(NSData *)fileData options:(NSDictionary *)options userInfo:(id)userInfo; 73 | - (NSString *)deleteItem:(CLWebItem *)webItem userInfo:(id)userInfo; 74 | - (NSString *)deleteItemAtHref:(NSURL *)href userInfo:(id)userInfo; 75 | - (NSString *)restoreItem:(CLWebItem *)webItem userInfo:(id)userInfo; 76 | - (NSString *)restoreItemAtHref:(NSURL *)href userInfo:(id)userInfo; 77 | - (NSString *)getItemListStartingAtPage:(NSInteger)pageNumStartingAtOne itemsPerPage:(NSInteger)perPage userInfo:(id)userInfo; 78 | - (NSString *)getItemListStartingAtPage:(NSInteger)pageNumStartingAtOne ofType:(CLWebItemType)type itemsPerPage:(NSInteger)perPage userInfo:(id)userInfo; 79 | - (NSString *)getItemListStartingAtPage:(NSInteger)pageNumStartingAtOne ofType:(CLWebItemType)type itemsPerPage:(NSInteger)perPage showOnlyItemsInTrash:(BOOL)showOnlyItemsInTrash userInfo:(id)userInfo; 80 | 81 | - (NSString *)getStoreProductsWithUserInfo:(id)userInfo; 82 | - (NSString *)redeemStoreReceipt:(NSString *)base64Receipt userInfo:(id)userInfo; 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/CLAPIEngine.m: -------------------------------------------------------------------------------- 1 | // 2 | // CLAPIEngine.m 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 7/20/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import "CLAPIEngine.h" 10 | #import "CLWebItem.h" 11 | #import "CLAPITransaction.h" 12 | #import "CLAPIDeserializer.h" 13 | #import "CLAPISerializer.h" 14 | #import "NSString+NPAdditions.h" 15 | 16 | 17 | static NSString *_CLAPIEngineBaseURL = @"http://my.cl.ly"; 18 | 19 | NSString *const CLAPIEngineUploadOptionPrivacyKey = @"CLAPIEngineUploadOptionPrivacy"; // Value is CLAPIEnginePrivacyOptionPrivate or CLAPIEnginePrivacyOptionPublic 20 | 21 | NSString *const CLAPIEnginePrivacyOptionPrivate = @"private"; 22 | NSString *const CLAPIEnginePrivacyOptionPublic = @"public"; 23 | 24 | 25 | @interface CLAPIEngine () 26 | 27 | - (NSURL *)_URLWithPath:(NSString *)path; 28 | 29 | - (NSString *)_createAndStartConnectionForTransaction:(CLAPITransaction *)transaction; 30 | - (CLAPITransaction *)_transactionForConnection:(NSURLConnection *)connection; 31 | - (CLAPITransaction *)_transactionForConnectionIdentifier:(NSString *)connectionIdentifier; 32 | 33 | @end 34 | 35 | 36 | @implementation CLAPIEngine 37 | 38 | @synthesize email = _email, password = _password, delegate = _delegate, baseURL = _baseURL, clearsCookies = _clearsCookies, 39 | transactions = _transactions; 40 | 41 | + (void)initialize 42 | { 43 | if (self == [CLAPIEngine class]) { 44 | // This is for testing against another server. 45 | NSString *possibleURL = [[NSUserDefaults standardUserDefaults] objectForKey:@"CloudAppBaseURL"]; 46 | if ([possibleURL length] > 0) 47 | _CLAPIEngineBaseURL = possibleURL; 48 | } 49 | } 50 | 51 | - (id)init 52 | { 53 | return [self initWithDelegate:nil]; 54 | } 55 | 56 | - (id)initWithDelegate:(id)aDelegate 57 | { 58 | if ((self = [super init])) { 59 | _delegate = aDelegate; 60 | _transactions = [[NSMutableSet alloc] init]; 61 | _clearsCookies = NO; 62 | _baseURL = [[[self class] defaultBaseURL] retain]; 63 | } 64 | return self; 65 | } 66 | 67 | + (id)engine 68 | { 69 | return [[[[self class] alloc] init] autorelease]; 70 | } 71 | 72 | + (id)engineWithDelegate:(id)aDelegate 73 | { 74 | return [[[[self class] alloc] initWithDelegate:aDelegate] autorelease]; 75 | } 76 | 77 | - (BOOL)isReady 78 | { 79 | return (self.email != nil && [self.email length] > 0 && self.password != nil && [self.password length] > 0); 80 | } 81 | 82 | + (NSURL *)defaultBaseURL 83 | { 84 | return [NSURL URLWithString:_CLAPIEngineBaseURL]; 85 | } 86 | 87 | #pragma mark - Actions 88 | 89 | - (NSString *)createAccountWithEmail:(NSString *)accountEmail password:(NSString *)accountPassword acceptTerms:(BOOL)acceptTerms userInfo:(id)userInfo 90 | { 91 | if (accountEmail == nil || accountPassword == nil) 92 | return nil; 93 | 94 | CLAPITransaction *transaction = [CLAPITransaction transaction]; 95 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[self _URLWithPath:@"/register"]]; 96 | [request setHTTPMethod:@"POST"]; 97 | [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 98 | [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 99 | 100 | NSData *bodyData = [CLAPISerializer accountWithEmail:accountEmail 101 | password:accountPassword 102 | acceptTerms:acceptTerms]; 103 | if (bodyData == nil) 104 | return nil; 105 | 106 | [request setHTTPBody:bodyData]; 107 | 108 | transaction.request = request; 109 | transaction.identifier = [NSString uniqueString]; 110 | transaction.requestType = CLAPIRequestTypeCreateAccount; 111 | transaction.userInfo = userInfo; 112 | 113 | return [self _createAndStartConnectionForTransaction:transaction]; 114 | } 115 | 116 | - (NSString *)changeNameOfItem:(CLWebItem *)webItem toName:(NSString *)newName userInfo:(id)userInfo 117 | { 118 | if (![self isReady] || webItem == nil || webItem.href == nil) 119 | return nil; 120 | 121 | CLAPITransaction *transaction = [CLAPITransaction transaction]; 122 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:webItem.href]; 123 | [request setHTTPMethod:@"PUT"]; 124 | [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 125 | [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 126 | 127 | NSData *bodyData = [CLAPISerializer itemWithName:newName]; 128 | if (bodyData == nil) 129 | return nil; 130 | 131 | [request setHTTPBody:bodyData]; 132 | 133 | transaction.request = request; 134 | transaction.identifier = [NSString uniqueString]; 135 | transaction.requestType = CLAPIRequestTypeItemUpdateName; 136 | transaction.userInfo = userInfo; 137 | 138 | return [self _createAndStartConnectionForTransaction:transaction]; 139 | } 140 | 141 | - (NSString *)changeNameOfItemAtHref:(NSURL *)href toName:(NSString *)newName userInfo:(id)userInfo 142 | { 143 | CLWebItem *webItem = [CLWebItem webItem]; 144 | webItem.href = href; 145 | 146 | return [self changeNameOfItem:webItem toName:newName userInfo:userInfo]; 147 | } 148 | 149 | - (NSString *)changePrivacyOfItem:(CLWebItem *)webItem toPrivate:(BOOL)isPrivate userInfo:(id)userInfo 150 | { 151 | if (![self isReady] || webItem == nil || webItem.href == nil) 152 | return nil; 153 | 154 | CLAPITransaction *transaction = [CLAPITransaction transaction]; 155 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:webItem.href]; 156 | [request setHTTPMethod:@"PUT"]; 157 | [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 158 | [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 159 | 160 | NSData *bodyData = [CLAPISerializer itemWithPrivate:isPrivate]; 161 | if (bodyData == nil) 162 | return nil; 163 | 164 | [request setHTTPBody:bodyData]; 165 | 166 | transaction.request = request; 167 | transaction.identifier = [NSString uniqueString]; 168 | transaction.requestType = CLAPIRequestTypeItemUpdatePrivacy; 169 | transaction.userInfo = userInfo; 170 | 171 | return [self _createAndStartConnectionForTransaction:transaction]; 172 | } 173 | 174 | - (NSString *)changePrivacyOfItemAtHref:(NSURL *)href toPrivate:(BOOL)isPrivate userInfo:(id)userInfo 175 | { 176 | CLWebItem *webItem = [CLWebItem webItem]; 177 | webItem.href = href; 178 | 179 | return [self changePrivacyOfItem:webItem toPrivate:isPrivate userInfo:userInfo]; 180 | } 181 | 182 | - (NSString *)getAccountInformationWithUserInfo:(id)userInfo 183 | { 184 | if (![self isReady]) 185 | return nil; 186 | 187 | CLAPITransaction *transaction = [CLAPITransaction transaction]; 188 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[self _URLWithPath:@"/account"]]; 189 | [request setHTTPMethod:@"GET"]; 190 | [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 191 | [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData]; 192 | 193 | transaction.request = request; 194 | transaction.identifier = [NSString uniqueString]; 195 | transaction.requestType = CLAPIRequestTypeGetAccountInformation; 196 | transaction.userInfo = userInfo; 197 | 198 | return [self _createAndStartConnectionForTransaction:transaction]; 199 | } 200 | 201 | - (NSString *)bookmarkLinkWithURL:(NSURL *)URL name:(NSString *)name userInfo:(id)userInfo 202 | { 203 | return [self bookmarkLinkWithURL:URL name:name options:nil userInfo:userInfo]; 204 | } 205 | 206 | - (NSString *)bookmarkLinkWithURL:(NSURL *)URL name:(NSString *)name options:(NSDictionary *)options userInfo:(id)userInfo 207 | { 208 | if (![self isReady] || [[URL absoluteString] length] == 0) 209 | return nil; 210 | 211 | if ([name length] == 0) 212 | name = [URL absoluteString]; 213 | 214 | CLAPITransaction *transaction = [CLAPITransaction transaction]; 215 | 216 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[self _URLWithPath:@"/items"]]; 217 | [request setHTTPMethod:@"POST"]; 218 | [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 219 | [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 220 | 221 | NSData *bodyData = nil; 222 | 223 | if ([options.allKeys containsObject:CLAPIEngineUploadOptionPrivacyKey]) { 224 | NSString *privacySetting = [options objectForKey:CLAPIEngineUploadOptionPrivacyKey]; 225 | if ([privacySetting isEqualToString:CLAPIEnginePrivacyOptionPublic]) { 226 | bodyData = [CLAPISerializer bookmarkWithURL:URL name:name private:NO]; 227 | } else if ([privacySetting isEqualToString:CLAPIEnginePrivacyOptionPrivate]) { 228 | bodyData = [CLAPISerializer bookmarkWithURL:URL name:name private:YES]; 229 | } else { 230 | bodyData = [CLAPISerializer bookmarkWithURL:URL name:name]; 231 | } 232 | } else { 233 | bodyData = [CLAPISerializer bookmarkWithURL:URL name:name]; 234 | } 235 | if (bodyData == nil) 236 | return nil; 237 | 238 | [request setHTTPBody:bodyData]; 239 | 240 | transaction.request = request; 241 | transaction.identifier = [NSString uniqueString]; 242 | transaction.requestType = CLAPIRequestTypeLinkBookmark; 243 | transaction.userInfo = userInfo; 244 | 245 | return [self _createAndStartConnectionForTransaction:transaction]; 246 | } 247 | 248 | - (NSString *)restoreItem:(CLWebItem *)webItem userInfo:(id)userInfo 249 | { 250 | if (![self isReady] || webItem == nil || webItem.href == nil) 251 | return nil; 252 | 253 | CLAPITransaction *transaction = [CLAPITransaction transaction]; 254 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:webItem.href]; 255 | [request setHTTPMethod:@"PUT"]; 256 | [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 257 | [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 258 | 259 | NSData *bodyData = [CLAPISerializer itemForRestore]; 260 | if (bodyData == nil) 261 | return nil; 262 | 263 | [request setHTTPBody:bodyData]; 264 | 265 | transaction.request = request; 266 | transaction.identifier = [NSString uniqueString]; 267 | transaction.requestType = CLAPIRequestTypeItemRestoration; 268 | transaction.userInfo = userInfo; 269 | 270 | return [self _createAndStartConnectionForTransaction:transaction]; 271 | } 272 | 273 | - (NSString *)restoreItemAtHref:(NSURL *)href userInfo:(id)userInfo 274 | { 275 | CLWebItem *tempItem = [CLWebItem webItem]; 276 | tempItem.href = href; 277 | 278 | return [self restoreItem:tempItem userInfo:userInfo]; 279 | } 280 | 281 | - (NSString *)deleteItem:(CLWebItem *)webItem userInfo:(id)userInfo 282 | { 283 | if (![self isReady] || webItem == nil || webItem.href == nil) 284 | return nil; 285 | 286 | CLAPITransaction *transaction = [CLAPITransaction transaction]; 287 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:webItem.href]; 288 | [request setHTTPMethod:@"DELETE"]; 289 | [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 290 | 291 | transaction.request = request; 292 | transaction.identifier = [NSString uniqueString]; 293 | transaction.requestType = CLAPIRequestTypeItemDeletion; 294 | transaction.userInfo = userInfo; 295 | 296 | return [self _createAndStartConnectionForTransaction:transaction]; 297 | } 298 | 299 | - (NSString *)getItemInformationAtURL:(NSURL *)itemURL userInfo:(id)userInfo 300 | { 301 | CLWebItem *tempItem = [CLWebItem webItem]; 302 | tempItem.URL = itemURL; 303 | 304 | return [self getItemInformation:tempItem userInfo:userInfo]; 305 | } 306 | 307 | - (NSString *)getItemInformation:(CLWebItem *)webItem userInfo:(id)userInfo 308 | { 309 | if (webItem == nil || webItem.URL == nil) 310 | return nil; 311 | 312 | CLAPITransaction *transaction = [CLAPITransaction transaction]; 313 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:webItem.URL]; 314 | [request setHTTPMethod:@"GET"]; 315 | [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 316 | 317 | transaction.request = request; 318 | transaction.identifier = [NSString uniqueString]; 319 | transaction.requestType = CLAPIRequestTypeGetItemInformation; 320 | transaction.userInfo = userInfo; 321 | 322 | return [self _createAndStartConnectionForTransaction:transaction]; 323 | } 324 | 325 | - (NSString *)deleteItemAtHref:(NSURL *)href userInfo:(id)userInfo 326 | { 327 | CLWebItem *tempItem = [CLWebItem webItem]; 328 | tempItem.href = href; 329 | 330 | return [self deleteItem:tempItem userInfo:userInfo]; 331 | } 332 | 333 | - (NSString *)getItemListStartingAtPage:(NSInteger)pageNumStartingAtOne itemsPerPage:(NSInteger)perPage userInfo:(id)userInfo 334 | { 335 | return [self getItemListStartingAtPage:pageNumStartingAtOne 336 | ofType:CLWebItemTypeNone 337 | itemsPerPage:perPage 338 | showOnlyItemsInTrash:NO 339 | userInfo:userInfo]; 340 | } 341 | 342 | - (NSString *)getItemListStartingAtPage:(NSInteger)pageNumStartingAtOne ofType:(CLWebItemType)type itemsPerPage:(NSInteger)perPage userInfo:(id)userInfo 343 | { 344 | return [self getItemListStartingAtPage:pageNumStartingAtOne 345 | ofType:type 346 | itemsPerPage:perPage 347 | showOnlyItemsInTrash:NO 348 | userInfo:userInfo]; 349 | } 350 | 351 | - (NSString *)getItemListStartingAtPage:(NSInteger)pageNumStartingAtOne ofType:(CLWebItemType)type itemsPerPage:(NSInteger)perPage showOnlyItemsInTrash:(BOOL)showOnlyItemsInTrash userInfo:(id)userInfo 352 | { 353 | if (![self isReady]) 354 | return nil; 355 | 356 | CLAPITransaction *transaction = [CLAPITransaction transaction]; 357 | 358 | static NSString *format = @"/items?page=%i&per_page=%i&deleted=%@"; 359 | NSString *path = [NSString stringWithFormat:format, pageNumStartingAtOne, perPage, showOnlyItemsInTrash ? @"true" : @"false"]; 360 | if (type != CLWebItemTypeNone) 361 | path = [path stringByAppendingFormat:@"&type=%@", [CLAPISerializer webItemTypeStringForType:type]]; 362 | 363 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[self _URLWithPath:path]]; 364 | [request setHTTPMethod:@"GET"]; 365 | [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 366 | 367 | transaction.request = request; 368 | transaction.identifier = [NSString uniqueString]; 369 | transaction.requestType = CLAPIRequestTypeGetItemList; 370 | transaction.userInfo = userInfo; 371 | 372 | return [self _createAndStartConnectionForTransaction:transaction]; 373 | } 374 | 375 | - (NSString *)uploadFileWithName:(NSString *)fileName fileData:(NSData *)fileData userInfo:(id)userInfo 376 | { 377 | return [self uploadFileWithName:fileName fileData:fileData options:nil userInfo:userInfo]; 378 | } 379 | 380 | - (NSString *)uploadFileWithName:(NSString *)fileName fileData:(NSData *)fileData options:(NSDictionary *)options userInfo:(id)userInfo 381 | { 382 | if (![self isReady]) 383 | return nil; 384 | 385 | 386 | NSURL *apiURL = [self _URLWithPath:@"/items/new"]; 387 | if ([options.allKeys containsObject:CLAPIEngineUploadOptionPrivacyKey]) { 388 | NSString *apiURLString = [apiURL absoluteString]; 389 | NSString *privacyOption = [options objectForKey:CLAPIEngineUploadOptionPrivacyKey]; 390 | if ([privacyOption isEqualToString:CLAPIEnginePrivacyOptionPublic]) 391 | apiURLString = [apiURLString stringByAppendingString:@"?item[private]=false"]; 392 | else if ([privacyOption isEqualToString:CLAPIEnginePrivacyOptionPrivate]) 393 | apiURLString = [apiURLString stringByAppendingString:@"?item[private]=true"]; 394 | 395 | apiURL = [NSURL URLWithString:apiURLString]; 396 | } 397 | 398 | // Make sure that the API URL is still valid after the editing 399 | if (apiURL == nil) 400 | return nil; 401 | 402 | 403 | CLAPITransaction *transaction = [CLAPITransaction transaction]; 404 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:apiURL]; 405 | [request setHTTPMethod:@"GET"]; 406 | [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 407 | 408 | transaction.request = request; 409 | transaction.identifier = [NSString uniqueString]; 410 | transaction.requestType = CLAPIRequestTypeGetS3UploadCredentials; 411 | transaction.userInfo = userInfo; 412 | transaction.internalContext = [NSDictionary dictionaryWithObjectsAndKeys:fileName, @"name", 413 | fileData, @"data", nil]; 414 | 415 | return [self _createAndStartConnectionForTransaction:transaction]; 416 | } 417 | 418 | #pragma mark - 419 | 420 | - (NSString *)getStoreProductsWithUserInfo:(id)userInfo 421 | { 422 | CLAPITransaction *transaction = [CLAPITransaction transaction]; 423 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[self _URLWithPath:@"/purchases"]]; 424 | [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 425 | [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData]; // disable caching 426 | 427 | transaction.request = request; 428 | transaction.identifier = [NSString uniqueString]; 429 | transaction.requestType = CLAPIRequestTypeGetStoreProducts; 430 | transaction.userInfo = userInfo; 431 | 432 | return [self _createAndStartConnectionForTransaction:transaction]; 433 | } 434 | 435 | - (NSString *)redeemStoreReceipt:(NSString *)base64Receipt userInfo:(id)userInfo 436 | { 437 | if (![self isReady]) { 438 | return nil; 439 | } 440 | 441 | CLAPITransaction *transaction = [CLAPITransaction transaction]; 442 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[self _URLWithPath:@"/purchases"]]; 443 | [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 444 | [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 445 | [request setHTTPMethod:@"POST"]; 446 | [request setHTTPBody:[CLAPISerializer receiptWithBase64String:base64Receipt]]; 447 | [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData]; // disable caching 448 | 449 | transaction.request = request; 450 | transaction.identifier = [NSString uniqueString]; 451 | transaction.requestType = CLAPIRequestTypeStoreReceiptRedemption; 452 | transaction.userInfo = userInfo; 453 | 454 | return [self _createAndStartConnectionForTransaction:transaction]; 455 | } 456 | 457 | #pragma mark - Connection actions 458 | 459 | - (void)cancelConnection:(NSString *)connectionIdentifier 460 | { 461 | CLAPITransaction *transaction = [self _transactionForConnectionIdentifier:connectionIdentifier]; 462 | if (transaction) { 463 | // Cancel transaction 464 | [transaction.connection cancel]; 465 | if ([self.transactions containsObject:transaction]) 466 | [self.transactions removeObject:transaction]; 467 | } 468 | } 469 | 470 | - (void)cancelAllConnections 471 | { 472 | NSMutableSet *transCopy = [[self.transactions mutableCopy] autorelease]; 473 | for (CLAPITransaction *transaction in transCopy) { 474 | [self cancelConnection:transaction.identifier]; 475 | } 476 | } 477 | 478 | - (id)userInfoForConnectionIdentifier:(NSString *)connectionIdentifier 479 | { 480 | CLAPITransaction *transaction = [self _transactionForConnectionIdentifier:connectionIdentifier]; 481 | return [transaction userInfo]; 482 | } 483 | 484 | - (CLAPIRequestType)requestTypeForConnectionIdentifier:(NSString *)connectionIdentifier 485 | { 486 | CLAPITransaction *transaction = [self _transactionForConnectionIdentifier:connectionIdentifier]; 487 | return [transaction requestType]; 488 | } 489 | 490 | #pragma mark - 491 | #pragma mark NSURLConnection Delegate Methods 492 | 493 | - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 494 | { 495 | [[self _transactionForConnection:connection].receivedData appendData:data]; 496 | } 497 | 498 | - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 499 | { 500 | if ([challenge previousFailureCount] == 0) { 501 | // Return credentials 502 | NSURLCredential *credential = [NSURLCredential credentialWithUser:[self.email lowercaseString] 503 | password:self.password 504 | persistence:NSURLCredentialPersistenceNone]; 505 | [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; 506 | 507 | } else { 508 | // Cancel challenge if it failed previously 509 | [[challenge sender] cancelAuthenticationChallenge:challenge]; 510 | } 511 | } 512 | 513 | - (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten 514 | totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite 515 | { 516 | CLAPITransaction *transaction = [self _transactionForConnection:connection]; 517 | if (transaction.requestType == CLAPIRequestTypeS3FileUpload) { 518 | // Calculate percentage and inform delegate 519 | CGFloat percentDone = (CGFloat)totalBytesWritten / (CGFloat)totalBytesExpectedToWrite; 520 | 521 | if ([self.delegate respondsToSelector:@selector(fileUploadDidProgress:connectionIdentifier:userInfo:)]) 522 | [self.delegate fileUploadDidProgress:percentDone 523 | connectionIdentifier:transaction.identifier 524 | userInfo:transaction.userInfo]; 525 | } 526 | } 527 | 528 | - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 529 | { 530 | if ([response isKindOfClass:[NSHTTPURLResponse class]]) { 531 | CLAPITransaction *transaction = [self _transactionForConnection:connection]; 532 | transaction.response = (NSHTTPURLResponse *)response; 533 | } 534 | } 535 | 536 | - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 537 | { 538 | CLAPITransaction *transaction = [self _transactionForConnection:connection]; 539 | 540 | // Inform delegate 541 | if ([self.delegate respondsToSelector:@selector(requestDidFailWithError:connectionIdentifier:userInfo:)]) 542 | [self.delegate requestDidFailWithError:error connectionIdentifier:transaction.identifier userInfo:transaction.userInfo]; 543 | 544 | if ([self.transactions containsObject:transaction]) 545 | [self.transactions removeObject:transaction]; 546 | } 547 | 548 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection 549 | { 550 | CLAPITransaction *transaction = [self _transactionForConnection:connection]; 551 | NSInteger statusCode = transaction.response.statusCode; 552 | CLAPIRequestType requestType = transaction.requestType; 553 | 554 | if (statusCode != 200 && statusCode != 201 && statusCode != 304) { 555 | // Try to parse the response 556 | NSArray *array = [CLAPIDeserializer arrayFromJSONData:transaction.receivedData]; 557 | 558 | NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; 559 | 560 | // Add the request type 561 | [userInfo setObject:[NSNumber numberWithInteger:requestType] 562 | forKey:CLAPIEngineErrorRequestTypeKey]; 563 | [userInfo setObject:[NSNumber numberWithInteger:statusCode] 564 | forKey:CLAPIEngineErrorStatusCodeKey]; 565 | if (array) { 566 | // Add the error messages 567 | [userInfo setObject:array 568 | forKey:CLAPIEngineErrorMessagesKey]; 569 | 570 | // Add recovery suggestion 571 | NSMutableString *recoverySuggestion = [NSMutableString string]; 572 | for (NSString *message in array) { 573 | [recoverySuggestion appendFormat:@"• %@\n", message]; 574 | } 575 | [userInfo setObject:recoverySuggestion 576 | forKey:NSLocalizedRecoverySuggestionErrorKey]; 577 | } 578 | 579 | // TODO: get status code from response body for API 1.1 580 | NSError *error = [NSError errorWithDomain:CLAPIEngineErrorDomain 581 | code:CLAPIEngineErrorUnknown 582 | userInfo:userInfo]; 583 | [self connection:connection didFailWithError:error]; 584 | return; 585 | } 586 | 587 | // Do not notify for the delegate on S3 upload credentials request 588 | if (requestType != CLAPIRequestTypeGetS3UploadCredentials) { 589 | if ([self.delegate respondsToSelector:@selector(requestDidSucceedWithConnectionIdentifier:userInfo:)]) { 590 | [self.delegate requestDidSucceedWithConnectionIdentifier:transaction.identifier userInfo:transaction.userInfo]; 591 | } 592 | } 593 | 594 | switch (requestType) { 595 | case CLAPIRequestTypeGetS3UploadCredentials: { 596 | // S3 credentials 597 | NSDictionary *s3Dict = [CLAPIDeserializer dictionaryFromJSONData:transaction.receivedData]; 598 | if (s3Dict == nil) { 599 | NSError *error = [NSError errorWithDomain:NSURLErrorDomain 600 | code:NSURLErrorBadServerResponse 601 | userInfo:nil]; 602 | [self connection:connection didFailWithError:error]; 603 | return; 604 | } 605 | 606 | // TODO: implement new error handling for API 1.1 607 | // Check if upload limit has been exceeded 608 | NSInteger remainingUploads = [[s3Dict objectForKey:@"uploads_remaining"] integerValue]; 609 | if (remainingUploads <= 0 && [[s3Dict allKeys] containsObject:@"uploads_remaining"]) { 610 | // Limit exceeded, create user info dict & error 611 | NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; 612 | 613 | // Add the request type 614 | [userInfo setObject:[NSNumber numberWithInteger:requestType] 615 | forKey:CLAPIEngineErrorRequestTypeKey]; 616 | // Add error message 617 | NSString *errorMessage = @"You've reached the daily upload limit allowed by the Free plan. Grab one of our snazzy Pro plans and never see this message again."; 618 | [userInfo setObject:[NSArray arrayWithObject:errorMessage] 619 | forKey:CLAPIEngineErrorMessagesKey]; 620 | [userInfo setObject:errorMessage 621 | forKey:NSLocalizedRecoverySuggestionErrorKey]; 622 | [userInfo setObject:[NSNumber numberWithInteger:statusCode] 623 | forKey:CLAPIEngineErrorStatusCodeKey]; 624 | 625 | NSError *error = [NSError errorWithDomain:CLAPIEngineErrorDomain 626 | code:CLAPIEngineErrorUploadLimitExceeded 627 | userInfo:userInfo]; 628 | 629 | [self connection:connection didFailWithError:error]; 630 | return; 631 | } 632 | 633 | // Check if file is too big 634 | NSData *fileData = [transaction.internalContext objectForKey:@"data"]; 635 | NSUInteger maxUploadSize = [[s3Dict objectForKey:@"max_upload_size"] unsignedIntegerValue]; 636 | NSUInteger fileSize = [fileData length]; 637 | if (maxUploadSize < fileSize && [[s3Dict allKeys] containsObject:@"max_upload_size"]) { 638 | // Too big, create user info dict & error 639 | NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; 640 | 641 | // Add the request type 642 | [userInfo setObject:[NSNumber numberWithInteger:requestType] 643 | forKey:CLAPIEngineErrorRequestTypeKey]; 644 | // Add error message 645 | NSString *format = @"This file is too large. You can upload files up to %dMB but this file is %dMB."; 646 | NSString *errorMessage = [NSString stringWithFormat:format, (int)(maxUploadSize / (1024 * 1024)), 647 | (int)(fileSize / (1024 * 1024))]; 648 | [userInfo setObject:[NSArray arrayWithObject:errorMessage] 649 | forKey:CLAPIEngineErrorMessagesKey]; 650 | [userInfo setObject:errorMessage 651 | forKey:NSLocalizedRecoverySuggestionErrorKey]; 652 | [userInfo setObject:[NSNumber numberWithInteger:statusCode] 653 | forKey:CLAPIEngineErrorStatusCodeKey]; 654 | 655 | NSError *error = [NSError errorWithDomain:CLAPIEngineErrorDomain 656 | code:CLAPIEngineErrorUploadTooLarge 657 | userInfo:userInfo]; 658 | 659 | [self connection:connection didFailWithError:error]; 660 | return; 661 | } 662 | 663 | // Upload file 664 | NSURLRequest *request = [CLAPIDeserializer URLRequestWithS3ParametersDictionary:s3Dict 665 | fileName:[transaction.internalContext objectForKey:@"name"] 666 | fileData:fileData]; 667 | CLAPITransaction *newTransaction = [CLAPITransaction transaction]; 668 | newTransaction.identifier = transaction.identifier; 669 | newTransaction.userInfo = transaction.userInfo; 670 | newTransaction.request = request; 671 | newTransaction.requestType = CLAPIRequestTypeS3FileUpload; 672 | 673 | [self _createAndStartConnectionForTransaction:newTransaction]; 674 | break; 675 | } 676 | 677 | case CLAPIRequestTypeS3FileUpload: { 678 | CLWebItem *resultItem = [CLAPIDeserializer webItemWithJSONDictionaryData:transaction.receivedData]; 679 | if ([self.delegate respondsToSelector:@selector(fileUploadDidSucceedWithResultingItem:connectionIdentifier:userInfo:)]) 680 | [self.delegate fileUploadDidSucceedWithResultingItem:resultItem 681 | connectionIdentifier:transaction.identifier 682 | userInfo:transaction.userInfo]; 683 | break; 684 | } 685 | 686 | case CLAPIRequestTypeAccountUpdate: { 687 | CLAccount *resultAccount = [CLAPIDeserializer accountWithJSONDictionaryData:transaction.receivedData]; 688 | if ([self.delegate respondsToSelector:@selector(accountUpdateDidSucceed:connectionIdentifier:userInfo:)]) 689 | [self.delegate accountUpdateDidSucceed:resultAccount 690 | connectionIdentifier:transaction.identifier 691 | userInfo:transaction.userInfo]; 692 | break; 693 | } 694 | 695 | case CLAPIRequestTypeItemUpdatePrivacy: 696 | case CLAPIRequestTypeItemUpdateName: { 697 | CLWebItem *resultItem = [CLAPIDeserializer webItemWithJSONDictionaryData:transaction.receivedData]; 698 | if ([self.delegate respondsToSelector:@selector(itemUpdateDidSucceed:connectionIdentifier:userInfo:)]) 699 | [self.delegate itemUpdateDidSucceed:resultItem 700 | connectionIdentifier:transaction.identifier 701 | userInfo:transaction.userInfo]; 702 | break; 703 | } 704 | 705 | case CLAPIRequestTypeItemDeletion: { 706 | CLWebItem *resultItem = [CLAPIDeserializer webItemWithJSONDictionaryData:transaction.receivedData]; 707 | if ([self.delegate respondsToSelector:@selector(itemDeletionDidSucceed:connectionIdentifier:userInfo:)]) 708 | [self.delegate itemDeletionDidSucceed:resultItem 709 | connectionIdentifier:transaction.identifier 710 | userInfo:transaction.userInfo]; 711 | break; 712 | } 713 | 714 | case CLAPIRequestTypeItemRestoration: { 715 | CLWebItem *resultItem = [CLAPIDeserializer webItemWithJSONDictionaryData:transaction.receivedData]; 716 | if ([self.delegate respondsToSelector:@selector(itemRestorationDidSucceed:connectionIdentifier:userInfo:)]) 717 | [self.delegate itemRestorationDidSucceed:resultItem 718 | connectionIdentifier:transaction.identifier 719 | userInfo:transaction.userInfo]; 720 | break; 721 | } 722 | 723 | case CLAPIRequestTypeGetItemList: { 724 | NSArray *itemArray = [CLAPIDeserializer webItemArrayWithJSONArrayData:transaction.receivedData]; 725 | if ([self.delegate respondsToSelector:@selector(itemListRetrievalSucceeded:connectionIdentifier:userInfo:)]) 726 | [self.delegate itemListRetrievalSucceeded:itemArray 727 | connectionIdentifier:transaction.identifier 728 | userInfo:transaction.userInfo]; 729 | break; 730 | } 731 | 732 | case CLAPIRequestTypeLinkBookmark: { 733 | CLWebItem *resultItem = [CLAPIDeserializer webItemWithJSONDictionaryData:transaction.receivedData]; 734 | if ([self.delegate respondsToSelector:@selector(linkBookmarkDidSucceedWithResultingItem:connectionIdentifier:userInfo:)]) 735 | [self.delegate linkBookmarkDidSucceedWithResultingItem:resultItem 736 | connectionIdentifier:transaction.identifier 737 | userInfo:transaction.userInfo]; 738 | break; 739 | } 740 | 741 | case CLAPIRequestTypeCreateAccount: { 742 | CLAccount *resultAccount = [CLAPIDeserializer accountWithJSONDictionaryData:transaction.receivedData]; 743 | if ([self.delegate respondsToSelector:@selector(accountCreationSucceeded:connectionIdentifier:userInfo:)]) 744 | [self.delegate accountCreationSucceeded:resultAccount 745 | connectionIdentifier:transaction.identifier 746 | userInfo:transaction.userInfo]; 747 | break; 748 | } 749 | 750 | case CLAPIRequestTypeGetAccountInformation: { 751 | CLAccount *resultAccount = [CLAPIDeserializer accountWithJSONDictionaryData:transaction.receivedData]; 752 | if ([self.delegate respondsToSelector:@selector(accountInformationRetrievalSucceeded:connectionIdentifier:userInfo:)]) 753 | [self.delegate accountInformationRetrievalSucceeded:resultAccount 754 | connectionIdentifier:transaction.identifier 755 | userInfo:transaction.userInfo]; 756 | break; 757 | } 758 | 759 | case CLAPIRequestTypeGetItemInformation: { 760 | CLWebItem *resultItem = [CLAPIDeserializer webItemWithJSONDictionaryData:transaction.receivedData]; 761 | if ([self.delegate respondsToSelector:@selector(itemInformationRetrievalSucceeded:connectionIdentifier:userInfo:)]) 762 | [self.delegate itemInformationRetrievalSucceeded:resultItem 763 | connectionIdentifier:transaction.identifier 764 | userInfo:transaction.userInfo]; 765 | break; 766 | } 767 | 768 | case CLAPIRequestTypeGetStoreProducts: { 769 | // Did receive store product identifiers 770 | NSArray *products = [CLAPIDeserializer productsWithJSONArrayData:transaction.receivedData]; 771 | if ([self.delegate respondsToSelector:@selector(storeProductInformationRetrievalSucceeded:connectionIdentifier:userInfo:)]) { 772 | [self.delegate storeProductInformationRetrievalSucceeded:products 773 | connectionIdentifier:transaction.identifier 774 | userInfo:transaction.userInfo]; 775 | } 776 | break; 777 | } 778 | 779 | case CLAPIRequestTypeStoreReceiptRedemption: { 780 | // Redemption of pro complete, return updated account 781 | CLAccount *account = [CLAPIDeserializer accountWithJSONDictionaryData:transaction.receivedData]; 782 | if ([self.delegate respondsToSelector:@selector(storeReceiptRedemptionSucceeded:connectionIdentifier:userInfo:)]) { 783 | [self.delegate storeReceiptRedemptionSucceeded:account 784 | connectionIdentifier:transaction.identifier 785 | userInfo:transaction.userInfo]; 786 | } 787 | break; 788 | } 789 | } 790 | 791 | if ([self.transactions containsObject:transaction]) 792 | [self.transactions removeObject:transaction]; 793 | } 794 | 795 | #pragma mark - 796 | #pragma mark Private Methods 797 | 798 | - (NSString *)_createAndStartConnectionForTransaction:(CLAPITransaction *)transaction 799 | { 800 | if (self.clearsCookies) { 801 | // Clear cookies 802 | NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; 803 | NSArray *cookies = [storage cookiesForURL:self.baseURL]; 804 | for (NSHTTPCookie *currCookie in cookies) 805 | [storage deleteCookie:currCookie]; 806 | } 807 | 808 | // Create & start connection 809 | NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:transaction.request 810 | delegate:self 811 | startImmediately:NO]; 812 | [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; 813 | transaction.connection = connection; 814 | [self.transactions addObject:transaction]; 815 | [connection start]; 816 | [connection release]; 817 | 818 | return transaction.identifier; 819 | } 820 | 821 | - (CLAPITransaction *)_transactionForConnection:(NSURLConnection *)connection 822 | { 823 | NSPredicate *predicate = [NSPredicate predicateWithFormat:@"connection = %@", connection]; 824 | NSSet *resultSet = [self.transactions filteredSetUsingPredicate:predicate]; 825 | return [resultSet anyObject]; 826 | } 827 | 828 | - (CLAPITransaction *)_transactionForConnectionIdentifier:(NSString *)connectionIdentifier 829 | { 830 | NSPredicate *predicate = [NSPredicate predicateWithFormat:@"identifier = %@", connectionIdentifier]; 831 | NSSet *resultSet = [self.transactions filteredSetUsingPredicate:predicate]; 832 | return [resultSet anyObject]; 833 | } 834 | 835 | #pragma mark - Private accessors 836 | 837 | - (NSURL *)_URLWithPath:(NSString *)path 838 | { 839 | NSString *URLString = [NSString stringWithFormat:@"%@%@", _CLAPIEngineBaseURL, path]; 840 | return [NSURL URLWithString:URLString]; 841 | } 842 | 843 | #pragma mark - 844 | #pragma mark Cleanup 845 | 846 | - (void)dealloc 847 | { 848 | [self cancelAllConnections]; 849 | 850 | [_email release]; 851 | _email = nil; 852 | [_password release]; 853 | _password = nil; 854 | _delegate = nil; 855 | [_transactions release]; 856 | _transactions = nil; 857 | 858 | [super dealloc]; 859 | } 860 | 861 | @end 862 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/CLAPIEngineConstants.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLAPIEngineConstants.h 3 | // Cloud 4 | // 5 | // Created by Matthias Plappert on 5/4/11. 6 | // Copyright 2011 Linebreak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | enum { 13 | CLAPIRequestTypeAccountUpdate = 0, 14 | CLAPIRequestTypeItemUpdatePrivacy, 15 | CLAPIRequestTypeItemUpdateName, 16 | CLAPIRequestTypeItemDeletion, 17 | CLAPIRequestTypeItemRestoration, 18 | CLAPIRequestTypeGetItemList, 19 | CLAPIRequestTypeLinkBookmark, 20 | CLAPIRequestTypeCreateAccount, 21 | CLAPIRequestTypeGetAccountInformation, 22 | CLAPIRequestTypeGetItemInformation, 23 | CLAPIRequestTypeGetS3UploadCredentials, 24 | CLAPIRequestTypeS3FileUpload, 25 | CLAPIRequestTypeGetStoreProducts, 26 | CLAPIRequestTypeStoreReceiptRedemption 27 | }; 28 | typedef NSInteger CLAPIRequestType; 29 | 30 | 31 | enum { 32 | CLWebItemTypeImage = 0, 33 | CLWebItemTypeBookmark, 34 | CLWebItemTypeText, 35 | CLWebItemTypeArchive, 36 | CLWebItemTypeAudio, 37 | CLWebItemTypeVideo, 38 | CLWebItemTypeUnknown, 39 | CLWebItemTypeNone 40 | }; 41 | typedef NSInteger CLWebItemType; 42 | 43 | 44 | // Error domain and user info keys 45 | extern NSString *const CLAPIEngineErrorDomain; 46 | extern NSString *const CLAPIEngineErrorMessagesKey; 47 | extern NSString *const CLAPIEngineErrorRequestTypeKey; 48 | extern NSString *const CLAPIEngineErrorStatusCodeKey; 49 | 50 | // Error codes 51 | enum { 52 | CLAPIEngineErrorUnknown = -1, 53 | CLAPIEngineErrorUploadLimitExceeded = 1, 54 | CLAPIEngineErrorUploadTooLarge = 2 55 | }; 56 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/CLAPIEngineConstants.m: -------------------------------------------------------------------------------- 1 | // 2 | // CLAPIEngineConstants.m 3 | // Cloud 4 | // 5 | // Created by Matthias Plappert on 5/4/11. 6 | // Copyright 2011 Linebreak. All rights reserved. 7 | // 8 | 9 | #import "CLAPIEngineConstants.h" 10 | 11 | 12 | NSString *const CLAPIEngineErrorDomain = @"com.linebreak.CloudApp.Engine"; 13 | NSString *const CLAPIEngineErrorMessagesKey = @"messages"; 14 | NSString *const CLAPIEngineErrorRequestTypeKey = @"requestType"; 15 | NSString *const CLAPIEngineErrorStatusCodeKey = @"statusCode"; 16 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/CLAPIEngineDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLAPIEngineDelegate.h 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 8/8/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @class CLWebItem, CLAPITransaction, CLAccount; 13 | 14 | 15 | @protocol CLAPIEngineDelegate 16 | 17 | @optional 18 | - (void)requestDidSucceedWithConnectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo; 19 | - (void)requestDidFailWithError:(NSError *)error connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo; 20 | 21 | - (void)fileUploadDidProgress:(CGFloat)percentageComplete connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo; 22 | - (void)fileUploadDidSucceedWithResultingItem:(CLWebItem *)item connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo; 23 | 24 | - (void)linkBookmarkDidSucceedWithResultingItem:(CLWebItem *)item connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo; 25 | 26 | - (void)accountUpdateDidSucceed:(CLAccount *)account connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo; 27 | - (void)itemUpdateDidSucceed:(CLWebItem *)item connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo; 28 | - (void)itemDeletionDidSucceed:(CLWebItem *)item connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo; 29 | - (void)itemRestorationDidSucceed:(CLWebItem *)item connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo; 30 | 31 | - (void)itemInformationRetrievalSucceeded:(CLWebItem *)item connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo; 32 | - (void)accountInformationRetrievalSucceeded:(CLAccount *)account connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo; 33 | - (void)itemListRetrievalSucceeded:(NSArray *)items connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo; 34 | 35 | - (void)accountCreationSucceeded:(CLAccount *)newAccount connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo; 36 | 37 | - (void)storeProductInformationRetrievalSucceeded:(NSArray *)productIdentifiers connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo; 38 | - (void)storeReceiptRedemptionSucceeded:(CLAccount *)account connectionIdentifier:(NSString *)connectionIdentifier userInfo:(id)userInfo; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/CLAPITransaction.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLAPITransaction.h 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 12/29/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CLAPIEngineConstants.h" 11 | 12 | 13 | @interface CLAPITransaction : NSObject { 14 | NSURLRequest *_request; 15 | NSURLConnection *_connection; 16 | NSMutableData *_receivedData; 17 | NSHTTPURLResponse *_response; 18 | CLAPIRequestType _requestType; 19 | NSString *_identifier; 20 | id _userInfo; 21 | id _internalContext; 22 | } 23 | 24 | @property (nonatomic, readwrite, retain) NSURLRequest *request; 25 | @property (nonatomic, readwrite, retain) NSHTTPURLResponse *response; 26 | @property (nonatomic, readwrite, retain) NSURLConnection *connection; 27 | @property (nonatomic, readwrite, retain) NSMutableData *receivedData; 28 | @property (nonatomic, readwrite, assign) CLAPIRequestType requestType; 29 | @property (nonatomic, readwrite, copy) NSString *identifier; 30 | @property (nonatomic, readwrite, retain) id userInfo; 31 | @property (nonatomic, readwrite, retain) id internalContext; 32 | 33 | + (id)transaction; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/CLAPITransaction.m: -------------------------------------------------------------------------------- 1 | // 2 | // CLAPITransaction.m 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 12/29/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import "CLAPITransaction.h" 10 | 11 | 12 | @implementation CLAPITransaction 13 | 14 | @synthesize request = _request, connection = _connection, receivedData = _receivedData, 15 | requestType = _requestType, userInfo = _userInfo, identifier = _identifier, 16 | response = _response, internalContext = _internalContext; 17 | 18 | + (id)transaction 19 | { 20 | return [[[[self class] alloc] init] autorelease]; 21 | } 22 | 23 | - (id)init 24 | { 25 | if ((self = [super init])) { 26 | _receivedData = [[NSMutableData alloc] init]; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)dealloc 32 | { 33 | [_request release]; 34 | _request = nil; 35 | [_response release]; 36 | _response = nil; 37 | [_connection release]; 38 | _connection = nil; 39 | [_receivedData release]; 40 | _receivedData = nil; 41 | [_userInfo release]; 42 | _userInfo = nil; 43 | [_identifier release]; 44 | _identifier = nil; 45 | [_internalContext release]; 46 | _internalContext = nil; 47 | 48 | [super dealloc]; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/Categories/NSMutableURLRequest+NPPOSTBody.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableURLRequest+NPPOSTBody.h 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 7/20/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | extern NSString * const NPHTTPBoundary; 13 | 14 | @interface NSMutableURLRequest (NPPOSTBody) 15 | 16 | - (void)addToHTTPBodyValue:(NSString *)theValue forKey:(NSString *)theKey; 17 | - (void)addToHTTPBodyFileData:(NSData *)someData fileName:(NSString *)aName mimeType:(NSString *)aMimeType forKey:(NSString *)aKey; 18 | 19 | //Make sure to call this when you are done if you used any of the above methods 20 | - (void)finalizeHTTPBody; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/Categories/NSMutableURLRequest+NPPOSTBody.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableURLRequest+NPPOSTBody.m 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 7/20/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import "NSMutableURLRequest+NPPOSTBody.h" 10 | 11 | 12 | NSString * const NPHTTPBoundary = @"-----NPRequestBoundary-----"; 13 | 14 | 15 | @implementation NSMutableURLRequest (NPPOSTBody) 16 | 17 | - (void)addToHTTPBodyValue:(NSString *)theValue forKey:(NSString *)theKey 18 | { 19 | NSMutableData *postBody = [NSMutableData dataWithData:[self HTTPBody]]; 20 | 21 | if ([postBody length] == 0) { 22 | // Add opening boundary 23 | NSString *boundary = [NSString stringWithFormat:@"--%@\r\n", NPHTTPBoundary]; 24 | [postBody appendData:[boundary dataUsingEncoding:NSUTF8StringEncoding]]; 25 | } 26 | 27 | // Content disposition 28 | NSString *contentDisposition = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", theKey]; 29 | [postBody appendData:[contentDisposition dataUsingEncoding:NSUTF8StringEncoding]]; 30 | 31 | // The actual value 32 | [postBody appendData:[theValue dataUsingEncoding:NSUTF8StringEncoding]]; 33 | 34 | // Separating boundary 35 | NSString *boundary = [NSString stringWithFormat:@"\r\n--%@\r\n", NPHTTPBoundary]; 36 | [postBody appendData:[boundary dataUsingEncoding:NSUTF8StringEncoding]]; 37 | 38 | [self setHTTPBody:postBody]; 39 | } 40 | 41 | - (void)addToHTTPBodyFileData:(NSData *)someData fileName:(NSString *)aName mimeType:(NSString *)aMimeType forKey:(NSString *)aKey 42 | { 43 | // Fallbacks 44 | if (aName == nil ||[aName length] == 0) 45 | aName = @"UnknownFileName"; 46 | 47 | if (aMimeType == nil || [aMimeType length] == 0) 48 | aMimeType = @"application/octet-stream"; 49 | 50 | // Get existing body 51 | NSMutableData *postBody = [NSMutableData dataWithData:[self HTTPBody]]; 52 | 53 | if ([postBody length] == 0) { 54 | // Add opening boundary 55 | NSString *boundary = [NSString stringWithFormat:@"--%@\r\n", NPHTTPBoundary]; 56 | [postBody appendData:[boundary dataUsingEncoding:NSUTF8StringEncoding]]; 57 | } 58 | 59 | // Content disposition 60 | NSString *contentDisposition = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", aKey, aName]; 61 | [postBody appendData:[contentDisposition dataUsingEncoding:NSUTF8StringEncoding]]; 62 | 63 | // Content type 64 | NSString *contentType = [NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", aMimeType]; 65 | [postBody appendData:[contentType dataUsingEncoding:NSUTF8StringEncoding]]; 66 | 67 | // Append actual data 68 | [postBody appendData:someData]; 69 | 70 | // Separating boundary 71 | NSString *boundary = [NSString stringWithFormat:@"\r\n--%@\r\n", NPHTTPBoundary]; 72 | [postBody appendData:[boundary dataUsingEncoding:NSUTF8StringEncoding]]; 73 | 74 | [self setHTTPBody:postBody]; 75 | } 76 | 77 | - (void)finalizeHTTPBody 78 | { 79 | NSData *smallerData = [[self HTTPBody] subdataWithRange:NSMakeRange([[self HTTPBody] length] - 2, 2)]; 80 | NSString *stringValue = [[NSString alloc] initWithData:smallerData encoding:NSUTF8StringEncoding]; 81 | if ([stringValue hasSuffix:@"\r\n"]) { 82 | // Transform last separating boundary into ending boundary 83 | NSData *subdata = [[self HTTPBody] subdataWithRange:NSMakeRange(0, [[self HTTPBody] length] - 2)]; 84 | NSMutableData *mutableSubdata = [NSMutableData dataWithData:subdata]; 85 | [mutableSubdata appendData:[@"--\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; 86 | [self setHTTPBody:mutableSubdata]; 87 | } 88 | [stringValue release]; 89 | } 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/Categories/NSString+NPAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+NPAdditions.h 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 7/20/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface NSString (NPAdditions) 13 | 14 | + (NSString *)stringWithData:(NSData *)theData encoding:(NSStringEncoding)theEncoding; 15 | + (NSString *)uniqueString; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/Categories/NSString+NPAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+NPAdditions.m 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 7/20/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import "NSString+NPAdditions.h" 10 | 11 | 12 | @implementation NSString (NPAdditions) 13 | 14 | + (NSString *)stringWithData:(NSData *)theData encoding:(NSStringEncoding)theEncoding 15 | { 16 | return [[[NSString alloc] initWithData:theData encoding:theEncoding] autorelease]; 17 | } 18 | 19 | + (NSString *)uniqueString 20 | { 21 | return [[NSProcessInfo processInfo] globallyUniqueString]; 22 | } 23 | 24 | @end -------------------------------------------------------------------------------- /Source/libCloud/Cloud/Categories/NSString+NPMimeType.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+NPMimeType.m.h 3 | // Cloud 4 | // 5 | // Created by np101137 on 9/5/09. 6 | // Copyright 2009 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface NSString(NPMimeType) 13 | 14 | - (NSString *)mimeType; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/Categories/NSString+NPMimeType.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+NPMimeType.m 3 | // Cloud 4 | // 5 | // Created by np101137 on 9/5/09. 6 | // Copyright 2009 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "NSString+NPMimeType.h" 10 | #if TARGET_OS_IPHONE 11 | #import 12 | #endif 13 | 14 | 15 | @implementation NSString (NPMimeType) 16 | 17 | - (NSString *)mimeType 18 | { 19 | NSString *pathExtension = [self pathExtension]; 20 | if (pathExtension == nil || [pathExtension isEqualToString:@""]) 21 | return @"application/octet-stream"; 22 | 23 | CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)pathExtension, NULL); 24 | if (UTI == nil) 25 | return @"application/octet-stream"; 26 | 27 | CFStringRef registeredType = UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType); 28 | if (registeredType == nil) { 29 | CFRelease(UTI); 30 | return @"application/octet-stream"; 31 | } 32 | 33 | CFRelease(UTI); 34 | return [(NSString *)registeredType autorelease]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/Cloud-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'Cloud' target in the 'Cloud' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/Cloud.h: -------------------------------------------------------------------------------- 1 | // 2 | // Cloud.h 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 2/15/11. 6 | // Copyright 2011 Linebreak. All rights reserved. 7 | // 8 | 9 | #import "CLAPIEngine.h" 10 | #import "CLAPITransaction.h" 11 | #import "CLAPIEngineDelegate.h" 12 | #import "CLAPIEngineConstants.h" 13 | #import "CLAccount.h" 14 | #import "CLWebItem.h" 15 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/Model/CLAccount.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLAccount.h 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 7/20/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | enum { 13 | CLAccountTypeFree, 14 | CLAccountTypePro 15 | }; 16 | typedef NSInteger CLAccountType; 17 | 18 | 19 | @class CLSocket; 20 | 21 | 22 | @interface CLAccount : NSObject { 23 | NSURL *_domain; 24 | NSURL *_domainHomePage; 25 | BOOL _alphaUser; 26 | BOOL _uploadsArePrivate; 27 | NSString *_email; 28 | NSDate *_subscriptionExpiresAt; 29 | CLAccountType _type; 30 | CLSocket *_socket; 31 | } 32 | 33 | @property (nonatomic, readwrite, retain) NSURL *domain; 34 | @property (nonatomic, readwrite, retain) NSURL *domainHomePage; 35 | @property (nonatomic, readwrite, assign, getter = isAlphaUser) BOOL alphaUser; 36 | @property (nonatomic, readwrite, assign) BOOL uploadsArePrivate; 37 | @property (nonatomic, readwrite, copy) NSString *email; 38 | @property (nonatomic, readwrite, retain) NSDate *subscriptionExpiresAt; 39 | @property (nonatomic, readwrite, assign) CLAccountType type; 40 | @property (nonatomic, readwrite, retain) CLSocket *socket; 41 | 42 | - (id)initWithEmail:(NSString *)anEmail; 43 | + (id)accountWithEmail:(NSString *)anEmail; 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/Model/CLAccount.m: -------------------------------------------------------------------------------- 1 | // 2 | // CLAccount.m 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 7/20/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import "CLAccount.h" 10 | 11 | 12 | static NSString * const CLAccountDomainKey = @"CLAccountDomainKey"; 13 | static NSString * const CLAccountDomainHomepageKey = @"CLAccountDomainHomepageKey"; 14 | static NSString * const CLAccountAlphaUserKey = @"CLAccountAlphaUserKey"; 15 | static NSString * const CLAccountUploadsArePrivateKey = @"CLAccountUploadsArePrivateKey"; 16 | static NSString * const CLAccountEmailKey = @"CLAccountEmailKey"; 17 | static NSString * const CLAccountExpiresAtKey = @"CLAccountExpiresAtKey"; 18 | static NSString * const CLAccountTypeKey = @"CLAccountTypeKey"; 19 | static NSString * const CLAccountSocketKey = @"CLAccountSocketKey"; 20 | 21 | 22 | @implementation CLAccount 23 | 24 | @synthesize uploadsArePrivate = _uploadsArePrivate, email = _email, 25 | subscriptionExpiresAt = _subscriptionExpiresAt, type = _type, domain = _domain, 26 | domainHomePage = _domainHomePage, alphaUser = _alphaUser, socket = _socket; 27 | 28 | + (id)accountWithEmail:(NSString *)anEmail 29 | { 30 | return [[[[self class] alloc] initWithEmail:anEmail] autorelease]; 31 | } 32 | 33 | - (id)init 34 | { 35 | return [self initWithEmail:nil]; 36 | } 37 | 38 | - (id)initWithEmail:(NSString *)anEmail 39 | { 40 | if ((self = [super init])) { 41 | _email = [anEmail copy]; 42 | } 43 | return self; 44 | } 45 | 46 | #pragma mark - 47 | #pragma mark NSCopying 48 | 49 | - (id)copyWithZone:(NSZone *)zone 50 | { 51 | CLAccount *theAccount = [[[self class] alloc] initWithEmail:self.email]; 52 | theAccount.domain = self.domain; 53 | theAccount.domainHomePage = self.domainHomePage; 54 | theAccount.alphaUser = self.alphaUser; 55 | theAccount.uploadsArePrivate = self.uploadsArePrivate; 56 | theAccount.subscriptionExpiresAt = self.subscriptionExpiresAt; 57 | theAccount.type = self.type; 58 | theAccount.socket = self.socket; 59 | 60 | return theAccount; 61 | } 62 | 63 | #pragma mark - 64 | #pragma mark NSCoding 65 | 66 | - (id)initWithCoder:(NSCoder *)decoder 67 | { 68 | if ((self = [super init])) { 69 | if ([decoder allowsKeyedCoding]) { 70 | _domain = [[decoder decodeObjectForKey:CLAccountDomainKey] retain]; 71 | _domainHomePage = [[decoder decodeObjectForKey:CLAccountDomainHomepageKey] retain]; 72 | _alphaUser = [decoder decodeBoolForKey:CLAccountAlphaUserKey]; 73 | _uploadsArePrivate = [decoder decodeBoolForKey:CLAccountUploadsArePrivateKey]; 74 | _email = [[decoder decodeObjectForKey:CLAccountEmailKey] retain]; 75 | _subscriptionExpiresAt = [[decoder decodeObjectForKey:CLAccountExpiresAtKey] retain]; 76 | _type = [decoder decodeIntegerForKey:CLAccountTypeKey]; 77 | _socket = [[decoder decodeObjectForKey:CLAccountSocketKey] retain]; 78 | } 79 | } 80 | return self; 81 | } 82 | 83 | - (void)encodeWithCoder:(NSCoder *)encoder 84 | { 85 | if ([encoder allowsKeyedCoding]) { 86 | [encoder encodeBool:self.alphaUser forKey:CLAccountAlphaUserKey]; 87 | [encoder encodeObject:self.domain forKey:CLAccountDomainKey]; 88 | [encoder encodeObject:self.domainHomePage forKey:CLAccountDomainHomepageKey]; 89 | [encoder encodeBool:self.uploadsArePrivate forKey:CLAccountUploadsArePrivateKey]; 90 | [encoder encodeObject:self.email forKey:CLAccountEmailKey]; 91 | [encoder encodeObject:self.subscriptionExpiresAt forKey:CLAccountExpiresAtKey]; 92 | [encoder encodeInteger:self.type forKey:CLAccountTypeKey]; 93 | [encoder encodeObject:self.socket forKey:CLAccountSocketKey]; 94 | } 95 | } 96 | 97 | #pragma mark - 98 | #pragma mark Cleanup 99 | 100 | - (void)dealloc 101 | { 102 | [_email release]; 103 | _email = nil; 104 | [_domain release]; 105 | _domain = nil; 106 | [_domainHomePage release]; 107 | _domainHomePage = nil; 108 | [_subscriptionExpiresAt release]; 109 | _subscriptionExpiresAt = nil; 110 | [_socket release]; 111 | _socket = nil; 112 | 113 | [super dealloc]; 114 | } 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/Model/CLSocket.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLSocket.h 3 | // Cloud 4 | // 5 | // Created by Matthias Plappert on 20.02.11. 6 | // Copyright 2011 Linebreak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | extern NSString *const CLSocketItemsChannel; 13 | 14 | 15 | @interface CLSocket : NSObject { 16 | NSString *_APIKey; 17 | NSInteger _appID; 18 | NSURL *_authURL; 19 | NSDictionary *_channels; 20 | } 21 | 22 | @property (nonatomic, readwrite, copy) NSString *APIKey; 23 | @property (nonatomic, readwrite, assign) NSInteger appID; 24 | @property (nonatomic, readwrite, retain) NSURL *authURL; 25 | @property (nonatomic, readwrite, retain) NSDictionary *channels; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/Model/CLSocket.m: -------------------------------------------------------------------------------- 1 | // 2 | // CLSocket.m 3 | // Cloud 4 | // 5 | // Created by Matthias Plappert on 20.02.11. 6 | // Copyright 2011 Linebreak. All rights reserved. 7 | // 8 | 9 | #import "CLSocket.h" 10 | 11 | 12 | NSString *const CLSocketItemsChannel = @"items"; 13 | 14 | static NSString *const CLSocketAPIKeyKey = @"CLSocketAPIKeyKey"; 15 | static NSString *const CLSocketAppIDKey = @"CLSocketAppIDKey"; 16 | static NSString *const CLSocketAuthURLKey = @"CLSocketAuthURLKey"; 17 | static NSString *const CLSocketChannelsKey = @"CLSocketChannelsKey"; 18 | 19 | 20 | @implementation CLSocket 21 | 22 | @synthesize APIKey = _APIKey, appID = _appID, authURL = _authURL, channels = _channels; 23 | 24 | - (id)init 25 | { 26 | if ((self = [super init])) { 27 | _APIKey = nil; 28 | _appID = NSNotFound; 29 | _authURL = nil; 30 | _channels = nil; 31 | } 32 | return self; 33 | } 34 | 35 | #pragma mark - 36 | #pragma mark NSCopying 37 | 38 | - (id)copyWithZone:(NSZone *)zone 39 | { 40 | CLSocket *theSocket = [[[self class] alloc] init]; 41 | theSocket.APIKey = self.APIKey; 42 | theSocket.appID = self.appID; 43 | theSocket.authURL = self.authURL; 44 | theSocket.channels = self.channels; 45 | 46 | return theSocket; 47 | } 48 | 49 | #pragma mark - 50 | #pragma mark NSCoding 51 | 52 | - (id)initWithCoder:(NSCoder *)decoder 53 | { 54 | if ((self = [super init])) { 55 | if ([decoder allowsKeyedCoding]) { 56 | _APIKey = [[decoder decodeObjectForKey:CLSocketAPIKeyKey] retain]; 57 | _appID = [decoder decodeIntegerForKey:CLSocketAppIDKey]; 58 | _authURL = [[decoder decodeObjectForKey:CLSocketAuthURLKey] retain]; 59 | _channels = [[decoder decodeObjectForKey:CLSocketChannelsKey] retain]; 60 | } 61 | } 62 | return self; 63 | } 64 | 65 | - (void)encodeWithCoder:(NSCoder *)encoder 66 | { 67 | if ([encoder allowsKeyedCoding]) { 68 | [encoder encodeObject:self.APIKey forKey:CLSocketAPIKeyKey]; 69 | [encoder encodeInteger:self.appID forKey:CLSocketAppIDKey]; 70 | [encoder encodeObject:self.authURL forKey:CLSocketAuthURLKey]; 71 | [encoder encodeObject:self.channels forKey:CLSocketChannelsKey]; 72 | } 73 | } 74 | 75 | #pragma mark - 76 | #pragma mark Memory management 77 | 78 | - (void)dealloc 79 | { 80 | [_APIKey release]; 81 | _APIKey = nil; 82 | [_authURL release]; 83 | _authURL = nil; 84 | [_channels release]; 85 | _channels = nil; 86 | 87 | [super dealloc]; 88 | } 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/Model/CLWebItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLWebItem.h 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 7/20/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CLAPIEngineConstants.h" 11 | 12 | 13 | @interface CLWebItem : NSObject { 14 | NSString *_name; 15 | CLWebItemType _type; 16 | NSURL *_contentURL; 17 | NSString *_mimeType; 18 | NSInteger _viewCount; 19 | NSURL *_remoteURL; 20 | NSURL *_href; 21 | NSURL *_URL; 22 | NSURL *_iconURL; 23 | #if TARGET_OS_IPHONE 24 | UIImage *_icon; 25 | #else 26 | NSImage *_icon; 27 | #endif 28 | BOOL _trashed; 29 | BOOL _private; 30 | NSDate *_createdAt; 31 | NSDate *_updatedAt; 32 | NSDate *_deletedAt; 33 | } 34 | 35 | @property (nonatomic, readwrite, copy) NSString *name; 36 | @property (nonatomic, readwrite, assign) CLWebItemType type; 37 | @property (nonatomic, readwrite, retain) NSURL *contentURL; 38 | @property (nonatomic, readwrite, retain) NSURL *URL; 39 | @property (nonatomic, readwrite, copy) NSString *mimeType; 40 | @property (nonatomic, readwrite, assign) NSInteger viewCount; 41 | @property (nonatomic, readwrite, retain) NSURL *remoteURL; 42 | @property (nonatomic, readwrite, retain) NSURL *href; 43 | @property (nonatomic, readwrite, retain) NSURL *iconURL; 44 | #if TARGET_OS_IPHONE 45 | @property (nonatomic, readwrite, copy) UIImage *icon; 46 | #else 47 | @property (nonatomic, readwrite, copy) NSImage *icon; 48 | #endif 49 | @property (nonatomic, readwrite, assign, getter = isTrashed) BOOL trashed; 50 | @property (nonatomic, readwrite, assign, getter = isPrivate) BOOL private; 51 | @property (nonatomic, readwrite, retain) NSDate *createdAt; 52 | @property (nonatomic, readwrite, retain) NSDate *updatedAt; 53 | @property (nonatomic, readwrite, retain) NSDate *deletedAt; 54 | 55 | - (id)initWithName:(NSString *)theName; 56 | - (id)initWithName:(NSString *)theName type:(CLWebItemType)theType viewCount:(NSInteger)theCount; 57 | 58 | + (id)webItem; 59 | + (id)webItemWithName:(NSString *)theName; 60 | + (id)webItemWithName:(NSString *)theName type:(CLWebItemType)theType viewCount:(NSInteger)theCount; 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Source/libCloud/Cloud/Model/CLWebItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // CLWebItem.m 3 | // Cloud 4 | // 5 | // Created by Nick Paulson on 7/20/10. 6 | // Copyright 2010 Linebreak. All rights reserved. 7 | // 8 | 9 | #import "CLWebItem.h" 10 | 11 | 12 | static NSString * const CLWebItemNameKey = @"CLWebItemNameKey"; 13 | static NSString * const CLWebItemTypeKey = @"CLWebItemTypeKey"; 14 | static NSString * const CLWebItemContentURLKey = @"CLWebItemContentURLKey"; 15 | static NSString * const CLWebItemURLKey = @"CLWebItemURLKey"; 16 | static NSString * const CLWebItemMimeTypeKey = @"CLWebItemMimeTypeKey"; 17 | static NSString * const CLWebItemViewCountKey = @"CLWebItemViewCountKey"; 18 | static NSString * const CLWebItemRemoteURLKey = @"CLWebItemRemoteURLKey"; 19 | static NSString * const CLWebItemHrefKey = @"CLWebItemHrefKey"; 20 | static NSString * const CLWebItemIconURLKey = @"CLWebItemIconURLKey"; 21 | static NSString * const CLWebItemIconKey = @"CLWebItemIconKey"; 22 | static NSString * const CLWebItemTrashedKey = @"CLWebItemTrashedKey"; 23 | static NSString * const CLWebItemPrivateKey = @"CLWebItemPrivateKey"; 24 | static NSString * const CLWebItemCreatedAtKey = @"CLWebItemCreatedAtKey"; 25 | static NSString * const CLWebItemUpdatedAtKey = @"CLWebItemUpdatedAtKey"; 26 | static NSString * const CLWebItemDeletedAtKey = @"CLWebItemDeletedAtKey"; 27 | 28 | 29 | @implementation CLWebItem 30 | 31 | @synthesize name = _name, type = _type, contentURL = _contentURL, mimeType = _mimeType, 32 | viewCount = _viewCount, remoteURL = _remoteURL, href = _href, URL = _URL, iconURL = _iconURL, 33 | icon = _icon, trashed = _trashed, private = _private, createdAt = _createdAt, 34 | updatedAt = _updatedAt, deletedAt = _deletedAt; 35 | 36 | - (id)init 37 | { 38 | return [self initWithName:nil]; 39 | } 40 | 41 | - (id)initWithName:(NSString *)theName 42 | { 43 | return [self initWithName:theName type:CLWebItemTypeNone viewCount:0]; 44 | } 45 | 46 | - (id)initWithName:(NSString *)theName type:(CLWebItemType)theType viewCount:(NSInteger)theCount 47 | { 48 | if ((self = [super init])) { 49 | _name = [theName copy]; 50 | _type = theType; 51 | _viewCount = theCount; 52 | } 53 | return self; 54 | } 55 | 56 | + (id)webItem 57 | { 58 | return [[[[self class] alloc] init] autorelease]; 59 | } 60 | 61 | + (id)webItemWithName:(NSString *)theName 62 | { 63 | return [[[[self class] alloc] initWithName:theName] autorelease]; 64 | } 65 | 66 | + (id)webItemWithName:(NSString *)theName type:(CLWebItemType)theType viewCount:(NSInteger)theCount 67 | { 68 | return [[[[self class] alloc] initWithName:theName type:theType viewCount:theCount] autorelease]; 69 | } 70 | 71 | - (NSString *)description 72 | { 73 | static NSString *format = @"<%@: %@ (%i) %@>"; 74 | return [NSString stringWithFormat:format, NSStringFromClass([self class]), self.name, self.viewCount, self.URL]; 75 | } 76 | 77 | #pragma mark - 78 | #pragma mark NSCopying 79 | 80 | - (id)copyWithZone:(NSZone *)zone 81 | { 82 | CLWebItem *retItem = [[[self class] alloc] initWithName:self.name type:self.type viewCount:self.viewCount]; 83 | retItem.contentURL = self.contentURL; 84 | retItem.mimeType = self.mimeType; 85 | retItem.remoteURL = self.remoteURL; 86 | retItem.href = self.href; 87 | retItem.trashed = self.trashed; 88 | retItem.private = self.private; 89 | retItem.iconURL = self.iconURL; 90 | retItem.icon = self.icon; 91 | retItem.URL = self.URL; 92 | 93 | return retItem; 94 | } 95 | 96 | #pragma mark - 97 | #pragma mark NSCoding 98 | 99 | - (id)initWithCoder:(NSCoder *)decoder 100 | { 101 | if ((self = [super init])) { 102 | if ([decoder allowsKeyedCoding]) { 103 | _name = [[decoder decodeObjectForKey:CLWebItemNameKey] retain]; 104 | _type = [decoder decodeIntegerForKey:CLWebItemTypeKey]; 105 | _viewCount = [decoder decodeIntegerForKey:CLWebItemViewCountKey]; 106 | _contentURL = [[decoder decodeObjectForKey:CLWebItemContentURLKey] retain]; 107 | _URL = [[decoder decodeObjectForKey:CLWebItemURLKey] retain]; 108 | _mimeType = [[decoder decodeObjectForKey:CLWebItemMimeTypeKey] retain]; 109 | _remoteURL = [[decoder decodeObjectForKey:CLWebItemRemoteURLKey] retain]; 110 | _href = [[decoder decodeObjectForKey:CLWebItemHrefKey] retain]; 111 | _trashed = [decoder decodeBoolForKey:CLWebItemTrashedKey]; 112 | _private = [decoder decodeBoolForKey:CLWebItemPrivateKey]; 113 | _iconURL = [[decoder decodeObjectForKey:CLWebItemIconURLKey] retain]; 114 | _icon = [[decoder decodeObjectForKey:CLWebItemIconKey] retain]; 115 | _createdAt = [[decoder decodeObjectForKey:CLWebItemCreatedAtKey] retain]; 116 | _updatedAt = [[decoder decodeObjectForKey:CLWebItemUpdatedAtKey] retain]; 117 | _deletedAt = [[decoder decodeObjectForKey:CLWebItemDeletedAtKey] retain]; 118 | } 119 | } 120 | return self; 121 | } 122 | 123 | - (void)encodeWithCoder:(NSCoder *)encoder 124 | { 125 | if ([encoder allowsKeyedCoding]) { 126 | [encoder encodeObject:self.name forKey:CLWebItemNameKey]; 127 | [encoder encodeInteger:self.type forKey:CLWebItemTypeKey]; 128 | [encoder encodeInteger:self.viewCount forKey:CLWebItemViewCountKey]; 129 | [encoder encodeObject:self.contentURL forKey:CLWebItemContentURLKey]; 130 | [encoder encodeObject:self.URL forKey:CLWebItemURLKey]; 131 | [encoder encodeObject:self.mimeType forKey:CLWebItemMimeTypeKey]; 132 | [encoder encodeObject:self.remoteURL forKey:CLWebItemRemoteURLKey]; 133 | [encoder encodeObject:self.href forKey:CLWebItemHrefKey]; 134 | [encoder encodeBool:self.trashed forKey:CLWebItemTrashedKey]; 135 | [encoder encodeBool:self.private forKey:CLWebItemPrivateKey]; 136 | [encoder encodeObject:self.icon forKey:CLWebItemIconKey]; 137 | [encoder encodeObject:self.iconURL forKey:CLWebItemIconURLKey]; 138 | [encoder encodeObject:self.createdAt forKey:CLWebItemCreatedAtKey]; 139 | [encoder encodeObject:self.updatedAt forKey:CLWebItemUpdatedAtKey]; 140 | [encoder encodeObject:self.deletedAt forKey:CLWebItemDeletedAtKey]; 141 | } 142 | } 143 | 144 | #pragma mark - 145 | #pragma mark Cleanup 146 | 147 | - (void)dealloc 148 | { 149 | [_name release]; 150 | _name = nil; 151 | [_contentURL release]; 152 | _contentURL = nil; 153 | [_mimeType release]; 154 | _mimeType = nil; 155 | [_remoteURL release]; 156 | _remoteURL = nil; 157 | [_href release]; 158 | _href = nil; 159 | [_iconURL release]; 160 | _iconURL = nil; 161 | [_icon release]; 162 | _icon = nil; 163 | [_URL release]; 164 | _URL = nil; 165 | [_createdAt release]; 166 | _createdAt = nil; 167 | [_updatedAt release]; 168 | _updatedAt = nil; 169 | [_deletedAt release]; 170 | _deletedAt = nil; 171 | 172 | [super dealloc]; 173 | } 174 | 175 | @end 176 | --------------------------------------------------------------------------------