Skip to content
Browse files

Replaced ASIHTTPRequest by AFNetworking mainly because ASIHTTPRequest…

… has been discontinued by his lead developer.

But also because AFNetworking is faster, has a minimal codebase and has less dependencies.

This is a major change that has required a modification of all the examples, but with good benefits:

- ImageManager no longer depends on the ApplicationDelegate.
- ImageManager code does not depend on the navigation structure of view controllers.
- Examples need less code.

The Place class has been also removed and the code now uses the builtin MKPointAnnotation class.
  • Loading branch information...
1 parent 3b08227 commit e40d3ce1466a02a50ef7aa12773242934fd391a4 @gimenete committed Oct 28, 2011
Showing with 974 additions and 9,963 deletions.
  1. +86 −88 IOSBoilerplate.xcodeproj/project.pbxproj
  2. +1 −0 IOSBoilerplate/AFNetworking
  3. +66 −0 IOSBoilerplate/AFURLCache.h
  4. +560 −0 IOSBoilerplate/AFURLCache.m
  5. +0 −35 IOSBoilerplate/ASIAuthenticationDialog.h
  6. +0 −487 IOSBoilerplate/ASIAuthenticationDialog.m
  7. +0 −103 IOSBoilerplate/ASICacheDelegate.h
  8. +0 −42 IOSBoilerplate/ASIDataCompressor.h
  9. +0 −219 IOSBoilerplate/ASIDataCompressor.m
  10. +0 −41 IOSBoilerplate/ASIDataDecompressor.h
  11. +0 −218 IOSBoilerplate/ASIDataDecompressor.m
  12. +0 −46 IOSBoilerplate/ASIDownloadCache.h
  13. +0 −514 IOSBoilerplate/ASIDownloadCache.m
  14. +0 −76 IOSBoilerplate/ASIFormDataRequest.h
  15. +0 −361 IOSBoilerplate/ASIFormDataRequest.m
  16. +0 −1,004 IOSBoilerplate/ASIHTTPRequest.h
  17. +0 −5,107 IOSBoilerplate/ASIHTTPRequest.m
  18. +0 −37 IOSBoilerplate/ASIHTTPRequestConfig.h
  19. +0 −35 IOSBoilerplate/ASIHTTPRequestDelegate.h
  20. +0 −26 IOSBoilerplate/ASIInputStream.h
  21. +0 −138 IOSBoilerplate/ASIInputStream.m
  22. +0 −38 IOSBoilerplate/ASIProgressDelegate.h
  23. +1 −1 IOSBoilerplate/AsyncCell.h
  24. +12 −22 IOSBoilerplate/AsyncCell.m
  25. +16 −22 IOSBoilerplate/AsyncCellImagesExample.m
  26. +0 −1 IOSBoilerplate/AsyncImageExample.h
  27. +9 −16 IOSBoilerplate/AsyncImageExample.m
  28. +45 −7 IOSBoilerplate/AutocompleteLocationExample.m
  29. +24 −8 IOSBoilerplate/BaseViewController.h
  30. +43 −47 IOSBoilerplate/BaseViewController.m
  31. +54 −6 IOSBoilerplate/DirectionsExample.m
  32. +16 −18 IOSBoilerplate/HTTPHUDExample.m
  33. +8 −2 IOSBoilerplate/IOSBoilerplateAppDelegate.m
  34. +2 −6 IOSBoilerplate/ImageManager.h
  35. +19 −74 IOSBoilerplate/ImageManager.m
  36. +0 −39 IOSBoilerplate/Place.h
  37. +0 −53 IOSBoilerplate/Place.m
  38. +0 −194 IOSBoilerplate/Reachability/Reachability.h
  39. +0 −814 IOSBoilerplate/Reachability/Reachability.m
  40. +12 −18 IOSBoilerplate/VariableHeightExample.m
View
174 IOSBoilerplate.xcodeproj/project.pbxproj
@@ -15,13 +15,23 @@
0927075E141E4C7800E778AE /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0927075D141E4C7800E778AE /* MapKit.framework */; };
09270761141E4E2B00E778AE /* StringHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 09270760141E4E2B00E778AE /* StringHelper.m */; };
09270764141E4EC900E778AE /* DataHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 09270763141E4EC900E778AE /* DataHelper.m */; };
- 09270767141E4F8500E778AE /* Place.m in Sources */ = {isa = PBXBuildFile; fileRef = 09270766141E4F8400E778AE /* Place.m */; };
09270769141E52BB00E778AE /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09270768141E52BB00E778AE /* CoreLocation.framework */; };
0927076D141E53AB00E778AE /* AutocompleteLocationExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 0927076B141E53AB00E778AE /* AutocompleteLocationExample.m */; };
0927076E141E53AB00E778AE /* AutocompleteLocationExample.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0927076C141E53AB00E778AE /* AutocompleteLocationExample.xib */; };
+ 092D3D1F145AA915002F5F6C /* AFHTTPClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 092D3D0B145AA915002F5F6C /* AFHTTPClient.m */; };
+ 092D3D20145AA915002F5F6C /* AFHTTPRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 092D3D0D145AA915002F5F6C /* AFHTTPRequestOperation.m */; };
+ 092D3D21145AA915002F5F6C /* AFImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 092D3D0F145AA915002F5F6C /* AFImageCache.m */; };
+ 092D3D22145AA915002F5F6C /* AFImageRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 092D3D11145AA915002F5F6C /* AFImageRequestOperation.m */; };
+ 092D3D23145AA915002F5F6C /* AFJSONRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 092D3D13145AA915002F5F6C /* AFJSONRequestOperation.m */; };
+ 092D3D24145AA915002F5F6C /* AFNetworkActivityIndicatorManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 092D3D15145AA915002F5F6C /* AFNetworkActivityIndicatorManager.m */; };
+ 092D3D25145AA915002F5F6C /* AFPropertyListRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 092D3D18145AA915002F5F6C /* AFPropertyListRequestOperation.m */; };
+ 092D3D26145AA915002F5F6C /* AFURLConnectionOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 092D3D1A145AA915002F5F6C /* AFURLConnectionOperation.m */; };
+ 092D3D27145AA915002F5F6C /* AFXMLRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 092D3D1C145AA915002F5F6C /* AFXMLRequestOperation.m */; };
+ 092D3D28145AA915002F5F6C /* UIImageView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 092D3D1E145AA915002F5F6C /* UIImageView+AFNetworking.m */; };
+ 092D3D2C145AE54E002F5F6C /* AFURLCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 092D3D2B145AE54E002F5F6C /* AFURLCache.m */; };
+ 09507B261459B92800CEBABF /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09885E981418F2E600CCE17A /* CoreGraphics.framework */; };
09885E951418F2E500CCE17A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09885E941418F2E500CCE17A /* UIKit.framework */; };
09885E971418F2E500CCE17A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09885E961418F2E500CCE17A /* Foundation.framework */; };
- 09885E991418F2E600CCE17A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09885E981418F2E600CCE17A /* CoreGraphics.framework */; };
09885E9F1418F2E600CCE17A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 09885E9D1418F2E600CCE17A /* InfoPlist.strings */; };
09885EA11418F2E600CCE17A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 09885EA01418F2E600CCE17A /* main.m */; };
09885EA51418F2E600CCE17A /* IOSBoilerplateAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 09885EA41418F2E600CCE17A /* IOSBoilerplateAppDelegate.m */; };
@@ -35,17 +45,6 @@
09885EC11418F2E600CCE17A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 09885EBF1418F2E600CCE17A /* InfoPlist.strings */; };
09885EC31418F2E600CCE17A /* IOSBoilerplateTests.h in Resources */ = {isa = PBXBuildFile; fileRef = 09885EC21418F2E600CCE17A /* IOSBoilerplateTests.h */; };
09885EC51418F2E600CCE17A /* IOSBoilerplateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 09885EC41418F2E600CCE17A /* IOSBoilerplateTests.m */; };
- 09885EE11418F3B700CCE17A /* ASIAuthenticationDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = 09885ED01418F3B700CCE17A /* ASIAuthenticationDialog.m */; };
- 09885EE21418F3B700CCE17A /* ASIDataCompressor.m in Sources */ = {isa = PBXBuildFile; fileRef = 09885ED31418F3B700CCE17A /* ASIDataCompressor.m */; };
- 09885EE31418F3B700CCE17A /* ASIDataDecompressor.m in Sources */ = {isa = PBXBuildFile; fileRef = 09885ED51418F3B700CCE17A /* ASIDataDecompressor.m */; };
- 09885EE41418F3B700CCE17A /* ASIDownloadCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 09885ED71418F3B700CCE17A /* ASIDownloadCache.m */; };
- 09885EE51418F3B700CCE17A /* ASIFormDataRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 09885ED91418F3B700CCE17A /* ASIFormDataRequest.m */; };
- 09885EE61418F3B700CCE17A /* ASIHTTPRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 09885EDB1418F3B700CCE17A /* ASIHTTPRequest.m */; };
- 09885EE71418F3B700CCE17A /* ASIInputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 09885EDF1418F3B700CCE17A /* ASIInputStream.m */; };
- 09885EEB1418F3DA00CCE17A /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 09885EEA1418F3DA00CCE17A /* Reachability.m */; };
- 09885EED1418F3F900CCE17A /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09885EEC1418F3F900CCE17A /* CFNetwork.framework */; };
- 09885EEF1418F40200CCE17A /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09885EEE1418F40200CCE17A /* SystemConfiguration.framework */; };
- 09885EF21418F44200CCE17A /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09885EF11418F44200CCE17A /* MobileCoreServices.framework */; };
09885EF91418F4AB00CCE17A /* BaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 09885EF81418F4AB00CCE17A /* BaseViewController.m */; };
09885F381418F73A00CCE17A /* ImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 09885F371418F73A00CCE17A /* ImageManager.m */; };
09885F3C1418FC6F00CCE17A /* HTTPHUDExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 09885F3A1418FC6E00CCE17A /* HTTPHUDExample.m */; };
@@ -76,7 +75,6 @@
09E442D9141F9DD400AD2DAE /* SwipeableTableViewExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E442D7141F9DD400AD2DAE /* SwipeableTableViewExample.m */; };
09E442DA141F9DD400AD2DAE /* SwipeableTableViewExample.xib in Resources */ = {isa = PBXBuildFile; fileRef = 09E442D8141F9DD400AD2DAE /* SwipeableTableViewExample.xib */; };
09E442DD141F9E3600AD2DAE /* SwipeableCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E442DC141F9E3600AD2DAE /* SwipeableCell.m */; };
- C37BC8E4144C340600423D44 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C37BC8E3144C340600423D44 /* libz.dylib */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -103,12 +101,33 @@
09270760141E4E2B00E778AE /* StringHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StringHelper.m; sourceTree = "<group>"; };
09270762141E4EC900E778AE /* DataHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataHelper.h; sourceTree = "<group>"; };
09270763141E4EC900E778AE /* DataHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataHelper.m; sourceTree = "<group>"; };
- 09270765141E4F8400E778AE /* Place.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Place.h; sourceTree = "<group>"; };
- 09270766141E4F8400E778AE /* Place.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Place.m; sourceTree = "<group>"; };
09270768141E52BB00E778AE /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
0927076A141E53AB00E778AE /* AutocompleteLocationExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutocompleteLocationExample.h; sourceTree = "<group>"; };
0927076B141E53AB00E778AE /* AutocompleteLocationExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AutocompleteLocationExample.m; sourceTree = "<group>"; };
0927076C141E53AB00E778AE /* AutocompleteLocationExample.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AutocompleteLocationExample.xib; sourceTree = "<group>"; };
+ 092D3D0A145AA915002F5F6C /* AFHTTPClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPClient.h; sourceTree = "<group>"; };
+ 092D3D0B145AA915002F5F6C /* AFHTTPClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFHTTPClient.m; sourceTree = "<group>"; };
+ 092D3D0C145AA915002F5F6C /* AFHTTPRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPRequestOperation.h; sourceTree = "<group>"; };
+ 092D3D0D145AA915002F5F6C /* AFHTTPRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFHTTPRequestOperation.m; sourceTree = "<group>"; };
+ 092D3D0E145AA915002F5F6C /* AFImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFImageCache.h; sourceTree = "<group>"; };
+ 092D3D0F145AA915002F5F6C /* AFImageCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFImageCache.m; sourceTree = "<group>"; };
+ 092D3D10145AA915002F5F6C /* AFImageRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFImageRequestOperation.h; sourceTree = "<group>"; };
+ 092D3D11145AA915002F5F6C /* AFImageRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFImageRequestOperation.m; sourceTree = "<group>"; };
+ 092D3D12145AA915002F5F6C /* AFJSONRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFJSONRequestOperation.h; sourceTree = "<group>"; };
+ 092D3D13145AA915002F5F6C /* AFJSONRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFJSONRequestOperation.m; sourceTree = "<group>"; };
+ 092D3D14145AA915002F5F6C /* AFNetworkActivityIndicatorManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFNetworkActivityIndicatorManager.h; sourceTree = "<group>"; };
+ 092D3D15145AA915002F5F6C /* AFNetworkActivityIndicatorManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFNetworkActivityIndicatorManager.m; sourceTree = "<group>"; };
+ 092D3D16145AA915002F5F6C /* AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFNetworking.h; sourceTree = "<group>"; };
+ 092D3D17145AA915002F5F6C /* AFPropertyListRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFPropertyListRequestOperation.h; sourceTree = "<group>"; };
+ 092D3D18145AA915002F5F6C /* AFPropertyListRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFPropertyListRequestOperation.m; sourceTree = "<group>"; };
+ 092D3D19145AA915002F5F6C /* AFURLConnectionOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLConnectionOperation.h; sourceTree = "<group>"; };
+ 092D3D1A145AA915002F5F6C /* AFURLConnectionOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLConnectionOperation.m; sourceTree = "<group>"; };
+ 092D3D1B145AA915002F5F6C /* AFXMLRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFXMLRequestOperation.h; sourceTree = "<group>"; };
+ 092D3D1C145AA915002F5F6C /* AFXMLRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFXMLRequestOperation.m; sourceTree = "<group>"; };
+ 092D3D1D145AA915002F5F6C /* UIImageView+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImageView+AFNetworking.h"; sourceTree = "<group>"; };
+ 092D3D1E145AA915002F5F6C /* UIImageView+AFNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImageView+AFNetworking.m"; sourceTree = "<group>"; };
+ 092D3D2A145AE54E002F5F6C /* AFURLCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLCache.h; sourceTree = "<group>"; };
+ 092D3D2B145AE54E002F5F6C /* AFURLCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLCache.m; sourceTree = "<group>"; };
09885E901418F2E500CCE17A /* IOSBoilerplate.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IOSBoilerplate.app; sourceTree = BUILT_PRODUCTS_DIR; };
09885E941418F2E500CCE17A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
09885E961418F2E500CCE17A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
@@ -129,26 +148,6 @@
09885EC01418F2E600CCE17A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
09885EC21418F2E600CCE17A /* IOSBoilerplateTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IOSBoilerplateTests.h; sourceTree = "<group>"; };
09885EC41418F2E600CCE17A /* IOSBoilerplateTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IOSBoilerplateTests.m; sourceTree = "<group>"; };
- 09885ECF1418F3B700CCE17A /* ASIAuthenticationDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIAuthenticationDialog.h; sourceTree = "<group>"; };
- 09885ED01418F3B700CCE17A /* ASIAuthenticationDialog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIAuthenticationDialog.m; sourceTree = "<group>"; };
- 09885ED11418F3B700CCE17A /* ASICacheDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASICacheDelegate.h; sourceTree = "<group>"; };
- 09885ED21418F3B700CCE17A /* ASIDataCompressor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIDataCompressor.h; sourceTree = "<group>"; };
- 09885ED31418F3B700CCE17A /* ASIDataCompressor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIDataCompressor.m; sourceTree = "<group>"; };
- 09885ED41418F3B700CCE17A /* ASIDataDecompressor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIDataDecompressor.h; sourceTree = "<group>"; };
- 09885ED51418F3B700CCE17A /* ASIDataDecompressor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIDataDecompressor.m; sourceTree = "<group>"; };
- 09885ED61418F3B700CCE17A /* ASIDownloadCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIDownloadCache.h; sourceTree = "<group>"; };
- 09885ED71418F3B700CCE17A /* ASIDownloadCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIDownloadCache.m; sourceTree = "<group>"; };
- 09885ED81418F3B700CCE17A /* ASIFormDataRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIFormDataRequest.h; sourceTree = "<group>"; };
- 09885ED91418F3B700CCE17A /* ASIFormDataRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIFormDataRequest.m; sourceTree = "<group>"; };
- 09885EDA1418F3B700CCE17A /* ASIHTTPRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIHTTPRequest.h; sourceTree = "<group>"; };
- 09885EDB1418F3B700CCE17A /* ASIHTTPRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIHTTPRequest.m; sourceTree = "<group>"; };
- 09885EDC1418F3B700CCE17A /* ASIHTTPRequestConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIHTTPRequestConfig.h; sourceTree = "<group>"; };
- 09885EDD1418F3B700CCE17A /* ASIHTTPRequestDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIHTTPRequestDelegate.h; sourceTree = "<group>"; };
- 09885EDE1418F3B700CCE17A /* ASIInputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIInputStream.h; sourceTree = "<group>"; };
- 09885EDF1418F3B700CCE17A /* ASIInputStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIInputStream.m; sourceTree = "<group>"; };
- 09885EE01418F3B700CCE17A /* ASIProgressDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIProgressDelegate.h; sourceTree = "<group>"; };
- 09885EE91418F3DA00CCE17A /* Reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reachability.h; sourceTree = "<group>"; };
- 09885EEA1418F3DA00CCE17A /* Reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Reachability.m; sourceTree = "<group>"; };
09885EEC1418F3F900CCE17A /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
09885EEE1418F40200CCE17A /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
09885EF11418F44200CCE17A /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
@@ -205,14 +204,10 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- C37BC8E4144C340600423D44 /* libz.dylib in Frameworks */,
+ 09507B261459B92800CEBABF /* CoreGraphics.framework in Frameworks */,
09270769141E52BB00E778AE /* CoreLocation.framework in Frameworks */,
0927075E141E4C7800E778AE /* MapKit.framework in Frameworks */,
09885F451419009200CCE17A /* QuartzCore.framework in Frameworks */,
- 09885EF21418F44200CCE17A /* MobileCoreServices.framework in Frameworks */,
- 09885E991418F2E600CCE17A /* CoreGraphics.framework in Frameworks */,
- 09885EEF1418F40200CCE17A /* SystemConfiguration.framework in Frameworks */,
- 09885EED1418F3F900CCE17A /* CFNetwork.framework in Frameworks */,
09885E951418F2E500CCE17A /* UIKit.framework in Frameworks */,
09885E971418F2E500CCE17A /* Foundation.framework in Frameworks */,
);
@@ -232,6 +227,43 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 092D3D09145AA915002F5F6C /* AFNetworking */ = {
+ isa = PBXGroup;
+ children = (
+ 092D3D0A145AA915002F5F6C /* AFHTTPClient.h */,
+ 092D3D0B145AA915002F5F6C /* AFHTTPClient.m */,
+ 092D3D0C145AA915002F5F6C /* AFHTTPRequestOperation.h */,
+ 092D3D0D145AA915002F5F6C /* AFHTTPRequestOperation.m */,
+ 092D3D0E145AA915002F5F6C /* AFImageCache.h */,
+ 092D3D0F145AA915002F5F6C /* AFImageCache.m */,
+ 092D3D10145AA915002F5F6C /* AFImageRequestOperation.h */,
+ 092D3D11145AA915002F5F6C /* AFImageRequestOperation.m */,
+ 092D3D12145AA915002F5F6C /* AFJSONRequestOperation.h */,
+ 092D3D13145AA915002F5F6C /* AFJSONRequestOperation.m */,
+ 092D3D14145AA915002F5F6C /* AFNetworkActivityIndicatorManager.h */,
+ 092D3D15145AA915002F5F6C /* AFNetworkActivityIndicatorManager.m */,
+ 092D3D16145AA915002F5F6C /* AFNetworking.h */,
+ 092D3D17145AA915002F5F6C /* AFPropertyListRequestOperation.h */,
+ 092D3D18145AA915002F5F6C /* AFPropertyListRequestOperation.m */,
+ 092D3D19145AA915002F5F6C /* AFURLConnectionOperation.h */,
+ 092D3D1A145AA915002F5F6C /* AFURLConnectionOperation.m */,
+ 092D3D1B145AA915002F5F6C /* AFXMLRequestOperation.h */,
+ 092D3D1C145AA915002F5F6C /* AFXMLRequestOperation.m */,
+ 092D3D1D145AA915002F5F6C /* UIImageView+AFNetworking.h */,
+ 092D3D1E145AA915002F5F6C /* UIImageView+AFNetworking.m */,
+ );
+ path = AFNetworking;
+ sourceTree = "<group>";
+ };
+ 092D3D29145AE52F002F5F6C /* AFURLCache */ = {
+ isa = PBXGroup;
+ children = (
+ 092D3D2A145AE54E002F5F6C /* AFURLCache.h */,
+ 092D3D2B145AE54E002F5F6C /* AFURLCache.m */,
+ );
+ name = AFURLCache;
+ sourceTree = "<group>";
+ };
09885E851418F2E500CCE17A = {
isa = PBXGroup;
children = (
@@ -272,13 +304,13 @@
09885E9A1418F2E600CCE17A /* IOSBoilerplate */ = {
isa = PBXGroup;
children = (
+ 092D3D29145AE52F002F5F6C /* AFURLCache */,
+ 092D3D09145AA915002F5F6C /* AFNetworking */,
09E442B7141F969400AD2DAE /* RefreshTableHeaderView */,
09885F491419027D00CCE17A /* JSONKit */,
09885F3E1418FFE000CCE17A /* SVProgressHUD */,
09885EF61418F48F00CCE17A /* Helpers */,
09885EF51418F48300CCE17A /* Examples */,
- 09885EE81418F3DA00CCE17A /* Reachability */,
- 09885ECE1418F33F00CCE17A /* ASIHTTPRequest */,
09885EA31418F2E600CCE17A /* IOSBoilerplateAppDelegate.h */,
09885EA41418F2E600CCE17A /* IOSBoilerplateAppDelegate.m */,
09885EA61418F2E600CCE17A /* MainWindow.xib */,
@@ -321,40 +353,6 @@
name = "Supporting Files";
sourceTree = "<group>";
};
- 09885ECE1418F33F00CCE17A /* ASIHTTPRequest */ = {
- isa = PBXGroup;
- children = (
- 09885ECF1418F3B700CCE17A /* ASIAuthenticationDialog.h */,
- 09885ED01418F3B700CCE17A /* ASIAuthenticationDialog.m */,
- 09885ED11418F3B700CCE17A /* ASICacheDelegate.h */,
- 09885ED21418F3B700CCE17A /* ASIDataCompressor.h */,
- 09885ED31418F3B700CCE17A /* ASIDataCompressor.m */,
- 09885ED41418F3B700CCE17A /* ASIDataDecompressor.h */,
- 09885ED51418F3B700CCE17A /* ASIDataDecompressor.m */,
- 09885ED61418F3B700CCE17A /* ASIDownloadCache.h */,
- 09885ED71418F3B700CCE17A /* ASIDownloadCache.m */,
- 09885ED81418F3B700CCE17A /* ASIFormDataRequest.h */,
- 09885ED91418F3B700CCE17A /* ASIFormDataRequest.m */,
- 09885EDA1418F3B700CCE17A /* ASIHTTPRequest.h */,
- 09885EDB1418F3B700CCE17A /* ASIHTTPRequest.m */,
- 09885EDC1418F3B700CCE17A /* ASIHTTPRequestConfig.h */,
- 09885EDD1418F3B700CCE17A /* ASIHTTPRequestDelegate.h */,
- 09885EDE1418F3B700CCE17A /* ASIInputStream.h */,
- 09885EDF1418F3B700CCE17A /* ASIInputStream.m */,
- 09885EE01418F3B700CCE17A /* ASIProgressDelegate.h */,
- );
- name = ASIHTTPRequest;
- sourceTree = "<group>";
- };
- 09885EE81418F3DA00CCE17A /* Reachability */ = {
- isa = PBXGroup;
- children = (
- 09885EE91418F3DA00CCE17A /* Reachability.h */,
- 09885EEA1418F3DA00CCE17A /* Reachability.m */,
- );
- path = Reachability;
- sourceTree = "<group>";
- };
09885EF51418F48300CCE17A /* Examples */ = {
isa = PBXGroup;
children = (
@@ -407,8 +405,6 @@
09270760141E4E2B00E778AE /* StringHelper.m */,
09270762141E4EC900E778AE /* DataHelper.h */,
09270763141E4EC900E778AE /* DataHelper.m */,
- 09270765141E4F8400E778AE /* Place.h */,
- 09270766141E4F8400E778AE /* Place.m */,
09E442CE141F97AE00AD2DAE /* ListViewController.h */,
09E442CF141F97AE00AD2DAE /* ListViewController.m */,
);
@@ -583,14 +579,6 @@
09885EA11418F2E600CCE17A /* main.m in Sources */,
09885EA51418F2E600CCE17A /* IOSBoilerplateAppDelegate.m in Sources */,
09885EAB1418F2E600CCE17A /* RootViewController.m in Sources */,
- 09885EE11418F3B700CCE17A /* ASIAuthenticationDialog.m in Sources */,
- 09885EE21418F3B700CCE17A /* ASIDataCompressor.m in Sources */,
- 09885EE31418F3B700CCE17A /* ASIDataDecompressor.m in Sources */,
- 09885EE41418F3B700CCE17A /* ASIDownloadCache.m in Sources */,
- 09885EE51418F3B700CCE17A /* ASIFormDataRequest.m in Sources */,
- 09885EE61418F3B700CCE17A /* ASIHTTPRequest.m in Sources */,
- 09885EE71418F3B700CCE17A /* ASIInputStream.m in Sources */,
- 09885EEB1418F3DA00CCE17A /* Reachability.m in Sources */,
09885EF91418F4AB00CCE17A /* BaseViewController.m in Sources */,
09885F381418F73A00CCE17A /* ImageManager.m in Sources */,
09885F3C1418FC6F00CCE17A /* HTTPHUDExample.m in Sources */,
@@ -606,13 +594,23 @@
0927075A141E4BDF00E778AE /* DirectionsExample.m in Sources */,
09270761141E4E2B00E778AE /* StringHelper.m in Sources */,
09270764141E4EC900E778AE /* DataHelper.m in Sources */,
- 09270767141E4F8500E778AE /* Place.m in Sources */,
0927076D141E53AB00E778AE /* AutocompleteLocationExample.m in Sources */,
09E442BB141F96A900AD2DAE /* EGORefreshTableHeaderView.m in Sources */,
09E442D0141F97AE00AD2DAE /* ListViewController.m in Sources */,
09E442D4141F989200AD2DAE /* PullDownExample.m in Sources */,
09E442D9141F9DD400AD2DAE /* SwipeableTableViewExample.m in Sources */,
09E442DD141F9E3600AD2DAE /* SwipeableCell.m in Sources */,
+ 092D3D1F145AA915002F5F6C /* AFHTTPClient.m in Sources */,
+ 092D3D20145AA915002F5F6C /* AFHTTPRequestOperation.m in Sources */,
+ 092D3D21145AA915002F5F6C /* AFImageCache.m in Sources */,
+ 092D3D22145AA915002F5F6C /* AFImageRequestOperation.m in Sources */,
+ 092D3D23145AA915002F5F6C /* AFJSONRequestOperation.m in Sources */,
+ 092D3D24145AA915002F5F6C /* AFNetworkActivityIndicatorManager.m in Sources */,
+ 092D3D25145AA915002F5F6C /* AFPropertyListRequestOperation.m in Sources */,
+ 092D3D26145AA915002F5F6C /* AFURLConnectionOperation.m in Sources */,
+ 092D3D27145AA915002F5F6C /* AFXMLRequestOperation.m in Sources */,
+ 092D3D28145AA915002F5F6C /* UIImageView+AFNetworking.m in Sources */,
+ 092D3D2C145AE54E002F5F6C /* AFURLCache.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
1 IOSBoilerplate/AFNetworking
@@ -0,0 +1 @@
+Subproject commit 4a6a93e8d46895aa3b4e888f439d2655b1438a94
View
66 IOSBoilerplate/AFURLCache.h
@@ -0,0 +1,66 @@
+// AFURLCache.h
+//
+// Copyright (c) 2010-2011 Olivier Poitrey <rs@dailymotion.com>
+// Modernized to use GCD by Peter Steinberger <steipete@gmail.com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is furnished
+// to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import <Foundation/Foundation.h>
+
+@interface AFURLCache : NSURLCache {
+ NSString *_diskCachePath;
+ NSMutableDictionary *_diskCacheInfo;
+ BOOL _diskCacheInfoDirty;
+ BOOL _ignoreMemoryOnlyStoragePolicy;
+ NSUInteger _diskCacheUsage;
+ NSTimeInterval _minCacheInterval;
+ dispatch_source_t _maintenanceTimer;
+ BOOL _timerPaused;
+}
+
+/*
+ * Defines the minimum number of seconds between now and the expiration time of a cacheable response
+ * in order for the response to be cached on disk. This prevent from spending time and storage capacity
+ * for an entry which will certainly expire before behing read back from disk cache (memory cache is
+ * best suited for short term cache). The default value is set to 5 minutes (300 seconds).
+ */
+@property (nonatomic, assign) NSTimeInterval minCacheInterval;
+
+/*
+ * Allow the responses that have a storage policy of NSURLCacheStorageAllowedInMemoryOnly to be cached
+ * on the disk anyway.
+ *
+ * This is mainly a workaround against cache policies generated by the UIWebViews: starting from iOS 4.2,
+ * it always has a cache policy of NSURLCacheStorageAllowedInMemoryOnly.
+ * The default value is YES
+ */
+@property (nonatomic, assign) BOOL ignoreMemoryOnlyStoragePolicy;
+
+/*
+ * Returns a default cache director path to be used at cache initialization. The generated path directory
+ * will be located in the application's cache directory and thus won't be synced by iTunes.
+ */
++ (NSString *)defaultCachePath;
+
+/*
+ * Checks if the provided URL exists in cache.
+ */
+- (BOOL)isCached:(NSURL *)url;
+
+@end
View
560 IOSBoilerplate/AFURLCache.m
@@ -0,0 +1,560 @@
+// AFURLCache.m
+//
+// Copyright (c) 2010-2011 Olivier Poitrey <rs@dailymotion.com>
+// Modernized to use GCD by Peter Steinberger <steipete@gmail.com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is furnished
+// to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import "AFURLCache.h"
+#import <CommonCrypto/CommonDigest.h>
+
+#define kAFURLCachePath @"AFNetworkingURLCache"
+#define kAFURLCacheMaintenanceTime 5ull
+
+static NSTimeInterval const kAFURLCacheInfoDefaultMinCacheInterval = 5 * 60; // 5 minute
+static NSString *const kAFURLCacheInfoFileName = @"cacheInfo.plist";
+static NSString *const kAFURLCacheInfoDiskUsageKey = @"diskUsage";
+static NSString *const kAFURLCacheInfoAccessesKey = @"accesses";
+static NSString *const kAFURLCacheInfoSizesKey = @"sizes";
+static float const kAFURLCacheLastModFraction = 0.1f; // 10% since Last-Modified suggested by RFC2616 section 13.2.4
+static float const kAFURLCacheDefault = 3600; // Default cache expiration delay if none defined (1 hour)
+
+static NSDateFormatter* CreateDateFormatter(NSString *format) {
+ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
+ [dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] autorelease]];
+ [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];
+ [dateFormatter setDateFormat:format];
+ return dateFormatter;
+}
+
+@implementation NSCachedURLResponse(NSCoder)
+
+- (void)encodeWithCoder:(NSCoder *)coder {
+ [coder encodeDataObject:self.data];
+ [coder encodeObject:self.response forKey:@"response"];
+ [coder encodeObject:self.userInfo forKey:@"userInfo"];
+ [coder encodeInt:self.storagePolicy forKey:@"storagePolicy"];
+}
+
+- (id)initWithCoder:(NSCoder *)coder {
+ return [self initWithResponse:[coder decodeObjectForKey:@"response"]
+ data:[coder decodeDataObject]
+ userInfo:[coder decodeObjectForKey:@"userInfo"]
+ storagePolicy:[coder decodeIntForKey:@"storagePolicy"]];
+}
+
+@end
+
+// deadlock-free variant of dispatch_sync
+void dispatch_sync_afreentrant(dispatch_queue_t queue, dispatch_block_t block);
+inline void dispatch_sync_afreentrant(dispatch_queue_t queue, dispatch_block_t block) {
+ dispatch_get_current_queue() == queue ? block() : dispatch_sync(queue, block);
+}
+
+void dispatch_async_afreentrant(dispatch_queue_t queue, dispatch_block_t block);
+inline void dispatch_async_afreentrant(dispatch_queue_t queue, dispatch_block_t block) {
+ dispatch_get_current_queue() == queue ? block() : dispatch_async(queue, block);
+}
+
+@interface AFURLCache ()
+@property (nonatomic, retain) NSString *diskCachePath;
+@property (nonatomic, retain) NSMutableDictionary *diskCacheInfo;
+- (void)periodicMaintenance;
+@end
+
+@implementation AFURLCache
+
+#pragma mark AFURLCache (tools)
+
++ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
+ NSString *string = request.URL.absoluteString;
+ NSRange hash = [string rangeOfString:@"#"];
+ if (hash.location == NSNotFound)
+ return request;
+
+ NSMutableURLRequest *copy = [[request mutableCopy] autorelease];
+ copy.URL = [NSURL URLWithString:[string substringToIndex:hash.location]];
+ return copy;
+}
+
++ (NSString *)cacheKeyForURL:(NSURL *)url {
+ const char *str = [url.absoluteString UTF8String];
+ unsigned char r[CC_MD5_DIGEST_LENGTH];
+ CC_MD5(str, strlen(str), r);
+ return [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]];
+}
+
+#pragma mark AFURLCache (private)
+
+static dispatch_queue_t get_date_formatter_queue() {
+ static dispatch_queue_t _dateFormatterQueue;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ _dateFormatterQueue = dispatch_queue_create("com.alamofire.disk-cache.dateformatter", NULL);
+ });
+ return _dateFormatterQueue;
+}
+
+static dispatch_queue_t get_disk_cache_queue() {
+ static dispatch_once_t onceToken;
+ static dispatch_queue_t _diskCacheQueue;
+ dispatch_once(&onceToken, ^{
+ _diskCacheQueue = dispatch_queue_create("com.alamofire.disk-cache.processing", NULL);
+ });
+ return _diskCacheQueue;
+}
+
+static dispatch_queue_t get_disk_io_queue() {
+ static dispatch_queue_t _diskIOQueue;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ _diskIOQueue = dispatch_queue_create("com.alamofire.disk-cache.io", NULL);
+ });
+ return _diskIOQueue;
+}
+
+- (dispatch_source_t)maintenanceTimer {
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+ _maintenanceTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
+ if (_maintenanceTimer) {
+ dispatch_source_set_timer(_maintenanceTimer, dispatch_walltime(DISPATCH_TIME_NOW, kAFURLCacheMaintenanceTime * NSEC_PER_SEC),
+ kAFURLCacheMaintenanceTime * NSEC_PER_SEC, kAFURLCacheMaintenanceTime/2 * NSEC_PER_SEC);
+ __block AFURLCache *blockSelf = self;
+ dispatch_source_set_event_handler(_maintenanceTimer, ^{
+ [blockSelf periodicMaintenance];
+
+ // will abuse cache queue to lock timer
+ dispatch_async_afreentrant(get_disk_cache_queue(), ^{
+ dispatch_suspend(_maintenanceTimer); // pause timer
+ _timerPaused = YES;
+ });
+ });
+ // initially wake up timer
+ dispatch_resume(_maintenanceTimer);
+ }
+ });
+ return _maintenanceTimer;
+}
+
+/*
+ * Parse HTTP Date: http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1
+ */
++ (NSDate *)dateFromHttpDateString:(NSString *)httpDate {
+ static dispatch_once_t onceToken;
+ static NSDateFormatter *_FC1123DateFormatter;
+ static NSDateFormatter *_ANSICDateFormatter;
+ static NSDateFormatter *_RFC850DateFormatter;
+ dispatch_once(&onceToken, ^{
+ _FC1123DateFormatter = CreateDateFormatter(@"EEE, dd MMM yyyy HH:mm:ss z");
+ _ANSICDateFormatter = CreateDateFormatter(@"EEE MMM d HH:mm:ss yyyy");
+ _RFC850DateFormatter = CreateDateFormatter(@"EEEE, dd-MMM-yy HH:mm:ss z");
+ });
+
+ __block NSDate *date = nil;
+ dispatch_sync(get_date_formatter_queue(), ^{
+ date = [_FC1123DateFormatter dateFromString:httpDate];
+ if (!date) {
+ // ANSI C date format - Sun Nov 6 08:49:37 1994
+ date = [_ANSICDateFormatter dateFromString:httpDate];
+ if (!date) {
+ // RFC 850 date format - Sunday, 06-Nov-94 08:49:37 GMT
+ date = [_RFC850DateFormatter dateFromString:httpDate];
+ }
+ }
+ });
+
+ return date;
+}
+
+/*
+ * This method tries to determine the expiration date based on a response headers dictionary.
+ */
++ (NSDate *)expirationDateFromHeaders:(NSDictionary *)headers withStatusCode:(NSInteger)status {
+ if (status != 200 && status != 203 && status != 300 && status != 301 && status != 302 && status != 307 && status != 410) {
+ // Uncacheable response status code
+ return nil;
+ }
+
+ // Check Pragma: no-cache
+ NSString *pragma = [headers objectForKey:@"Pragma"];
+ if (pragma && [pragma isEqualToString:@"no-cache"]) {
+ // Uncacheable response
+ return nil;
+ }
+
+ // Define "now" based on the request
+ NSString *date = [headers objectForKey:@"Date"];
+ // If no Date: header, define now from local clock
+ NSDate *now = date ? [AFURLCache dateFromHttpDateString:date] : [NSDate date];
+
+ // Look at info from the Cache-Control: max-age=n header
+ NSString *cacheControl = [headers objectForKey:@"Cache-Control"];
+ if (cacheControl) {
+ NSRange foundRange = [cacheControl rangeOfString:@"no-store"];
+ if (foundRange.length > 0) {
+ // Can't be cached
+ return nil;
+ }
+
+ NSInteger maxAge;
+ foundRange = [cacheControl rangeOfString:@"max-age="];
+ if (foundRange.length > 0) {
+ NSScanner *cacheControlScanner = [NSScanner scannerWithString:cacheControl];
+ [cacheControlScanner setScanLocation:foundRange.location + foundRange.length];
+ if ([cacheControlScanner scanInteger:&maxAge]) {
+ return maxAge > 0 ? [[[NSDate alloc] initWithTimeInterval:maxAge sinceDate:now] autorelease] : nil;
+ }
+ }
+ }
+
+ // If not Cache-Control found, look at the Expires header
+ NSString *expires = [headers objectForKey:@"Expires"];
+ if (expires) {
+ NSTimeInterval expirationInterval = 0;
+ NSDate *expirationDate = [AFURLCache dateFromHttpDateString:expires];
+ if (expirationDate) {
+ expirationInterval = [expirationDate timeIntervalSinceDate:now];
+ }
+ if (expirationInterval > 0) {
+ // Convert remote expiration date to local expiration date
+ return [NSDate dateWithTimeIntervalSinceNow:expirationInterval];
+ }
+ else {
+ // If the Expires header can't be parsed or is expired, do not cache
+ return nil;
+ }
+ }
+
+ if (status == 302 || status == 307) {
+ // If not explict cache control defined, do not cache those status
+ return nil;
+ }
+
+ // If no cache control defined, try some heristic to determine an expiration date
+ NSString *lastModified = [headers objectForKey:@"Last-Modified"];
+ if (lastModified) {
+ NSTimeInterval age = 0;
+ NSDate *lastModifiedDate = [AFURLCache dateFromHttpDateString:lastModified];
+ if (lastModifiedDate) {
+ // Define the age of the document by comparing the Date header with the Last-Modified header
+ age = [now timeIntervalSinceDate:lastModifiedDate];
+ }
+ return age > 0 ? [NSDate dateWithTimeIntervalSinceNow:(age * kAFURLCacheLastModFraction)] : nil;
+ }
+
+ // If nothing permitted to define the cache expiration delay nor to restrict its cacheability, use a default cache expiration delay
+ return [[[NSDate alloc] initWithTimeInterval:kAFURLCacheDefault sinceDate:now] autorelease];
+}
+
+- (NSMutableDictionary *)diskCacheInfo {
+ if (!_diskCacheInfo) {
+ dispatch_sync_afreentrant(get_disk_cache_queue(), ^{
+ if (!_diskCacheInfo) { // Check again, maybe another thread created it while waiting for the mutex
+ _diskCacheInfo = [[NSMutableDictionary alloc] initWithContentsOfFile:[_diskCachePath stringByAppendingPathComponent:kAFURLCacheInfoFileName]];
+ if (!_diskCacheInfo) {
+ _diskCacheInfo = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithUnsignedInt:0], kAFURLCacheInfoDiskUsageKey,
+ [NSMutableDictionary dictionary], kAFURLCacheInfoAccessesKey,
+ [NSMutableDictionary dictionary], kAFURLCacheInfoSizesKey,
+ nil];
+ }
+ _diskCacheInfoDirty = NO;
+ _diskCacheUsage = [[_diskCacheInfo objectForKey:kAFURLCacheInfoDiskUsageKey] unsignedIntValue];
+
+ // create maintenance timer
+ [self maintenanceTimer];
+ }
+ });
+ }
+
+ return _diskCacheInfo;
+}
+
+- (void)createDiskCachePath {
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ NSFileManager *fileManager = [[NSFileManager alloc] init];
+ if (![fileManager fileExistsAtPath:_diskCachePath]) {
+ [fileManager createDirectoryAtPath:_diskCachePath
+ withIntermediateDirectories:YES
+ attributes:nil
+ error:NULL];
+ }
+ [fileManager release];
+ });
+}
+
+- (void)saveCacheInfo {
+ [self createDiskCachePath];
+ dispatch_async_afreentrant(get_disk_cache_queue(), ^{
+ NSData *data = [NSPropertyListSerialization dataFromPropertyList:self.diskCacheInfo format:NSPropertyListBinaryFormat_v1_0 errorDescription:NULL];
+ if (data) {
+ [data writeToFile:[_diskCachePath stringByAppendingPathComponent:kAFURLCacheInfoFileName] atomically:YES];
+ }
+
+ _diskCacheInfoDirty = NO;
+ });
+}
+
+- (void)removeCachedResponseForCachedKeys:(NSArray *)cacheKeys {
+ dispatch_async_afreentrant(get_disk_cache_queue(), ^{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ NSEnumerator *enumerator = [cacheKeys objectEnumerator];
+ NSString *cacheKey;
+
+ NSMutableDictionary *accesses = [self.diskCacheInfo objectForKey:kAFURLCacheInfoAccessesKey];
+ NSMutableDictionary *sizes = [self.diskCacheInfo objectForKey:kAFURLCacheInfoSizesKey];
+ NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];
+
+ while ((cacheKey = [enumerator nextObject])) {
+ NSUInteger cacheItemSize = [[sizes objectForKey:cacheKey] unsignedIntegerValue];
+ [accesses removeObjectForKey:cacheKey];
+ [sizes removeObjectForKey:cacheKey];
+ [fileManager removeItemAtPath:[_diskCachePath stringByAppendingPathComponent:cacheKey] error:NULL];
+
+ _diskCacheUsage -= cacheItemSize;
+ [self.diskCacheInfo setObject:[NSNumber numberWithUnsignedInteger:_diskCacheUsage] forKey:kAFURLCacheInfoDiskUsageKey];
+ }
+
+ [pool drain];
+ });
+}
+
+- (void)balanceDiskUsage {
+ if (_diskCacheUsage < self.diskCapacity) {
+ return; // Already done
+ }
+
+ dispatch_async_afreentrant(get_disk_cache_queue(), ^{
+ NSMutableArray *keysToRemove = [NSMutableArray array];
+
+ // Apply LRU cache eviction algorithm while disk usage outreach capacity
+ NSDictionary *sizes = [self.diskCacheInfo objectForKey:kAFURLCacheInfoSizesKey];
+
+ NSInteger capacityToSave = _diskCacheUsage - self.diskCapacity;
+ NSArray *sortedKeys = [[self.diskCacheInfo objectForKey:kAFURLCacheInfoAccessesKey] keysSortedByValueUsingSelector:@selector(compare:)];
+ NSEnumerator *enumerator = [sortedKeys objectEnumerator];
+ NSString *cacheKey;
+
+ while (capacityToSave > 0 && (cacheKey = [enumerator nextObject])) {
+ [keysToRemove addObject:cacheKey];
+ capacityToSave -= [(NSNumber *)[sizes objectForKey:cacheKey] unsignedIntegerValue];
+ }
+
+ [self removeCachedResponseForCachedKeys:keysToRemove];
+ [self saveCacheInfo];
+ });
+}
+
+
+- (void)storeRequestToDisk:(NSURLRequest *)request response:(NSCachedURLResponse *)cachedResponse {
+ NSString *cacheKey = [AFURLCache cacheKeyForURL:request.URL];
+ NSString *cacheFilePath = [_diskCachePath stringByAppendingPathComponent:cacheKey];
+
+ [self createDiskCachePath];
+
+ // Archive the cached response on disk
+ if (![NSKeyedArchiver archiveRootObject:cachedResponse toFile:cacheFilePath]) {
+ // Caching failed for some reason
+ return;
+ }
+
+ // Update disk usage info
+ NSFileManager *fileManager = [[NSFileManager alloc] init];
+ NSNumber *cacheItemSize = [[fileManager attributesOfItemAtPath:cacheFilePath error:NULL] objectForKey:NSFileSize];
+ [fileManager release];
+
+ dispatch_async_afreentrant(get_disk_cache_queue(), ^{
+ _diskCacheUsage += [cacheItemSize unsignedIntegerValue];
+ [self.diskCacheInfo setObject:[NSNumber numberWithUnsignedInteger:_diskCacheUsage] forKey:kAFURLCacheInfoDiskUsageKey];
+
+ // Update cache info for the stored item
+ [(NSMutableDictionary *)[self.diskCacheInfo objectForKey:kAFURLCacheInfoAccessesKey] setObject:[NSDate date] forKey:cacheKey];
+ [(NSMutableDictionary *)[self.diskCacheInfo objectForKey:kAFURLCacheInfoSizesKey] setObject:cacheItemSize forKey:cacheKey];
+
+ [self saveCacheInfo];
+
+ // start timer for cleanup (rely on fact that dispatch_suspend syncs with disk cache queue)
+ if (_timerPaused) {
+ _timerPaused = NO;
+ dispatch_resume([self maintenanceTimer]);
+ }
+ });
+}
+
+// called in NSTimer
+- (void)periodicMaintenance {
+ if (_diskCacheUsage > self.diskCapacity) {
+ dispatch_async(get_disk_io_queue(), ^{
+ [self balanceDiskUsage];
+ });
+ }
+ else if (_diskCacheInfoDirty) {
+ dispatch_async(get_disk_io_queue(), ^{
+ [self saveCacheInfo];
+ });
+ }
+}
+
+#pragma mark AFURLCache
+
++ (NSString *)defaultCachePath {
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
+ return [[paths objectAtIndex:0] stringByAppendingPathComponent:kAFURLCachePath];
+}
+
+#pragma mark NSURLCache
+
+- (id)initWithMemoryCapacity:(NSUInteger)memoryCapacity diskCapacity:(NSUInteger)diskCapacity diskPath:(NSString *)path {
+ if ((self = [super initWithMemoryCapacity:memoryCapacity diskCapacity:diskCapacity diskPath:path])) {
+ self.minCacheInterval = kAFURLCacheInfoDefaultMinCacheInterval;
+ self.diskCachePath = path;
+ self.ignoreMemoryOnlyStoragePolicy = NO;
+ }
+
+ return self;
+}
+
+- (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request {
+ request = [AFURLCache canonicalRequestForRequest:request];
+
+ if (request.cachePolicy == NSURLRequestReloadIgnoringLocalCacheData
+ || request.cachePolicy == NSURLRequestReloadIgnoringLocalAndRemoteCacheData
+ || request.cachePolicy == NSURLRequestReloadIgnoringCacheData) {
+ // When cache is ignored for read, it's a good idea not to store the result as well as this option
+ // have big chance to be used every times in the future for the same request.
+ // NOTE: This is a change regarding default URLCache behavior
+ return;
+ }
+
+ [super storeCachedResponse:cachedResponse forRequest:request];
+
+ NSURLCacheStoragePolicy storagePolicy = cachedResponse.storagePolicy;
+ if ((storagePolicy == NSURLCacheStorageAllowed || (storagePolicy == NSURLCacheStorageAllowedInMemoryOnly && _ignoreMemoryOnlyStoragePolicy))
+ && [cachedResponse.response isKindOfClass:[NSHTTPURLResponse self]]
+ && cachedResponse.data.length < self.diskCapacity) {
+ NSDictionary *headers = [(NSHTTPURLResponse *)cachedResponse.response allHeaderFields];
+ // RFC 2616 section 13.3.4 says clients MUST use Etag in any cache-conditional request if provided by server
+ if (![headers objectForKey:@"Etag"]) {
+ NSDate *expirationDate = [AFURLCache expirationDateFromHeaders:headers
+ withStatusCode:((NSHTTPURLResponse *)cachedResponse.response).statusCode];
+ if (!expirationDate || [expirationDate timeIntervalSinceNow] - _minCacheInterval <= 0) {
+ // This response is not cacheable, headers said
+ return;
+ }
+ }
+
+ dispatch_async(get_disk_io_queue(), ^{
+ [self storeRequestToDisk:request response:cachedResponse];
+ });
+ }
+}
+
+- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request {
+ request = [AFURLCache canonicalRequestForRequest:request];
+
+ NSCachedURLResponse *memoryResponse = [super cachedResponseForRequest:request];
+ if (memoryResponse) {
+ return memoryResponse;
+ }
+
+ NSString *cacheKey = [AFURLCache cacheKeyForURL:request.URL];
+
+ // NOTE: We don't handle expiration here as even staled cache data is necessary for NSURLConnection to handle cache revalidation.
+ // Staled cache data is also needed for cachePolicies which force the use of the cache.
+ __block NSCachedURLResponse *response = nil;
+ dispatch_sync(get_disk_cache_queue(), ^{
+ NSMutableDictionary *accesses = [self.diskCacheInfo objectForKey:kAFURLCacheInfoAccessesKey];
+ if ([accesses objectForKey:cacheKey]) { // OPTI: Check for cache-hit in a in-memory dictionnary before to hit the FS
+ response = [NSKeyedUnarchiver unarchiveObjectWithFile:[_diskCachePath stringByAppendingPathComponent:cacheKey]];
+ if (response) {
+ // OPTI: Log the entry last access time for LRU cache eviction algorithm but don't save the dictionary
+ // on disk now in order to save IO and time
+ [accesses setObject:[NSDate date] forKey:cacheKey];
+ _diskCacheInfoDirty = YES;
+ }
+ }
+ });
+
+ // OPTI: Store the response to memory cache for potential future requests
+ if (response) {
+ [super storeCachedResponse:response forRequest:request];
+ }
+
+ return response;
+}
+
+- (NSUInteger)currentDiskUsage {
+ if (!_diskCacheInfo) {
+ [self diskCacheInfo];
+ }
+ return _diskCacheUsage;
+}
+
+- (void)removeCachedResponseForRequest:(NSURLRequest *)request {
+ request = [AFURLCache canonicalRequestForRequest:request];
+
+ [super removeCachedResponseForRequest:request];
+ [self removeCachedResponseForCachedKeys:[NSArray arrayWithObject:[AFURLCache cacheKeyForURL:request.URL]]];
+ [self saveCacheInfo];
+}
+
+- (void)removeAllCachedResponses {
+ [super removeAllCachedResponses];
+ NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];
+ [fileManager removeItemAtPath:_diskCachePath error:NULL];
+ dispatch_async_afreentrant(get_disk_cache_queue(), ^{
+ self.diskCacheInfo = nil;
+ });
+}
+
+- (BOOL)isCached:(NSURL *)url {
+ NSURLRequest *request = [NSURLRequest requestWithURL:url];
+ request = [AFURLCache canonicalRequestForRequest:request];
+
+ if ([super cachedResponseForRequest:request]) {
+ return YES;
+ }
+ NSString *cacheKey = [AFURLCache cacheKeyForURL:url];
+ NSString *cacheFile = [_diskCachePath stringByAppendingPathComponent:cacheKey];
+
+ BOOL isCached = [[[[NSFileManager alloc] init] autorelease] fileExistsAtPath:cacheFile];
+ return isCached;
+}
+
+#pragma mark NSObject
+
+- (void)dealloc {
+ dispatch_source_cancel(_maintenanceTimer);
+ dispatch_release(_maintenanceTimer);
+ [_diskCachePath release], _diskCachePath = nil;
+ [_diskCacheInfo release], _diskCacheInfo = nil;
+ [super dealloc];
+}
+
+@synthesize minCacheInterval = _minCacheInterval;
+@synthesize ignoreMemoryOnlyStoragePolicy = _ignoreMemoryOnlyStoragePolicy;
+@synthesize diskCachePath = _diskCachePath;
+@synthesize diskCacheInfo = _diskCacheInfo;
+
+@end
View
35 IOSBoilerplate/ASIAuthenticationDialog.h
@@ -1,35 +0,0 @@
-//
-// ASIAuthenticationDialog.h
-// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest
-//
-// Created by Ben Copsey on 21/08/2009.
-// Copyright 2009 All-Seeing Interactive. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-#import <UIKit/UIKit.h>
-@class ASIHTTPRequest;
-
-typedef enum _ASIAuthenticationType {
- ASIStandardAuthenticationType = 0,
- ASIProxyAuthenticationType = 1
-} ASIAuthenticationType;
-
-@interface ASIAutorotatingViewController : UIViewController
-@end
-
-@interface ASIAuthenticationDialog : ASIAutorotatingViewController <UIActionSheetDelegate, UITableViewDelegate, UITableViewDataSource> {
- ASIHTTPRequest *request;
- ASIAuthenticationType type;
- UITableView *tableView;
- UIViewController *presentingController;
- BOOL didEnableRotationNotifications;
-}
-+ (void)presentAuthenticationDialogForRequest:(ASIHTTPRequest *)request;
-+ (void)dismiss;
-
-@property (retain) ASIHTTPRequest *request;
-@property (assign) ASIAuthenticationType type;
-@property (assign) BOOL didEnableRotationNotifications;
-@property (retain, nonatomic) UIViewController *presentingController;
-@end
View
487 IOSBoilerplate/ASIAuthenticationDialog.m
@@ -1,487 +0,0 @@
-//
-// ASIAuthenticationDialog.m
-// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest
-//
-// Created by Ben Copsey on 21/08/2009.
-// Copyright 2009 All-Seeing Interactive. All rights reserved.
-//
-
-#import "ASIAuthenticationDialog.h"
-#import "ASIHTTPRequest.h"
-#import <QuartzCore/QuartzCore.h>
-
-static ASIAuthenticationDialog *sharedDialog = nil;
-BOOL isDismissing = NO;
-static NSMutableArray *requestsNeedingAuthentication = nil;
-
-static const NSUInteger kUsernameRow = 0;
-static const NSUInteger kUsernameSection = 0;
-static const NSUInteger kPasswordRow = 1;
-static const NSUInteger kPasswordSection = 0;
-static const NSUInteger kDomainRow = 0;
-static const NSUInteger kDomainSection = 1;
-
-
-@implementation ASIAutorotatingViewController
-
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
-{
- return YES;
-}
-
-@end
-
-
-@interface ASIAuthenticationDialog ()
-- (void)showTitle;
-- (void)show;
-- (NSArray *)requestsRequiringTheseCredentials;
-- (void)presentNextDialog;
-- (void)keyboardWillShow:(NSNotification *)notification;
-- (void)orientationChanged:(NSNotification *)notification;
-- (void)cancelAuthenticationFromDialog:(id)sender;
-- (void)loginWithCredentialsFromDialog:(id)sender;
-@property (retain) UITableView *tableView;
-@end
-
-@implementation ASIAuthenticationDialog
-
-#pragma mark init / dealloc
-
-+ (void)initialize
-{
- if (self == [ASIAuthenticationDialog class]) {
- requestsNeedingAuthentication = [[NSMutableArray array] retain];
- }
-}
-
-+ (void)presentAuthenticationDialogForRequest:(ASIHTTPRequest *)theRequest
-{
- // No need for a lock here, this will always be called on the main thread
- if (!sharedDialog) {
- sharedDialog = [[self alloc] init];
- [sharedDialog setRequest:theRequest];
- if ([theRequest authenticationNeeded] == ASIProxyAuthenticationNeeded) {
- [sharedDialog setType:ASIProxyAuthenticationType];
- } else {
- [sharedDialog setType:ASIStandardAuthenticationType];
- }
- [sharedDialog show];
- } else {
- [requestsNeedingAuthentication addObject:theRequest];
- }
-}
-
-- (id)init
-{
- if ((self = [self initWithNibName:nil bundle:nil])) {
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
-
-#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_3_2
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
-#endif
- if (![UIDevice currentDevice].generatesDeviceOrientationNotifications) {
- [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
- [self setDidEnableRotationNotifications:YES];
- }
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
-#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_3_2
- }
-#endif
- }
- return self;
-}
-
-- (void)dealloc
-{
- if ([self didEnableRotationNotifications]) {
- [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
- }
- [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
-
- [request release];
- [tableView release];
- [presentingController.view removeFromSuperview];
- [presentingController release];
- [super dealloc];
-}
-
-#pragma mark keyboard notifications
-
-- (void)keyboardWillShow:(NSNotification *)notification
-{
-#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_3_2
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
-#endif
-#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_2
- NSValue *keyboardBoundsValue = [[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey];
-#else
- NSValue *keyboardBoundsValue = [[notification userInfo] objectForKey:UIKeyboardBoundsUserInfoKey];
-#endif
- CGRect keyboardBounds;
- [keyboardBoundsValue getValue:&keyboardBounds];
- UIEdgeInsets e = UIEdgeInsetsMake(0, 0, keyboardBounds.size.height, 0);
- [[self tableView] setScrollIndicatorInsets:e];
- [[self tableView] setContentInset:e];
-#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_3_2
- }
-#endif
-}
-
-// Manually handles orientation changes on iPhone
-- (void)orientationChanged:(NSNotification *)notification
-{
- [self showTitle];
-
- UIInterfaceOrientation o = (UIInterfaceOrientation)[[UIApplication sharedApplication] statusBarOrientation];
- CGFloat angle = 0;
- switch (o) {
- case UIDeviceOrientationLandscapeLeft: angle = 90; break;
- case UIDeviceOrientationLandscapeRight: angle = -90; break;
- case UIDeviceOrientationPortraitUpsideDown: angle = 180; break;
- default: break;
- }
-
- CGRect f = [[UIScreen mainScreen] applicationFrame];
-
- // Swap the frame height and width if necessary
- if (UIDeviceOrientationIsLandscape(o)) {
- CGFloat t;
- t = f.size.width;
- f.size.width = f.size.height;
- f.size.height = t;
- }
-
- CGAffineTransform previousTransform = self.view.layer.affineTransform;
- CGAffineTransform newTransform = CGAffineTransformMakeRotation((CGFloat)(angle * M_PI / 180.0));
-
- // Reset the transform so we can set the size
- self.view.layer.affineTransform = CGAffineTransformIdentity;
- self.view.frame = (CGRect){ { 0, 0 }, f.size};
-
- // Revert to the previous transform for correct animation
- self.view.layer.affineTransform = previousTransform;
-
- [UIView beginAnimations:nil context:NULL];
- [UIView setAnimationDuration:0.3];
-
- // Set the new transform
- self.view.layer.affineTransform = newTransform;
-
- // Fix the view origin
- self.view.frame = (CGRect){ { f.origin.x, f.origin.y },self.view.frame.size};
- [UIView commitAnimations];
-}
-
-#pragma mark utilities
-
-- (UIViewController *)presentingController
-{
- if (!presentingController) {
- presentingController = [[ASIAutorotatingViewController alloc] initWithNibName:nil bundle:nil];
-
- // Attach to the window, but don't interfere.
- UIWindow *window = [[[UIApplication sharedApplication] windows] objectAtIndex:0];
- [window addSubview:[presentingController view]];
- [[presentingController view] setFrame:CGRectZero];
- [[presentingController view] setUserInteractionEnabled:NO];
- }
-
- return presentingController;
-}
-
-- (UITextField *)textFieldInRow:(NSUInteger)row section:(NSUInteger)section
-{
- return [[[[[self tableView] cellForRowAtIndexPath:
- [NSIndexPath indexPathForRow:row inSection:section]]
- contentView] subviews] objectAtIndex:0];
-}
-
-- (UITextField *)usernameField
-{
- return [self textFieldInRow:kUsernameRow section:kUsernameSection];
-}
-
-- (UITextField *)passwordField
-{
- return [self textFieldInRow:kPasswordRow section:kPasswordSection];
-}
-
-- (UITextField *)domainField
-{
- return [self textFieldInRow:kDomainRow section:kDomainSection];
-}
-
-#pragma mark show / dismiss
-
-+ (void)dismiss
-{
- [[sharedDialog parentViewController] dismissModalViewControllerAnimated:YES];
-}
-
-- (void)viewDidDisappear:(BOOL)animated
-{
- [self retain];
- [sharedDialog release];
- sharedDialog = nil;
- [self performSelector:@selector(presentNextDialog) withObject:nil afterDelay:0];
- [self release];
-}
-
-- (void)dismiss
-{
- if (self == sharedDialog) {
- [[self class] dismiss];
- } else {
- [[self parentViewController] dismissModalViewControllerAnimated:YES];
- }
-}
-
-- (void)showTitle
-{
- UINavigationBar *navigationBar = [[[self view] subviews] objectAtIndex:0];
- UINavigationItem *navItem = [[navigationBar items] objectAtIndex:0];
- if (UIInterfaceOrientationIsPortrait([[UIDevice currentDevice] orientation])) {
- // Setup the title
- if ([self type] == ASIProxyAuthenticationType) {
- [navItem setPrompt:@"Login to this secure proxy server."];
- } else {
- [navItem setPrompt:@"Login to this secure server."];
- }
- } else {
- [navItem setPrompt:nil];
- }
- [navigationBar sizeToFit];
- CGRect f = [[self view] bounds];
- f.origin.y = [navigationBar frame].size.height;
- f.size.height -= f.origin.y;
- [[self tableView] setFrame:f];
-}
-
-- (void)show
-{
- // Remove all subviews
- UIView *v;
- while ((v = [[[self view] subviews] lastObject])) {
- [v removeFromSuperview];
- }
-
- // Setup toolbar
- UINavigationBar *bar = [[[UINavigationBar alloc] init] autorelease];
- [bar setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
-
- UINavigationItem *navItem = [[[UINavigationItem alloc] init] autorelease];
- bar.items = [NSArray arrayWithObject:navItem];
-
- [[self view] addSubview:bar];
-
- [self showTitle];
-
- // Setup toolbar buttons
- if ([self type] == ASIProxyAuthenticationType) {
- [navItem setTitle:[[self request] proxyHost]];
- } else {
- [navItem setTitle:[[[self request] url] host]];
- }
-
- [navItem setLeftBarButtonItem:[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelAuthenticationFromDialog:)] autorelease]];
- [navItem setRightBarButtonItem:[[[UIBarButtonItem alloc] initWithTitle:@"Login" style:UIBarButtonItemStyleDone target:self action:@selector(loginWithCredentialsFromDialog:)] autorelease]];
-
- // We show the login form in a table view, similar to Safari's authentication dialog
- [bar sizeToFit];
- CGRect f = [[self view] bounds];
- f.origin.y = [bar frame].size.height;
- f.size.height -= f.origin.y;
-
- [self setTableView:[[[UITableView alloc] initWithFrame:f style:UITableViewStyleGrouped] autorelease]];
- [[self tableView] setDelegate:self];
- [[self tableView] setDataSource:self];
- [[self tableView] setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
- [[self view] addSubview:[self tableView]];
-
- // Force reload the table content, and focus the first field to show the keyboard
- [[self tableView] reloadData];
- [[[[[self tableView] cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]].contentView subviews] objectAtIndex:0] becomeFirstResponder];
-
-#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_3_2
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- [self setModalPresentationStyle:UIModalPresentationFormSheet];
- }
-#endif
-
- [[self presentingController] presentModalViewController:self animated:YES];
-}
-
-#pragma mark button callbacks
-
-- (void)cancelAuthenticationFromDialog:(id)sender
-{
- for (ASIHTTPRequest *theRequest in [self requestsRequiringTheseCredentials]) {
- [theRequest cancelAuthentication];
- [requestsNeedingAuthentication removeObject:theRequest];
- }
- [self dismiss];
-}
-
-- (NSArray *)requestsRequiringTheseCredentials
-{
- NSMutableArray *requestsRequiringTheseCredentials = [NSMutableArray array];
- NSURL *requestURL = [[self request] url];
- for (ASIHTTPRequest *otherRequest in requestsNeedingAuthentication) {
- NSURL *theURL = [otherRequest url];
- if (([otherRequest authenticationNeeded] == [[self request] authenticationNeeded]) && [[theURL host] isEqualToString:[requestURL host]] && ([theURL port] == [requestURL port] || ([requestURL port] && [[theURL port] isEqualToNumber:[requestURL port]])) && [[theURL scheme] isEqualToString:[requestURL scheme]] && ((![otherRequest authenticationRealm] && ![[self request] authenticationRealm]) || ([otherRequest authenticationRealm] && [[self request] authenticationRealm] && [[[self request] authenticationRealm] isEqualToString:[otherRequest authenticationRealm]]))) {
- [requestsRequiringTheseCredentials addObject:otherRequest];
- }
- }
- [requestsRequiringTheseCredentials addObject:[self request]];
- return requestsRequiringTheseCredentials;
-}
-
-- (void)presentNextDialog
-{
- if ([requestsNeedingAuthentication count]) {
- ASIHTTPRequest *nextRequest = [requestsNeedingAuthentication objectAtIndex:0];
- [requestsNeedingAuthentication removeObjectAtIndex:0];
- [[self class] presentAuthenticationDialogForRequest:nextRequest];
- }
-}
-
-
-- (void)loginWithCredentialsFromDialog:(id)sender
-{
- for (ASIHTTPRequest *theRequest in [self requestsRequiringTheseCredentials]) {
-
- NSString *username = [[self usernameField] text];
- NSString *password = [[self passwordField] text];
-
- if (username == nil) { username = @""; }
- if (password == nil) { password = @""; }
-
- if ([self type] == ASIProxyAuthenticationType) {
- [theRequest setProxyUsername:username];
- [theRequest setProxyPassword:password];
- } else {
- [theRequest setUsername:username];
- [theRequest setPassword:password];
- }
-
- // Handle NTLM domains
- NSString *scheme = ([self type] == ASIStandardAuthenticationType) ? [[self request] authenticationScheme] : [[self request] proxyAuthenticationScheme];
- if ([scheme isEqualToString:(NSString *)kCFHTTPAuthenticationSchemeNTLM]) {
- NSString *domain = [[self domainField] text];
- if ([self type] == ASIProxyAuthenticationType) {
- [theRequest setProxyDomain:domain];
- } else {
- [theRequest setDomain:domain];
- }
- }
-
- [theRequest retryUsingSuppliedCredentials];
- [requestsNeedingAuthentication removeObject:theRequest];
- }
- [self dismiss];
-}
-
-#pragma mark table view data source
-
-- (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView
-{
- NSString *scheme = ([self type] == ASIStandardAuthenticationType) ? [[self request] authenticationScheme] : [[self request] proxyAuthenticationScheme];
- if ([scheme isEqualToString:(NSString *)kCFHTTPAuthenticationSchemeNTLM]) {
- return 2;
- }
- return 1;
-}
-
-- (CGFloat)tableView:(UITableView *)aTableView heightForFooterInSection:(NSInteger)section
-{
- if (section == [self numberOfSectionsInTableView:aTableView]-1) {
- return 30;
- }
- return 0;
-}
-
-- (CGFloat)tableView:(UITableView *)aTableView heightForHeaderInSection:(NSInteger)section
-{
- if (section == 0) {
-#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_3_2
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- return 54;
- }
-#endif
- return 30;
- }
- return 0;
-}
-
-- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
-{
- if (section == 0) {
- return [[self request] authenticationRealm];
- }
- return nil;
-}
-
-- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-{
-#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_0
- UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
-#else
- UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CGRectMake(0,0,0,0) reuseIdentifier:nil] autorelease];
-#endif
-
- [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
-
- CGRect f = CGRectInset([cell bounds], 10, 10);
- UITextField *textField = [[[UITextField alloc] initWithFrame:f] autorelease];
- [textField setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
- [textField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
- [textField setAutocorrectionType:UITextAutocorrectionTypeNo];
-
- NSUInteger s = [indexPath section];
- NSUInteger r = [indexPath row];
-
- if (s == kUsernameSection && r == kUsernameRow) {
- [textField setPlaceholder:@"User"];
- } else if (s == kPasswordSection && r == kPasswordRow) {
- [textField setPlaceholder:@"Password"];
- [textField setSecureTextEntry:YES];
- } else if (s == kDomainSection && r == kDomainRow) {
- [textField setPlaceholder:@"Domain"];
- }
- [cell.contentView addSubview:textField];
-
- return cell;
-}
-
-- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section
-{
- if (section == 0) {
- return 2;
- } else {
- return 1;
- }
-}
-
-- (NSString *)tableView:(UITableView *)aTableView titleForFooterInSection:(NSInteger)section
-{
- if (section == [self numberOfSectionsInTableView:aTableView]-1) {
- // If we're using Basic authentication and the connection is not using SSL, we'll show the plain text message
- if ([[[self request] authenticationScheme] isEqualToString:(NSString *)kCFHTTPAuthenticationSchemeBasic] && ![[[[self request] url] scheme] isEqualToString:@"https"]) {
- return @"Password will be sent in the clear.";
- // We are using Digest, NTLM, or any scheme over SSL
- } else {
- return @"Password will be sent securely.";
- }
- }
- return nil;
-}
-
-#pragma mark -
-
-@synthesize request;
-@synthesize type;
-@synthesize tableView;
-@synthesize didEnableRotationNotifications;
-@synthesize presentingController;
-@end
View
103 IOSBoilerplate/ASICacheDelegate.h
@@ -1,103 +0,0 @@
-//
-// ASICacheDelegate.h
-// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest
-//
-// Created by Ben Copsey on 01/05/2010.
-// Copyright 2010 All-Seeing Interactive. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-@class ASIHTTPRequest;
-
-// Cache policies control the behaviour of a cache and how requests use the cache
-// When setting a cache policy, you can use a combination of these values as a bitmask
-// For example: [request setCachePolicy:ASIAskServerIfModifiedCachePolicy|ASIFallbackToCacheIfLoadFailsCachePolicy|ASIDoNotWriteToCacheCachePolicy];
-// Note that some of the behaviours below are mutally exclusive - you cannot combine ASIAskServerIfModifiedWhenStaleCachePolicy and ASIAskServerIfModifiedCachePolicy, for example.
-typedef enum _ASICachePolicy {
-
- // The default cache policy. When you set a request to use this, it will use the cache's defaultCachePolicy
- // ASIDownloadCache's default cache policy is 'ASIAskServerIfModifiedWhenStaleCachePolicy'
- ASIUseDefaultCachePolicy = 0,
-
- // Tell the request not to read from the cache
- ASIDoNotReadFromCacheCachePolicy = 1,
-
- // The the request not to write to the cache
- ASIDoNotWriteToCacheCachePolicy = 2,
-
- // Ask the server if there is an updated version of this resource (using a conditional GET) ONLY when the cached data is stale
- ASIAskServerIfModifiedWhenStaleCachePolicy = 4,
-
- // Always ask the server if there is an updated version of this resource (using a conditional GET)
- ASIAskServerIfModifiedCachePolicy = 8,
-
- // If cached data exists, use it even if it is stale. This means requests will not talk to the server unless the resource they are requesting is not in the cache
- ASIOnlyLoadIfNotCachedCachePolicy = 16,
-
- // If cached data exists, use it even if it is stale. If cached data does not exist, stop (will not set an error on the request)
- ASIDontLoadCachePolicy = 32,
-
- // Specifies that cached data may be used if the request fails. If cached data is used, the request will succeed without error. Usually used in combination with other options above.
- ASIFallbackToCacheIfLoadFailsCachePolicy = 64
-} ASICachePolicy;
-
-// Cache storage policies control whether cached data persists between application launches (ASICachePermanentlyCacheStoragePolicy) or not (ASICacheForSessionDurationCacheStoragePolicy)
-// Calling [ASIHTTPRequest clearSession] will remove any data stored using ASICacheForSessionDurationCacheStoragePolicy
-typedef enum _ASICacheStoragePolicy {
- ASICacheForSessionDurationCacheStoragePolicy = 0,
- ASICachePermanentlyCacheStoragePolicy = 1
-} ASICacheStoragePolicy;
-
-
-@protocol ASICacheDelegate <NSObject>
-
-@required
-
-// Should return the cache policy that will be used when requests have their cache policy set to ASIUseDefaultCachePolicy
-- (ASICachePolicy)defaultCachePolicy;
-
-// Returns the date a cached response should expire on. Pass a non-zero max age to specify a custom date.
-- (NSDate *)expiryDateForRequest:(ASIHTTPRequest *)request maxAge:(NSTimeInterval)maxAge;
-
-// Updates cached response headers with a new expiry date. Pass a non-zero max age to specify a custom date.
-- (void)updateExpiryForRequest:(ASIHTTPRequest *)request maxAge:(NSTimeInterval)maxAge;
-
-// Looks at the request's cache policy and any cached headers to determine if the cache data is still valid
-- (BOOL)canUseCachedDataForRequest:(ASIHTTPRequest *)request;
-
-// Removes cached data for a particular request
-- (void)removeCachedDataForRequest:(ASIHTTPRequest *)request;
-
-// Should return YES if the cache considers its cached response current for the request
-// Should return NO is the data is not cached, or (for example) if the cached headers state the request should have expired
-- (BOOL)isCachedDataCurrentForRequest:(ASIHTTPRequest *)request;
-
-// Should store the response for the passed request in the cache
-// When a non-zero maxAge is passed, it should be used as the expiry time for the cached response
-- (void)storeResponseForRequest:(ASIHTTPRequest *)request maxAge:(NSTimeInterval)maxAge;
-
-// Removes cached data for a particular url
-- (void)removeCachedDataForURL:(NSURL *)url;
-
-// Should return an NSDictionary of cached headers for the passed URL, if it is stored in the cache
-- (NSDictionary *)cachedResponseHeadersForURL:(NSURL *)url;
-
-// Should return the cached body of a response for the passed URL, if it is stored in the cache
-- (NSData *)cachedResponseDataForURL:(NSURL *)url;
-
-// Returns a path to the cached response data, if it exists
-- (NSString *)pathToCachedResponseDataForURL:(NSURL *)url;
-
-// Returns a path to the cached response headers, if they url
-- (NSString *)pathToCachedResponseHeadersForURL:(NSURL *)url;
-
-// Returns the location to use to store cached response headers for a particular request
-- (NSString *)pathToStoreCachedResponseHeadersForRequest:(ASIHTTPRequest *)request;
-
-// Returns the location to use to store a cached response body for a particular request
-- (NSString *)pathToStoreCachedResponseDataForRequest:(ASIHTTPRequest *)request;
-
-// Clear cached data stored for the passed storage policy
-- (void)clearCachedResponsesForStoragePolicy:(ASICacheStoragePolicy)cachePolicy;
-
-@end
View
42 IOSBoilerplate/ASIDataCompressor.h
@@ -1,42 +0,0 @@
-//
-// ASIDataCompressor.h
-// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest
-//
-// Created by Ben Copsey on 17/08/2010.
-// Copyright 2010 All-Seeing Interactive. All rights reserved.
-//
-
-// This is a helper class used by ASIHTTPRequest to handle deflating (compressing) data in memory and on disk
-// You may also find it helpful if you need to deflate data and files yourself - see the class methods below
-// Most of the zlib stuff is based on the sample code by Mark Adler available at http://zlib.net
-
-#import <Foundation/Foundation.h>
-#import <zlib.h>
-
-@interface ASIDataCompressor : NSObject {
- BOOL streamReady;
- z_stream zStream;
-}
-
-// Convenience constructor will call setupStream for you
-+ (id)compressor;
-
-// Compress the passed chunk of data
-// Passing YES for shouldFinish will finalize the deflated data - you must pass YES when you are on the last chunk of data
-- (NSData *)compressBytes:(Bytef *)bytes length:(NSUInteger)length error:(NSError **)err shouldFinish:(BOOL)shouldFinish;
-
-// Convenience method - pass it some data, and you'll get deflated data back
-+ (NSData *)compressData:(NSData*)uncompressedData error:(NSError **)err;
-
-// Convenience method - pass it a file containing the data to compress in sourcePath, and it will write deflated data to destinationPath
-+ (BOOL)compressDataFromFile:(NSString *)sourcePath toFile:(NSString *)destinationPath error:(NSError **)err;
-
-// Sets up zlib to handle the inflating. You only need to call this yourself if you aren't using the convenience constructor 'compressor'
-- (NSError *)setupStream;
-
-// Tells zlib to clean up. You need to call this if you need to cancel deflating part way through
-// If deflating finishes or fails, this method will be called automatically
-- (NSError *)closeStream;
-
-@property (assign, readonly) BOOL streamReady;
-@end
View
219 IOSBoilerplate/ASIDataCompressor.m
@@ -1,219 +0,0 @@
-//
-// ASIDataCompressor.m
-// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest
-//
-// Created by Ben Copsey on 17/08/2010.
-// Copyright 2010 All-Seeing Interactive. All rights reserved.
-//
-
-#import "ASIDataCompressor.h"
-#import "ASIHTTPRequest.h"
-
-#define DATA_CHUNK_SIZE 262144 // Deal with gzipped data in 256KB chunks
-#define COMPRESSION_AMOUNT Z_DEFAULT_COMPRESSION
-
-@interface ASIDataCompressor ()
-+ (NSError *)deflateErrorWithCode:(int)code;
-@end
-
-@implementation ASIDataCompressor
-
-+ (id)compressor
-{
- ASIDataCompressor *compressor = [[[self alloc] init] autorelease];
- [compressor setupStream];
- return compressor;
-}
-
-- (void)dealloc
-{
- if (streamReady) {
- [self closeStream];
- }
- [super dealloc];
-}
-
-- (NSError *)setupStream
-{
- if (streamReady) {
- return nil;
- }
- // Setup the inflate stream
- zStream.zalloc = Z_NULL;
- zStream.zfree = Z_NULL;
- zStream.opaque = Z_NULL;
- zStream.avail_in = 0;
- zStream.next_in = 0;
- int status = deflateInit2(&zStream, COMPRESSION_AMOUNT, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY);
- if (status != Z_OK) {
- return [[self class] deflateErrorWithCode:status];
- }
- streamReady = YES;
- return nil;
-}
-
-- (NSError *)closeStream
-{
- if (!streamReady) {
- return nil;
- }
- // Close the deflate stream
- streamReady = NO;
- int status = deflateEnd(&zStream);
- if (status != Z_OK) {
- return [[self class] deflateErrorWithCode:status];
- }
- return nil;
-}
-
-- (NSData *)compressBytes:(Bytef *)bytes length:(NSUInteger)length error:(NSError **)err shouldFinish:(BOOL)shouldFinish
-{
- if (length == 0) return nil;
-
- NSUInteger halfLength = length/2;
-
- // We'll take a guess that the compressed data will fit in half the size of the original (ie the max to compress at once is half DATA_CHUNK_SIZE), if not, we'll increase it below
- NSMutableData *outputData = [NSMutableData dataWithLength:length/2];
-
- int status;
-
- zStream.next_in = bytes;
- zStream.avail_in = (unsigned int)length;
- zStream.avail_out = 0;
-
- NSInteger bytesProcessedAlready = zStream.total_out;
- while (zStream.avail_out == 0) {
-
- if (zStream.total_out-bytesProcessedAlready >= [outputData length]) {
- [outputData increaseLengthBy:halfLength];
- }
-
- zStream.next_out = [outputData mutableBytes] + zStream.total_out-bytesProcessedAlready;
- zStream.avail_out = (unsigned int)([outputData length] - (zStream.total_out-bytesProcessedAlready));
- status = deflate(&zStream, shouldFinish ? Z_FINISH : Z_NO_FLUSH);
-
- if (status == Z_STREAM_END) {
- break;
- } else if (status != Z_OK) {
- if (err) {
- *err = [[self class] deflateErrorWithCode:status];
- }
- return NO;
- }
- }
-
- // Set real length
- [outputData setLength: zStream.total_out-bytesProcessedAlready];
- return outputData;
-}
-
-
-+ (NSData *)compressData:(NSData*)uncompressedData error:(NSError **)err
-{
- NSError *theError = nil;
- NSData *outputData = [[ASIDataCompressor compressor] compressBytes:(Bytef *)[uncompressedData bytes] length:[uncompressedData length] error:&theError shouldFinish:YES];
- if (theError) {
- if (err) {
- *err = theError;
- }
- return nil;
- }
- return outputData;
-}
-
-
-
-+ (BOOL)compressDataFromFile:(NSString *)sourcePath toFile:(NSString *)destinationPath error:(NSError **)err
-{
- NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];
-
- // Create an empty file at the destination path
- if (![fileManager createFileAtPath:destinationPath contents:[NSData data] attributes:nil]) {
- if (err) {
- *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Compression of %@ failed because we were to create a file at %@",sourcePath,destinationPath],NSLocalizedDescriptionKey,nil]];
- }
- return NO;
- }
-
- // Ensure the source file exists
- if (![fileManager fileExistsAtPath:sourcePath]) {
- if (err) {
- *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Compression of %@ failed the file does not exist",sourcePath],NSLocalizedDescriptionKey,nil]];
- }
- return NO;
- }
-
- UInt8 inputData[DATA_CHUNK_SIZE];
- NSData *outputData;
- NSInteger readLength;
- NSError *theError = nil;
-
- ASIDataCompressor *compressor = [ASIDataCompressor compressor];
-
- NSInputStream *inputStream = [NSInputStream inputStreamWithFileAtPath:sourcePath];
- [inputStream open];
- NSOutputStream *outputStream = [NSOutputStream outputStreamToFileAtPath:destinationPath append:NO];
- [outputStream open];
-
- while ([compressor streamReady]) {
-
- // Read some data from the file
- readLength = [inputStream read:inputData maxLength:DATA_CHUNK_SIZE];
-
- // Make sure nothing went wrong
- if ([inputStream streamStatus] == NSStreamEventErrorOccurred) {
- if (err) {
- *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Compression of %@ failed because we were unable to read from the source data file",sourcePath],NSLocalizedDescriptionKey,[inputStream streamError],NSUnderlyingErrorKey,nil]];
- }
- [compressor closeStream];
- return NO;
- }
- // Have we reached the end of the input data?
- if (!readLength) {
- break;
- }
-
- // Attempt to deflate the chunk of data
- outputData = [compressor compressBytes:inputData length:readLength error:&theError shouldFinish:readLength < DATA_CHUNK_SIZE ];
- if (theError) {
- if (err) {
- *err = theError;
- }
- [compressor closeStream];
- return NO;
- }
-
- // Write the deflated data out to the destination file
- [outputStream write:[outputData bytes] maxLength:[outputData length]];
-
- // Make sure nothing went wrong
- if ([inputStream streamStatus] == NSStreamEventErrorOccurred) {
- if (err) {
- *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Compression of %@ failed because we were unable to write to the destination data file at &@",sourcePath,destinationPath],NSLocalizedDescriptionKey,[outputStream streamError],NSUnderlyingErrorKey,nil]];
- }
- [compressor closeStream];
- return NO;
- }
-
- }
- [inputStream close];
- [outputStream close];
-
- NSError *error = [compressor closeStream];
- if (error) {
- if (err) {
- *err = error;
- }
- return NO;
- }
-
- return YES;
-}
-
-+ (NSError *)deflateErrorWithCode:(int)code
-{
- return [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Compression of data failed with code %hi",code],NSLocalizedDescriptionKey,nil]];
-}
-
-@synthesize streamReady;
-@end
View
41 IOSBoilerplate/ASIDataDecompressor.h
@@ -1,41 +0,0 @@
-//
-// ASIDataDecompressor.h
-// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest
-//
-// Created by Ben Copsey on 17/08/2010.
-// Copyright 2010 All-Seeing Interactive. All rights reserved.
-//
-
-// This is a helper class used by ASIHTTPRequest to handle inflating (decompressing) data in memory and on disk
-// You may also find it helpful if you need to inflate data and files yourself - see the class methods below
-// Most of the zlib stuff is based on the sample code by Mark Adler available at http://zlib.net
-
-#import <Foundation/Foundation.h>
-#import <zlib.h>
-
-@interface ASIDataDecompressor : NSObject {
- BOOL streamReady;
- z_stream zStream;
-}
-
-// Convenience constructor will call setupStream for you
-+ (id)decompressor;
-
-// Uncompress the passed chunk of data
-- (NSData *)uncompressBytes:(Bytef *)bytes length:(NSUInteger)length error:(NSError **)err;
-
-// Convenience method - pass it some deflated data, and you'll get inflated data back
-+ (NSData *)uncompressData:(NSData*)compressedData error:(NSError **)err;
-
-// Convenience method - pass it a file containing deflated data in sourcePath, and it will write inflated data to destinationPath
-+ (BOOL)uncompressDataFromFile:(NSString *)sourcePath toFile:(NSString *)destinationPath error:(NSError **)err;
-
-// Sets up zlib to handle the inflating. You only need to call this yourself if you aren't using the convenience constructor 'decompressor'
-- (NSError *)setupStream;
-
-// Tells zlib to clean up. You need to call this if you need to cancel inflating part way through
-// If inflating finishes or fails, this method will be called automatically
-- (NSError *)closeStream;
-
-@property (assign, readonly) BOOL streamReady;
-@end
View
218 IOSBoilerplate/ASIDataDecompressor.m
@@ -1,218 +0,0 @@
-//
-// ASIDataDecompressor.m
-// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest
-//
-// Created by Ben Copsey on 17/08/2010.
-// Copyright 2010 All-Seeing Interactive. All rights reserved.
-//
-
-#import "ASIDataDecompressor.h"
-#import "ASIHTTPRequest.h"
-
-#define DATA_CHUNK_SIZE 262144 // Deal with gzipped data in 256KB chunks
-
-@interface ASIDataDecompressor ()
-+ (NSError *)inflateErrorWithCode:(int)code;
-@end;
-
-@implementation ASIDataDecompressor
-
-+ (id)decompressor
-{
- ASIDataDecompressor *decompressor = [[[self alloc] init] autorelease];
- [decompressor setupStream];
- return decompressor;
-}
-
-- (void)dealloc
-{
- if (streamReady) {
- [self closeStream];
- }
- [super dealloc];
-}
-
-- (NSError *)setupStream
-{
- if (streamReady) {
- return nil;
- }
- // Setup the inflate stream
- zStream.zalloc = Z_NULL;
- zStream.zfree = Z_NULL;
- zStream.opaque = Z_NULL;
- zStream.avail_in = 0;
- zStream.next_in = 0;
- int status = inflateInit2(&zStream, (15+32));
- if (status != Z_OK) {
- return [[self class] inflateErrorWithCode:status];
- }
- streamReady = YES;
- return nil;
-}
-
-- (NSError *)closeStream
-{
- if (!streamReady) {
- return nil;
- }
- // Close the inflate stream
- streamReady = NO;
- int status = inflateEnd(&zStream);
- if (status != Z_OK) {
- return [[self class] inflateErrorWithCode:status];
- }
- return nil;
-}
-
-- (NSData *)uncompressBytes:(Bytef *)bytes length:(NSUInteger)length error:(NSError **)err
-{
- if (length == 0) return nil;
-
- NSUInteger halfLength = length/2;
- NSMutableData *outputData = [NSMutableData dataWithLength:length+halfLength];
-
- int status;
-
- zStream.next_in = bytes;
- zStream.avail_in = (unsigned int)length;
- zStream.avail_out = 0;
-
- NSInteger bytesProcessedAlready = zStream.total_out;
- while (zStream.avail_in != 0) {
-
- if (zStream.total_out-bytesProcessedAlready >= [outputData length]) {
- [outputData increaseLengthBy:halfLength];
- }
-
- zStream.next_out = [outputData mutableBytes] + zStream.total_out-bytesProcessedAlready;
- zStream.avail_out = (unsigned int)([outputData length] - (zStream.total_out-bytesProcessedAlready));
-
- status = inflate(&zStream, Z_NO_FLUSH);
-
- if (status == Z_STREAM_END) {
- break;
- } else if (status != Z_OK) {
- if (err) {
- *err = [[self class] inflateErrorWithCode:status];
- }
- return nil;
- }
- }
-
- // Set real length
- [outputData setLength: zStream.total_out-bytesProcessedAlready];
- return outputData;
-}
-
-
-+ (NSData *)uncompressData:(NSData*)compressedData error:(NSError **)err
-{
- NSError *theError = nil;
- NSData *outputData = [[ASIDataDecompressor decompressor] uncompressBytes:(Bytef *)[compressedData bytes] length:[compressedData length] error:&theError];
- if (theError) {
- if (err) {
- *err = theError;
- }
- return nil;
- }
- return outputData;
-}
-
-+ (BOOL)uncompressDataFromFile:(NSString *)sourcePath toFile:(NSString *)destinationPath error:(NSError **)err
-{
- NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];
-
- // Create an empty file at the destination path
- if (![fileManager createFileAtPath:destinationPath contents:[NSData data] attributes:nil]) {
- if (err) {
- *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Decompression of %@ failed because we were to create a file at %@",sourcePath,destinationPath],NSLocalizedDescriptionKey,nil]];
- }
- return NO;
- }
-
- // Ensure the source file exists
- if (![fileManager fileExistsAtPath:sourcePath]) {
- if (err) {
- *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Decompression of %@ failed the file does not exist",sourcePath],NSLocalizedDescriptionKey,nil]];
- }
- return NO;
- }
-
- UInt8 inputData[DATA_CHUNK_SIZE];
- NSData *outputData;
- NSInteger readLength;
- NSError *theError = nil;
-
-
- ASIDataDecompressor *decompressor = [ASIDataDecompressor decompressor];
-
- NSInputStream *inputStream = [NSInputStream inputStreamWithFileAtPath:sourcePath];
- [inputStream open];
- NSOutputStream *outputStream = [NSOutputStream outputStreamToFileAtPath:destinationPath append:NO];
- [outputStream open];
-
- while ([decompressor streamReady]) {
-
- // Read some data from the file
- readLength = [inputStream read:inputData maxLength:DATA_CHUNK_SIZE];
-
- // Make sure nothing went wrong
- if ([inputStream streamStatus] == NSStreamEventErrorOccurred) {
- if (err) {
- *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Decompression of %@ failed because we were unable to read from the source data file",sourcePath],NSLocalizedDescriptionKey,[inputStream streamError],NSUnderlyingErrorKey,nil]];
- }
- [decompressor closeStream];
- return NO;
- }
- // Have we reached the end of the input data?
- if (!readLength) {
- break;
- }
-
- // Attempt to inflate the chunk of data
- outputData = [decompressor uncompressBytes:inputData length:readLength error:&theError];
- if (theError) {
- if (err) {
- *err = theError;
- }
- [decompressor closeStream];
- return NO;
- }
-
- // Write the inflated data out to the destination file
- [outputStream write:[outputData bytes] maxLength:[outputData length]];
-
- // Make sure nothing went wrong
- if ([inputStream streamStatus] == NSStreamEventErrorOccurred) {
- if (err) {
- *err = [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Decompression of %@ failed because we were unable to write to the destination data file at &@",sourcePath,destinationPath],NSLocalizedDescriptionKey,[outputStream streamError],NSUnderlyingErrorKey,nil]];
- }
- [decompressor closeStream];
- return NO;
- }
-
- }
-
- [inputStream close];
- [outputStream close];
-
- NSError *error = [decompressor closeStream];
- if (error) {
- if (err) {
- *err = error;
- }
- return NO;
- }
-
- return YES;
-}
-
-
-+ (NSError *)inflateErrorWithCode:(int)code
-{
- return [NSError errorWithDomain:NetworkRequestErrorDomain code:ASICompressionError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Decompression of data failed with code %hi",code],NSLocalizedDescriptionKey,nil]];
-}
-
-@synthesize streamReady;
-@end
View
46 IOSBoilerplate/ASIDownloadCache.h
@@ -1,46 +0,0 @@
-//
-// ASIDownloadCache.h
-// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest
-//
-// Created by Ben Copsey on 01/05/2010.
-// Copyright 2010 All-Seeing Interactive. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-#import "ASICacheDelegate.h"
-
-@interface ASIDownloadCache : NSObject <ASICacheDelegate> {
-
- // The default cache policy for this cache
- // Requests that store data in the cache will use this cache policy if their cache policy is set to ASIUseDefaultCachePolicy
- // Defaults to ASIAskServerIfModifiedWhenStaleCachePolicy
- ASICachePolicy defaultCachePolicy;
-
- // The directory in which cached data will be stored
- // Defaults to a directory called 'ASIHTTPRequestCache' in the temporary directory
- NSString *storagePath;
-
- // Mediates access to the cache
- NSRecursiveLock *accessLock;
-
- // When YES, the cache will look for cache-control / pragma: no-cache headers, and won't reuse store responses if it finds them
- BOOL shouldRespectCacheControlHeaders;
-}
-
-// Returns a static instance of an ASIDownloadCache
-// In most circumstances, it will make sense to use this as a global cache, rather than creating your own cache
-// To make ASIHTTPRequests use it automatically, use [ASIHTTPRequest setDefaultCache:[ASIDownloadCache sharedCache]];
-+ (id)sharedCache;
-
-// A helper function that determines if the server has requested data should not be cached by looking at the request's response headers
-+ (BOOL)serverAllowsResponseCachingForRequest:(ASIHTTPRequest *)request;
-
-// A list of file extensions that we know won't be readable by a webview when accessed locally
-// If we're asking for a path to cache a particular url and it has one of these extensions, we change it to '.html'
-+ (NSArray *)fileExtensionsToHandleAsHTML;
-
-@property (assign, nonatomic) ASICachePolicy defaultCachePolicy;
-@property (retain, nonatomic) NSString *storagePath;
-@property (retain) NSRecursiveLock *accessLock;
-@property (assign) BOOL shouldRespectCacheControlHeaders;
-@end
View
514 IOSBoilerplate/ASIDownloadCache.m
@@ -1,514 +0,0 @@
-//
-// ASIDownloadCache.m
-// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest
-//
-// Created by Ben Copsey on 01/05/2010.
-// Copyright 2010 All-Seeing Interactive. All rights reserved.
-//
-
-#import "ASIDownloadCache.h"
-#import "ASIHTTPRequest.h"
-#import <CommonCrypto/CommonHMAC.h>
-
-static ASIDownloadCache *sharedCache = nil;
-
-static NSString *sessionCacheFolder = @"SessionStore";
-static NSString *permanentCacheFolder = @"PermanentStore";
-static NSArray *fileExtensionsToHandleAsHTML = nil;
-
-@interface ASIDownloadCache ()
-+ (NSString *)keyForURL:(NSURL *)url;
-- (NSString *)pathToFile:(NSString *)file;
-@end
-
-@implementation ASIDownloadCache
-
-+ (void)initialize
-{
- if (self == [ASIDownloadCache class]) {
- // Obviously this is not an exhaustive list, but hopefully these are the most commonly used and this will 'just work' for the widest range of people
- // I imagine many web developers probably use url rewriting anyway
- fileExtensionsToHandleAsHTML = [[NSArray alloc] initWithObjects:@"asp",@"aspx",@"jsp",@"php",@"rb",@"py",@"pl",@"cgi", nil];
- }
-}
-
-- (id)init
-{
- self = [super init];
- [self setShouldRespectCacheControlHeaders:YES];
- [self setDefaultCachePolicy:ASIUseDefaultCachePolicy];
- [self setAccessLock:[[[NSRecursiveLock alloc] init] autorelease]];
- return self;
-}
-
-+ (id)sharedCache
-{
- if (!sharedCache) {
- @synchronized(self) {
- if (!sharedCache) {
- sharedCache = [[self alloc] init];
- [sharedCache setStoragePath:[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"ASIHTTPRequestCache"]];
- }
- }
- }
- return sharedCache;
-}
-
-- (void)dealloc
-{
- [storagePath release];
- [accessLock release];
- [super dealloc];
-}
-
-- (NSString *)storagePath
-{
- [[self accessLock] lock];
- NSString *p = [[storagePath retain] autorelease];
- [[self accessLock] unlock];
- return p;
-}
-
-
-- (void)setStoragePath:(NSString *)path
-{
- [[self accessLock] lock];
- [self clearCachedResponsesForStoragePolicy:ASICacheForSessionDurationCacheStoragePolicy];
- [storagePath release];
- storagePath = [path retain];
-
- NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];
-
- BOOL isDirectory = NO;
- NSArray *directories = [NSArray arrayWithObjects:path,[path stringByAppendingPathComponent:sessionCacheFolder],[path stringByAppendingPathComponent:permanentCacheFolder],nil];
- for (NSString *directory in directories) {
- BOOL exists = [fileManager fileExistsAtPath:directory isDirectory:&isDirectory];
- if (exists && !isDirectory) {
- [[self accessLock] unlock];
- [NSException raise:@"FileExistsAtCachePath" format:@"Cannot create a directory for the cache at '%@', because a file already exists",directory];
- } else if (!exists) {
- [fileManager createDirectoryAtPath:directory withIntermediateDirectories:NO attributes:nil error:nil];
- if (![fileManager fileExistsAtPath:directory]) {
- [[self accessLock] unlock];
- [NSException raise:@"FailedToCreateCacheDirectory" format:@"Failed to create a directory for the cache at '%@'",directory];
- }
- }
- }
- [self clearCachedResponsesForStoragePolicy:ASICacheForSessionDurationCacheStoragePolicy];
- [[self accessLock] unlock];
-}
-
-- (void)updateExpiryForRequest:(ASIHTTPRequest *)request maxAge:(NSTimeInterval)maxAge
-{
- NSString *headerPath = [self pathToStoreCachedResponseHeadersForRequest:request];
- NSMutableDictionary *cachedHeaders = [NSMutableDictionary dictionaryWithContentsOfFile:headerPath];
- if (!cachedHeaders) {
- return;
- }
- NSDate *expires = [self expiryDateForRequest:request maxAge:maxAge];
- if (!expires) {
- return;
- }
- [cachedHeaders setObject:[NSNumber numberWithDouble:[expires timeIntervalSince1970]] forKey:@"X-ASIHTTPRequest-Expires"];
- [cachedHeaders writeToFile:headerPath atomically:NO];
-}
-
-- (NSDate *)expiryDateForRequest:(ASIHTTPRequest *)request maxAge:(NSTimeInterval)maxAge
-{
- return [ASIHTTPRequest expiryDateForRequest:request maxAge:maxAge];
-}
-
-- (void)storeResponseForRequest:(ASIHTTPRequest *)request maxAge:(NSTimeInterval)maxAge
-{
- [[self accessLock] lock];
-
- if ([request error] || ![request responseHeaders] || ([request cachePolicy] & ASIDoNotWriteToCacheCachePolicy)) {
- [[self accessLock] unlock];
- return;
- }
-
- // We only cache 200/OK or redirect reponses (redirect responses are cached so the cache works better with no internet connection)
- int responseCode = [request responseStatusCode];
- if (responseCode != 200 && responseCode != 301 && responseCode != 302 && responseCode != 303 && responseCode != 307) {
- [[self accessLock] unlock];
- return;
- }
-
- if ([self shouldRespectCacheControlHeaders] && ![[self class] serverAllowsResponseCachingForRequest:request]) {
- [[self accessLock] unlock];
- return;
- }
-
- NSString *headerPath = [self pathToStoreCachedResponseHeadersForRequest:request];
- NSString *dataPath = [self pathToStoreCachedResponseDataForRequest:request];
-
- NSMutableDictionary *responseHeaders = [NSMutableDictionary dictionaryWithDictionary:[request responseHeaders]];
- if ([request isResponseCompressed]) {
- [responseHeaders removeObjectForKey:@"Content-Encoding"];
- }
-
- // Create a special 'X-ASIHTTPRequest-Expires' header
- // This is what we use for deciding if cached data is current, rather than parsing the expires / max-age headers individually each time
- // We store this as a timestamp to make reading it easier as NSDateFormatter is quite expensive
-
- NSDate *expires = [self expiryDateForRequest:request maxAge:maxAge];
- if (expires) {
- [responseHeaders setObject:[NSNumber numberWithDouble:[expires timeIntervalSince1970]] forKey:@"X-ASIHTTPRequest-Expires"];
- }
-
- // Store the response code in a custom header so we can reuse it later
-
- // We'll change 304/Not Modified to 200/OK because this is likely to be us updating the cached headers with a conditional GET
- int statusCode = [request responseStatusCode];
- if (statusCode == 304) {
- statusCode = 200;
- }
- [responseHeaders setObject:[NSNumber numberWithInt:statusCode] forKey:@"X-ASIHTTPRequest-Response-Status-Code"];
-
- [responseHeaders writeToFile:headerPath atomically:NO];
-
- if ([request responseData]) {
- [[request responseData] writeToFile:dataPath atomically:NO];
- } else if ([request downloadDestinationPath] && ![[request downloadDestinationPath] isEqualToString:dataPath]) {
- NSError *error = nil;
- NSFileManager* manager = [[NSFileManager alloc] init];
- if ([manager fileExistsAtPath:dataPath]) {
- [manager removeItemAtPath:dataPath error:&error];
- }
- [manager copyItemAtPath:[request downloadDestinationPath] toPath:dataPath error:&error];
- [manager release];
- }
- [[self accessLock] unlock];
-}
-
-- (NSDictionary *)cachedResponseHeadersForURL:(NSURL *)url
-{
- NSString *path = [self pathToCachedResponseHeadersForURL:url];
- if (path) {
- return [NSDictionary dictionaryWithContentsOfFile:path];
- }
- return nil;
-}
-
-- (NSData *)cachedResponseDataForURL:(NSURL *)url
-{
- NSString *path = [self pathToCachedResponseDataForURL:url];