Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: luka1995/LPGoogleFunctions-iOS
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: qaavi/LPGoogleFunctions-iOS
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref

Commits on Mar 27, 2017

  1. Copy the full SHA
    658ce5e View commit details
  2. Copy the full SHA
    48b7f38 View commit details

Commits on Mar 30, 2017

  1. Copy the full SHA
    42dd7b9 View commit details

Commits on May 4, 2017

  1. Copy the full SHA
    607dc8a View commit details

Commits on May 11, 2017

  1. reverted to seconds

    qaavi committed May 11, 2017
    Copy the full SHA
    46e91f6 View commit details

Commits on Jul 20, 2017

  1. VIA Design changes

    qaavi committed Jul 20, 2017
    Copy the full SHA
    8cece14 View commit details

Commits on Sep 12, 2017

  1. Adeel's changes

    qaavi committed Sep 12, 2017
    Copy the full SHA
    92edbfe View commit details

Commits on Oct 5, 2017

  1. Copy the full SHA
    fc96d91 View commit details

Commits on Oct 30, 2017

  1. Traffic Model parameter added

    qaavi committed Oct 30, 2017
    Copy the full SHA
    a4d266a View commit details

Commits on Nov 8, 2017

  1. Geocoding API added

    qaavi committed Nov 8, 2017
    Copy the full SHA
    b883906 View commit details

Commits on Nov 9, 2017

  1. Copy the full SHA
    dc422a1 View commit details

Commits on Nov 23, 2017

  1. PlaceID added to LPPrediction

    qaavi committed Nov 23, 2017
    Copy the full SHA
    9d14ebc View commit details

Commits on Mar 27, 2018

  1. strictBounds added to AutoComplete API

    Abdul Qavi committed Mar 27, 2018
    Copy the full SHA
    198a035 View commit details
  2. strictbounds added to another Autocomplete method

    Abdul Qavi committed Mar 27, 2018
    Copy the full SHA
    9afeac6 View commit details

Commits on Oct 19, 2018

  1. AFNetworking 2.0 migrated to AFNetworking 3.0

    Abdul Qavi committed Oct 19, 2018
    Copy the full SHA
    edf7222 View commit details
  2. Copy the full SHA
    429f163 View commit details
  3. Warning removed and 1 error resolved due to refactoring AFNetworking …

    …3.0 code
    Abdul Qavi committed Oct 19, 2018
    Copy the full SHA
    29fb686 View commit details

Commits on Dec 21, 2018

  1. URLString: log commented

    Abdul Qavi committed Dec 21, 2018
    Copy the full SHA
    5f38828 View commit details

Commits on Jun 1, 2019

  1. traffic_model made optional in 3 apis, code refactoring - deprecated …

    …AFNetworking methods removed
    Abdul Qavi committed Jun 1, 2019
    Copy the full SHA
    888fff4 View commit details

Commits on Jun 12, 2019

  1. Update LPGoogleFunctions.h

    qaavi authored Jun 12, 2019
    Copy the full SHA
    7ba0bbe View commit details

Commits on Jun 26, 2019

  1. header=nil removed from AFNetworking calls

    Abdul Qavi committed Jun 26, 2019
    Copy the full SHA
    ef89efa View commit details
  2. Copy the full SHA
    5e90d09 View commit details
Showing with 4,287 additions and 4,108 deletions.
  1. BIN .DS_Store
  2. 0 .gitignore
  3. +43 −0 Examples/AFNetworking/AFNetworking/AFCompatibilityMacros.h
  4. +0 −67 Examples/AFNetworking/AFNetworking/AFHTTPRequestOperation.h
  5. +0 −206 Examples/AFNetworking/AFNetworking/AFHTTPRequestOperation.m
  6. +0 −308 Examples/AFNetworking/AFNetworking/AFHTTPRequestOperationManager.h
  7. +0 −253 Examples/AFNetworking/AFNetworking/AFHTTPRequestOperationManager.m
  8. +242 −50 Examples/AFNetworking/AFNetworking/AFHTTPSessionManager.h
  9. +210 −102 Examples/AFNetworking/AFNetworking/AFHTTPSessionManager.m
  10. +41 −24 Examples/AFNetworking/AFNetworking/AFNetworkReachabilityManager.h
  11. +74 −58 Examples/AFNetworking/AFNetworking/AFNetworkReachabilityManager.m
  12. +4 −7 Examples/AFNetworking/AFNetworking/AFNetworking.h
  13. +43 −32 Examples/AFNetworking/AFNetworking/AFSecurityPolicy.h
  14. +107 −83 Examples/AFNetworking/AFNetworking/AFSecurityPolicy.m
  15. +0 −328 Examples/AFNetworking/AFNetworking/AFURLConnectionOperation.h
  16. +0 −789 Examples/AFNetworking/AFNetworking/AFURLConnectionOperation.m
  17. +98 −63 Examples/AFNetworking/AFNetworking/AFURLRequestSerialization.h
  18. +237 −153 Examples/AFNetworking/AFNetworking/AFURLRequestSerialization.m
  19. +52 −31 Examples/AFNetworking/AFNetworking/AFURLResponseSerialization.h
  20. +152 −112 Examples/AFNetworking/AFNetworking/AFURLResponseSerialization.m
  21. +139 −146 Examples/AFNetworking/AFNetworking/AFURLSessionManager.h
  22. +475 −200 Examples/AFNetworking/AFNetworking/AFURLSessionManager.m
  23. +160 −0 Examples/AFNetworking/UIKit+AFNetworking/AFAutoPurgingImageCache.h
  24. +205 −0 Examples/AFNetworking/UIKit+AFNetworking/AFAutoPurgingImageCache.m
  25. +171 −0 Examples/AFNetworking/UIKit+AFNetworking/AFImageDownloader.h
  26. +417 −0 Examples/AFNetworking/UIKit+AFNetworking/AFImageDownloader.m
  27. +35 −8 Examples/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.h
  28. +145 −57 Examples/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m
  29. +5 −21 Examples/AFNetworking/UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.h
  30. +53 −36 Examples/AFNetworking/UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.m
  31. +0 −96 Examples/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.h
  32. +0 −111 Examples/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.m
  33. +52 −23 Examples/AFNetworking/UIKit+AFNetworking/UIButton+AFNetworking.h
  34. +196 −79 Examples/AFNetworking/UIKit+AFNetworking/UIButton+AFNetworking.m
  35. +35 −0 Examples/AFNetworking/UIKit+AFNetworking/UIImage+AFNetworking.h
  36. +29 −63 Examples/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.h
  37. +74 −128 Examples/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.m
  38. +9 −5 Examples/AFNetworking/UIKit+AFNetworking/UIKit+AFNetworking.h
  39. +9 −33 Examples/AFNetworking/UIKit+AFNetworking/UIProgressView+AFNetworking.h
  40. +14 −71 Examples/AFNetworking/UIKit+AFNetworking/UIProgressView+AFNetworking.m
  41. +8 −19 Examples/AFNetworking/UIKit+AFNetworking/UIRefreshControl+AFNetworking.h
  42. +54 −36 Examples/AFNetworking/UIKit+AFNetworking/UIRefreshControl+AFNetworking.m
  43. +24 −27 Examples/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.h
  44. +51 −45 Examples/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.m
  45. 0 Examples/LPDistanceMatrixService/LPDistanceMatrixService.xcodeproj/project.pbxproj
  46. 0 ...tanceMatrixService/LPDistanceMatrixService.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  47. 0 ...stanceMatrixService.xcodeproj/project.xcworkspace/xcshareddata/LPDistanceMatrixService.xccheckout
  48. BIN ...ce.xcodeproj/project.xcworkspace/xcuserdata/LukaPenger.xcuserdatad/UserInterfaceState.xcuserstate
  49. BIN ...ervice.xcodeproj/project.xcworkspace/xcuserdata/nelson.xcuserdatad/UserInterfaceState.xcuserstate
  50. 0 ...rixService.xcodeproj/xcuserdata/LukaPenger.xcuserdatad/xcschemes/LPDistanceMatrixService.xcscheme
  51. 0 ...tanceMatrixService.xcodeproj/xcuserdata/LukaPenger.xcuserdatad/xcschemes/xcschememanagement.plist
  52. 0 ...eMatrixService.xcodeproj/xcuserdata/nelson.xcuserdatad/xcschemes/LPDistanceMatrixService.xcscheme
  53. 0 ...PDistanceMatrixService.xcodeproj/xcuserdata/nelson.xcuserdatad/xcschemes/xcschememanagement.plist
  54. 0 Examples/LPDistanceMatrixService/LPDistanceMatrixService/Application/LPAppDelegate.h
  55. 0 Examples/LPDistanceMatrixService/LPDistanceMatrixService/Application/LPAppDelegate.m
  56. 0 Examples/LPDistanceMatrixService/LPDistanceMatrixService/Classes/LPMainViewController.h
  57. 0 Examples/LPDistanceMatrixService/LPDistanceMatrixService/Classes/LPMainViewController.m
  58. 0 .../LPDistanceMatrixService/LPDistanceMatrixService/Images.xcassets/AppIcon.appiconset/Contents.json
  59. 0 ...stanceMatrixService/LPDistanceMatrixService/Images.xcassets/LaunchImage.launchimage/Contents.json
  60. 0 Examples/LPDistanceMatrixService/LPDistanceMatrixService/LPDistanceMatrixService-Info.plist
  61. 0 Examples/LPDistanceMatrixService/LPDistanceMatrixService/LPDistanceMatrixService-Prefix.pch
  62. 0 Examples/LPDistanceMatrixService/LPDistanceMatrixService/Views/LPMainViewController.xib
  63. 0 Examples/LPDistanceMatrixService/LPDistanceMatrixService/en.lproj/InfoPlist.strings
  64. 0 Examples/LPDistanceMatrixService/LPDistanceMatrixService/main.m
  65. 0 Examples/LPPlacesAutocompleteService/LPPlacesAutocompleteService.xcodeproj/project.pbxproj
  66. 0 ...ompleteService/LPPlacesAutocompleteService.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  67. 0 ...completeService.xcodeproj/project.xcworkspace/xcshareddata/LPPlacesAutocompleteService.xccheckout
  68. BIN ...ce.xcodeproj/project.xcworkspace/xcuserdata/LukaPenger.xcuserdatad/UserInterfaceState.xcuserstate
  69. BIN ...Service.xcodeproj/project.xcworkspace/xcuserdata/alten.xcuserdatad/UserInterfaceState.xcuserstate
  70. 0 ...ervice.xcodeproj/xcuserdata/LukaPenger.xcuserdatad/xcschemes/LPPlacesAutocompleteService.xcscheme
  71. 0 ...utocompleteService.xcodeproj/xcuserdata/LukaPenger.xcuserdatad/xcschemes/xcschememanagement.plist
  72. 0 ...leteService.xcodeproj/xcuserdata/alten.xcuserdatad/xcschemes/LPPlacesAutocompleteService.xcscheme
  73. 0 ...acesAutocompleteService.xcodeproj/xcuserdata/alten.xcuserdatad/xcschemes/xcschememanagement.plist
  74. 0 Examples/LPPlacesAutocompleteService/LPPlacesAutocompleteService/Application/LPAppDelegate.h
  75. 0 Examples/LPPlacesAutocompleteService/LPPlacesAutocompleteService/Application/LPAppDelegate.m
  76. 0 Examples/LPPlacesAutocompleteService/LPPlacesAutocompleteService/Classes/LPCell.h
  77. 0 Examples/LPPlacesAutocompleteService/LPPlacesAutocompleteService/Classes/LPCell.m
  78. 0 Examples/LPPlacesAutocompleteService/LPPlacesAutocompleteService/Classes/LPMainViewController.h
  79. 0 Examples/LPPlacesAutocompleteService/LPPlacesAutocompleteService/Classes/LPMainViewController.m
  80. 0 ...sAutocompleteService/LPPlacesAutocompleteService/Images.xcassets/AppIcon.appiconset/Contents.json
  81. 0 ...completeService/LPPlacesAutocompleteService/Images.xcassets/LaunchImage.launchimage/Contents.json
  82. 0 ...es/LPPlacesAutocompleteService/LPPlacesAutocompleteService/LPPlacesAutocompleteService-Info.plist
  83. 0 ...es/LPPlacesAutocompleteService/LPPlacesAutocompleteService/LPPlacesAutocompleteService-Prefix.pch
  84. 0 Examples/LPPlacesAutocompleteService/LPPlacesAutocompleteService/Libraries/LPImage/LPImage.h
  85. 0 Examples/LPPlacesAutocompleteService/LPPlacesAutocompleteService/Libraries/LPImage/LPImage.m
  86. 0 Examples/LPPlacesAutocompleteService/LPPlacesAutocompleteService/Views/LPCell.xib
  87. 0 Examples/LPPlacesAutocompleteService/LPPlacesAutocompleteService/Views/LPMainViewController.xib
  88. 0 Examples/LPPlacesAutocompleteService/LPPlacesAutocompleteService/en.lproj/InfoPlist.strings
  89. 0 Examples/LPPlacesAutocompleteService/LPPlacesAutocompleteService/main.m
  90. 0 Examples/LPSpeakService/LPSpeakService.xcodeproj/project.pbxproj
  91. 0 Examples/LPSpeakService/LPSpeakService.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  92. 0 ...PSpeakService/LPSpeakService.xcodeproj/project.xcworkspace/xcshareddata/LPSpeakService.xccheckout
  93. BIN ...ce.xcodeproj/project.xcworkspace/xcuserdata/LukaPenger.xcuserdatad/UserInterfaceState.xcuserstate
  94. BIN ...Service.xcodeproj/project.xcworkspace/xcuserdata/alten.xcuserdatad/UserInterfaceState.xcuserstate
  95. BIN ...ervice.xcodeproj/project.xcworkspace/xcuserdata/nelson.xcuserdatad/UserInterfaceState.xcuserstate
  96. 0 ...vice/LPSpeakService.xcodeproj/xcuserdata/LukaPenger.xcuserdatad/xcschemes/LPSpeakService.xcscheme
  97. 0 ...ice/LPSpeakService.xcodeproj/xcuserdata/LukaPenger.xcuserdatad/xcschemes/xcschememanagement.plist
  98. 0 ...akService/LPSpeakService.xcodeproj/xcuserdata/alten.xcuserdatad/xcschemes/LPSpeakService.xcscheme
  99. 0 ...kService/LPSpeakService.xcodeproj/xcuserdata/alten.xcuserdatad/xcschemes/xcschememanagement.plist
  100. 0 ...kService/LPSpeakService.xcodeproj/xcuserdata/nelson.xcuserdatad/xcschemes/LPSpeakService.xcscheme
  101. 0 ...Service/LPSpeakService.xcodeproj/xcuserdata/nelson.xcuserdatad/xcschemes/xcschememanagement.plist
  102. 0 Examples/LPSpeakService/LPSpeakService/Application/LPAppDelegate.h
  103. 0 Examples/LPSpeakService/LPSpeakService/Application/LPAppDelegate.m
  104. 0 Examples/LPSpeakService/LPSpeakService/Classes/LPMainViewController.h
  105. 0 Examples/LPSpeakService/LPSpeakService/Classes/LPMainViewController.m
  106. 0 Examples/LPSpeakService/LPSpeakService/Images.xcassets/AppIcon.appiconset/Contents.json
  107. 0 Examples/LPSpeakService/LPSpeakService/Images.xcassets/LaunchImage.launchimage/Contents.json
  108. 0 Examples/LPSpeakService/LPSpeakService/LPSpeakService-Info.plist
  109. 0 Examples/LPSpeakService/LPSpeakService/LPSpeakService-Prefix.pch
  110. 0 Examples/LPSpeakService/LPSpeakService/Views/LPMainViewController.xib
  111. 0 Examples/LPSpeakService/LPSpeakService/en.lproj/InfoPlist.strings
  112. 0 Examples/LPSpeakService/LPSpeakService/main.m
  113. 0 Examples/LPStaticMapImagesService/LPStaticMapImagesService.xcodeproj/project.pbxproj
  114. 0 ...cMapImagesService/LPStaticMapImagesService.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  115. 0 ...icMapImagesService.xcodeproj/project.xcworkspace/xcshareddata/LPStaticMapImagesService.xccheckout
  116. BIN ...ce.xcodeproj/project.xcworkspace/xcuserdata/LukaPenger.xcuserdatad/UserInterfaceState.xcuserstate
  117. BIN ...Service.xcodeproj/project.xcworkspace/xcuserdata/alten.xcuserdatad/UserInterfaceState.xcuserstate
  118. 0 ...esService.xcodeproj/xcuserdata/LukaPenger.xcuserdatad/xcschemes/LPStaticMapImagesService.xcscheme
  119. 0 ...icMapImagesService.xcodeproj/xcuserdata/LukaPenger.xcuserdatad/xcschemes/xcschememanagement.plist
  120. 0 ...pImagesService.xcodeproj/xcuserdata/alten.xcuserdatad/xcschemes/LPStaticMapImagesService.xcscheme
  121. 0 ...PStaticMapImagesService.xcodeproj/xcuserdata/alten.xcuserdatad/xcschemes/xcschememanagement.plist
  122. 0 Examples/LPStaticMapImagesService/LPStaticMapImagesService/Application/LPAppDelegate.h
  123. 0 Examples/LPStaticMapImagesService/LPStaticMapImagesService/Application/LPAppDelegate.m
  124. 0 Examples/LPStaticMapImagesService/LPStaticMapImagesService/Classes/LPMainViewController.h
  125. 0 Examples/LPStaticMapImagesService/LPStaticMapImagesService/Classes/LPMainViewController.m
  126. 0 ...PStaticMapImagesService/LPStaticMapImagesService/Images.xcassets/AppIcon.appiconset/Contents.json
  127. 0 ...icMapImagesService/LPStaticMapImagesService/Images.xcassets/LaunchImage.launchimage/Contents.json
  128. 0 Examples/LPStaticMapImagesService/LPStaticMapImagesService/LPStaticMapImagesService-Info.plist
  129. 0 Examples/LPStaticMapImagesService/LPStaticMapImagesService/LPStaticMapImagesService-Prefix.pch
  130. 0 Examples/LPStaticMapImagesService/LPStaticMapImagesService/Views/LPMainViewController.xib
  131. 0 Examples/LPStaticMapImagesService/LPStaticMapImagesService/en.lproj/InfoPlist.strings
  132. 0 Examples/LPStaticMapImagesService/LPStaticMapImagesService/main.m
  133. 0 Examples/LPStreetViewImagesService/LPStreetViewImagesService.xcodeproj/project.pbxproj
  134. 0 ...iewImagesService/LPStreetViewImagesService.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  135. 0 ...ViewImagesService.xcodeproj/project.xcworkspace/xcshareddata/LPStreetViewImagesService.xccheckout
  136. BIN ...ce.xcodeproj/project.xcworkspace/xcuserdata/LukaPenger.xcuserdatad/UserInterfaceState.xcuserstate
  137. BIN ...Service.xcodeproj/project.xcworkspace/xcuserdata/alten.xcuserdatad/UserInterfaceState.xcuserstate
  138. BIN ...ervice.xcodeproj/project.xcworkspace/xcuserdata/nelson.xcuserdatad/UserInterfaceState.xcuserstate
  139. 0 ...sService.xcodeproj/xcuserdata/LukaPenger.xcuserdatad/xcschemes/LPStreetViewImagesService.xcscheme
  140. 0 ...tViewImagesService.xcodeproj/xcuserdata/LukaPenger.xcuserdatad/xcschemes/xcschememanagement.plist
  141. 0 ...ImagesService.xcodeproj/xcuserdata/alten.xcuserdatad/xcschemes/LPStreetViewImagesService.xcscheme
  142. 0 ...StreetViewImagesService.xcodeproj/xcuserdata/alten.xcuserdatad/xcschemes/xcschememanagement.plist
  143. 0 ...magesService.xcodeproj/xcuserdata/nelson.xcuserdatad/xcschemes/LPStreetViewImagesService.xcscheme
  144. 0 ...treetViewImagesService.xcodeproj/xcuserdata/nelson.xcuserdatad/xcschemes/xcschememanagement.plist
  145. 0 Examples/LPStreetViewImagesService/LPStreetViewImagesService/Application/LPAppDelegate.h
  146. 0 Examples/LPStreetViewImagesService/LPStreetViewImagesService/Application/LPAppDelegate.m
  147. 0 Examples/LPStreetViewImagesService/LPStreetViewImagesService/Classes/LPMainViewController.h
  148. 0 Examples/LPStreetViewImagesService/LPStreetViewImagesService/Classes/LPMainViewController.m
  149. 0 ...treetViewImagesService/LPStreetViewImagesService/Images.xcassets/AppIcon.appiconset/Contents.json
  150. 0 ...ViewImagesService/LPStreetViewImagesService/Images.xcassets/LaunchImage.launchimage/Contents.json
  151. 0 Examples/LPStreetViewImagesService/LPStreetViewImagesService/LPStreetViewImagesService-Info.plist
  152. 0 Examples/LPStreetViewImagesService/LPStreetViewImagesService/LPStreetViewImagesService-Prefix.pch
  153. 0 Examples/LPStreetViewImagesService/LPStreetViewImagesService/Views/LPMainViewController.xib
  154. 0 Examples/LPStreetViewImagesService/LPStreetViewImagesService/en.lproj/InfoPlist.strings
  155. 0 Examples/LPStreetViewImagesService/LPStreetViewImagesService/main.m
  156. 0 LICENSE
  157. +1 −1 LPGoogleFunctions.podspec
  158. BIN LPGoogleFunctions/.DS_Store
  159. 0 LPGoogleFunctions/AQGoogleSignature/LPURLSigner.h
  160. 0 LPGoogleFunctions/AQGoogleSignature/LPURLSigner.m
  161. +30 −12 LPGoogleFunctions/LPGoogleFunctions.h
  162. +558 −211 LPGoogleFunctions/LPGoogleFunctions.m
  163. 0 LPGoogleFunctions/LPGoogleObjects/LPAddressComponent.h
  164. 0 LPGoogleFunctions/LPGoogleObjects/LPAddressComponent.m
  165. 0 LPGoogleFunctions/LPGoogleObjects/LPAgencie.h
  166. 0 LPGoogleFunctions/LPGoogleObjects/LPAgencie.m
  167. 0 LPGoogleFunctions/LPGoogleObjects/LPBounds.h
  168. 0 LPGoogleFunctions/LPGoogleObjects/LPBounds.m
  169. 0 LPGoogleFunctions/LPGoogleObjects/LPDirections.h
  170. 0 LPGoogleFunctions/LPGoogleObjects/LPDirections.m
  171. 0 LPGoogleFunctions/LPGoogleObjects/LPDistance.h
  172. 0 LPGoogleFunctions/LPGoogleObjects/LPDistance.m
  173. 0 LPGoogleFunctions/LPGoogleObjects/LPDistanceMatrix.h
  174. 0 LPGoogleFunctions/LPGoogleObjects/LPDistanceMatrix.m
  175. 0 LPGoogleFunctions/LPGoogleObjects/LPDistanceMatrixElement.h
  176. 0 LPGoogleFunctions/LPGoogleObjects/LPDistanceMatrixElement.m
  177. 0 LPGoogleFunctions/LPGoogleObjects/LPDuration.h
  178. 0 LPGoogleFunctions/LPGoogleObjects/LPDuration.m
  179. 0 LPGoogleFunctions/LPGoogleObjects/LPEvent.h
  180. 0 LPGoogleFunctions/LPGoogleObjects/LPEvent.m
  181. 0 LPGoogleFunctions/LPGoogleObjects/LPGeocodingFilter.h
  182. 0 LPGoogleFunctions/LPGoogleObjects/LPGeocodingFilter.m
  183. +3 −1 LPGoogleFunctions/LPGoogleObjects/LPGeocodingResults.h
  184. +11 −6 LPGoogleFunctions/LPGoogleObjects/LPGeocodingResults.m
  185. 0 LPGoogleFunctions/LPGoogleObjects/LPGeometry.h
  186. 0 LPGoogleFunctions/LPGoogleObjects/LPGeometry.m
  187. 0 LPGoogleFunctions/LPGoogleObjects/LPLeg.h
  188. 0 LPGoogleFunctions/LPGoogleObjects/LPLeg.m
  189. 0 LPGoogleFunctions/LPGoogleObjects/LPLine.h
  190. 0 LPGoogleFunctions/LPGoogleObjects/LPLine.m
  191. 0 LPGoogleFunctions/LPGoogleObjects/LPLocation.h
  192. 0 LPGoogleFunctions/LPGoogleObjects/LPLocation.m
  193. 0 LPGoogleFunctions/LPGoogleObjects/LPMapImageMarker.h
  194. 0 LPGoogleFunctions/LPGoogleObjects/LPMapImageMarker.m
  195. 0 LPGoogleFunctions/LPGoogleObjects/LPMatchedSubstring.h
  196. 0 LPGoogleFunctions/LPGoogleObjects/LPMatchedSubstring.m
  197. 0 LPGoogleFunctions/LPGoogleObjects/LPPlaceDetails.h
  198. 0 LPGoogleFunctions/LPGoogleObjects/LPPlaceDetails.m
  199. 0 LPGoogleFunctions/LPGoogleObjects/LPPlaceDetailsResults.h
  200. 0 LPGoogleFunctions/LPGoogleObjects/LPPlaceDetailsResults.m
  201. 0 LPGoogleFunctions/LPGoogleObjects/LPPlacePhoto.h
  202. 0 LPGoogleFunctions/LPGoogleObjects/LPPlacePhoto.m
  203. 0 LPGoogleFunctions/LPGoogleObjects/LPPlaceSearchResults.h
  204. 0 LPGoogleFunctions/LPGoogleObjects/LPPlaceSearchResults.m
  205. 0 LPGoogleFunctions/LPGoogleObjects/LPPlacesAutocomplete.h
  206. 0 LPGoogleFunctions/LPGoogleObjects/LPPlacesAutocomplete.m
  207. 0 LPGoogleFunctions/LPGoogleObjects/LPPolyline.h
  208. 0 LPGoogleFunctions/LPGoogleObjects/LPPolyline.m
  209. +3 −1 LPGoogleFunctions/LPGoogleObjects/LPPrediction.h
  210. +14 −6 LPGoogleFunctions/LPGoogleObjects/LPPrediction.m
  211. +4 −0 LPGoogleFunctions/LPGoogleObjects/LPRoute.h
  212. 0 LPGoogleFunctions/LPGoogleObjects/LPRoute.m
  213. 0 LPGoogleFunctions/LPGoogleObjects/LPStep.h
  214. 0 LPGoogleFunctions/LPGoogleObjects/LPStep.m
  215. 0 LPGoogleFunctions/LPGoogleObjects/LPStop.h
  216. 0 LPGoogleFunctions/LPGoogleObjects/LPStop.m
  217. 0 LPGoogleFunctions/LPGoogleObjects/LPTerm.h
  218. 0 LPGoogleFunctions/LPGoogleObjects/LPTerm.m
  219. 0 LPGoogleFunctions/LPGoogleObjects/LPTime.h
  220. 0 LPGoogleFunctions/LPGoogleObjects/LPTime.m
  221. 0 LPGoogleFunctions/LPGoogleObjects/LPTransitDetails.h
  222. 0 LPGoogleFunctions/LPGoogleObjects/LPTransitDetails.m
  223. 0 LPGoogleFunctions/LPGoogleObjects/LPVehicle.h
  224. 0 LPGoogleFunctions/LPGoogleObjects/LPVehicle.m
  225. 0 LPGoogleFunctions/LPGoogleObjects/LPWaypoint.h
  226. 0 LPGoogleFunctions/LPGoogleObjects/LPWaypoint.m
  227. 0 LPGoogleFunctions/OrderedDictionary.h
  228. 0 LPGoogleFunctions/OrderedDictionary.m
  229. 0 README.mdown
  230. BIN ScreenShots/img1-thumb.png
  231. BIN ScreenShots/img1.png
  232. BIN ScreenShots/img2-thumb.png
  233. BIN ScreenShots/img2.png
  234. BIN ScreenShots/img3-thumb.png
  235. BIN ScreenShots/img3.png
  236. BIN ScreenShots/img4-thumb.png
  237. BIN ScreenShots/img4.png
  238. BIN ScreenShots/img5-thumb.png
  239. BIN ScreenShots/img5.png
Binary file modified .DS_Store
100644 → 100755
Binary file not shown.
Empty file modified .gitignore
100644 → 100755
Empty file.
43 changes: 43 additions & 0 deletions Examples/AFNetworking/AFNetworking/AFCompatibilityMacros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// AFCompatibilityMacros.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// 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.

#ifndef AFCompatibilityMacros_h
#define AFCompatibilityMacros_h

#ifdef API_UNAVAILABLE
#define AF_API_UNAVAILABLE(x) API_UNAVAILABLE(x)
#else
#define AF_API_UNAVAILABLE(x)
#endif // API_UNAVAILABLE

#if __has_warning("-Wunguarded-availability-new")
#define AF_CAN_USE_AT_AVAILABLE 1
#else
#define AF_CAN_USE_AT_AVAILABLE 0
#endif

#if ((__IPHONE_OS_VERSION_MAX_ALLOWED && __IPHONE_OS_VERSION_MAX_ALLOWED < 100000) || (__MAC_OS_VERSION_MAX_ALLOWED && __MAC_OS_VERSION_MAX_ALLOWED < 101200) ||(__WATCH_OS_MAX_VERSION_ALLOWED && __WATCH_OS_MAX_VERSION_ALLOWED < 30000) ||(__TV_OS_MAX_VERSION_ALLOWED && __TV_OS_MAX_VERSION_ALLOWED < 100000))
#define AF_CAN_INCLUDE_SESSION_TASK_METRICS 0
#else
#define AF_CAN_INCLUDE_SESSION_TASK_METRICS 1
#endif

#endif /* AFCompatibilityMacros_h */
67 changes: 0 additions & 67 deletions Examples/AFNetworking/AFNetworking/AFHTTPRequestOperation.h

This file was deleted.

206 changes: 0 additions & 206 deletions Examples/AFNetworking/AFNetworking/AFHTTPRequestOperation.m

This file was deleted.

308 changes: 0 additions & 308 deletions Examples/AFNetworking/AFNetworking/AFHTTPRequestOperationManager.h

This file was deleted.

253 changes: 0 additions & 253 deletions Examples/AFNetworking/AFNetworking/AFHTTPRequestOperationManager.m

This file was deleted.

292 changes: 242 additions & 50 deletions Examples/AFNetworking/AFNetworking/AFHTTPSessionManager.h

Large diffs are not rendered by default.

312 changes: 210 additions & 102 deletions Examples/AFNetworking/AFNetworking/AFHTTPSessionManager.m

Large diffs are not rendered by default.

65 changes: 41 additions & 24 deletions Examples/AFNetworking/AFNetworking/AFNetworkReachabilityManager.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
// AFNetworkReachabilityManager.h
//
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// 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
@@ -21,13 +20,9 @@
// THE SOFTWARE.

#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>

#import <netinet/in.h>
#import <netinet6/in6.h>
#import <arpa/inet.h>
#import <ifaddrs.h>
#import <netdb.h>
#if !TARGET_OS_WATCH
#import <SystemConfiguration/SystemConfiguration.h>

typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
AFNetworkReachabilityStatusUnknown = -1,
@@ -36,13 +31,15 @@ typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
AFNetworkReachabilityStatusReachableViaWiFi = 2,
};

NS_ASSUME_NONNULL_BEGIN

/**
`AFNetworkReachabilityManager` monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces.
Reachability can be used to determine background information about why a network operation failed, or to trigger a network operation retrying when a connection is established. It should not be used to prevent a user from initiating a network request, as it's possible that an initial request may be required to establish reachability.
See Apple's Reachability Sample Code (https://developer.apple.com/library/ios/samplecode/reachability/)
See Apple's Reachability Sample Code ( https://developer.apple.com/library/ios/samplecode/reachability/ )
@warning Instances of `AFNetworkReachabilityManager` must be started with `-startMonitoring` before reachability status can be determined.
*/
@interface AFNetworkReachabilityManager : NSObject
@@ -77,31 +74,48 @@ typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
+ (instancetype)sharedManager;

/**
Creates and returns a network reachability manager for the specified domain.
Creates and returns a network reachability manager with the default socket address.
@return An initialized network reachability manager, actively monitoring the default socket address.
*/
+ (instancetype)manager;

/**
Creates and returns a network reachability manager for the specified domain.
@param domain The domain used to evaluate network reachability.
@return An initialized network reachability manager, actively monitoring the specified domain.
*/
+ (instancetype)managerForDomain:(NSString *)domain;

/**
Creates and returns a network reachability manager for the socket address.
@param address The socket address used to evaluate network reachability.
@param address The socket address (`sockaddr_in6`) used to evaluate network reachability.
@return An initialized network reachability manager, actively monitoring the specified socket address.
*/
+ (instancetype)managerForAddress:(const struct sockaddr_in *)address;
+ (instancetype)managerForAddress:(const void *)address;

/**
Initializes an instance of a network reachability manager from the specified reachability object.
@param reachability The reachability object to monitor.
@return An initialized network reachability manager, actively monitoring the specified reachability.
*/
- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability;
- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability NS_DESIGNATED_INITIALIZER;

/**
* Unavailable initializer
*/
+ (instancetype)new NS_UNAVAILABLE;

/**
* Unavailable initializer
*/
- (instancetype)init NS_UNAVAILABLE;

///--------------------------------------------------
/// @name Starting & Stopping Reachability Monitoring
@@ -135,7 +149,7 @@ typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
@param block A block object to be executed when the network availability of the `baseURL` host changes.. This block has no return value and takes a single argument which represents the various reachability states from the device to the `baseURL`.
*/
- (void)setReachabilityStatusChangeBlock:(void (^)(AFNetworkReachabilityStatus status))block;
- (void)setReachabilityStatusChangeBlock:(nullable void (^)(AFNetworkReachabilityStatus status))block;

@end

@@ -186,8 +200,8 @@ typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
@warning In order for network reachability to be monitored, include the `SystemConfiguration` framework in the active target's "Link Binary With Library" build phase, and add `#import <SystemConfiguration/SystemConfiguration.h>` to the header prefix of the project (`Prefix.pch`).
*/
extern NSString * const AFNetworkingReachabilityDidChangeNotification;
extern NSString * const AFNetworkingReachabilityNotificationStatusItem;
FOUNDATION_EXPORT NSString * const AFNetworkingReachabilityDidChangeNotification;
FOUNDATION_EXPORT NSString * const AFNetworkingReachabilityNotificationStatusItem;

///--------------------
/// @name Functions
@@ -196,4 +210,7 @@ extern NSString * const AFNetworkingReachabilityNotificationStatusItem;
/**
Returns a localized string representation of an `AFNetworkReachabilityStatus` value.
*/
extern NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status);
FOUNDATION_EXPORT NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status);

NS_ASSUME_NONNULL_END
#endif
132 changes: 74 additions & 58 deletions Examples/AFNetworking/AFNetworking/AFNetworkReachabilityManager.m
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
// AFNetworkReachabilityManager.m
//
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// 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
@@ -21,17 +20,19 @@
// THE SOFTWARE.

#import "AFNetworkReachabilityManager.h"
#if !TARGET_OS_WATCH

#import <netinet/in.h>
#import <netinet6/in6.h>
#import <arpa/inet.h>
#import <ifaddrs.h>
#import <netdb.h>

NSString * const AFNetworkingReachabilityDidChangeNotification = @"com.alamofire.networking.reachability.change";
NSString * const AFNetworkingReachabilityNotificationStatusItem = @"AFNetworkingReachabilityNotificationStatusItem";

typedef void (^AFNetworkReachabilityStatusBlock)(AFNetworkReachabilityStatus status);

typedef NS_ENUM(NSUInteger, AFNetworkReachabilityAssociation) {
AFNetworkReachabilityForAddress = 1,
AFNetworkReachabilityForAddressPair = 2,
AFNetworkReachabilityForName = 3,
};
typedef AFNetworkReachabilityManager * (^AFNetworkReachabilityStatusCallback)(AFNetworkReachabilityStatus status);

NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status) {
switch (status) {
@@ -70,21 +71,32 @@ static AFNetworkReachabilityStatus AFNetworkReachabilityStatusForFlags(SCNetwork
return status;
}

static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) {
/**
* Queue a status change notification for the main thread.
*
* This is done to ensure that the notifications are received in the same order
* as they are sent. If notifications are sent directly, it is possible that
* a queued notification (for an earlier status condition) is processed after
* the later update, resulting in the listener being left in the wrong state.
*/
static void AFPostReachabilityStatusChange(SCNetworkReachabilityFlags flags, AFNetworkReachabilityStatusCallback block) {
AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags);
AFNetworkReachabilityStatusBlock block = (__bridge AFNetworkReachabilityStatusBlock)info;
if (block) {
block(status);
}


dispatch_async(dispatch_get_main_queue(), ^{
AFNetworkReachabilityManager *manager = nil;
if (block) {
manager = block(status);
}
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:@{ AFNetworkingReachabilityNotificationStatusItem: @(status) }];
NSDictionary *userInfo = @{ AFNetworkingReachabilityNotificationStatusItem: @(status) };
[notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:manager userInfo:userInfo];
});

}

static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) {
AFPostReachabilityStatusChange(flags, (__bridge AFNetworkReachabilityStatusCallback)info);
}


static const void * AFNetworkReachabilityRetainCallback(const void *info) {
return Block_copy(info);
}
@@ -96,8 +108,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
}

@interface AFNetworkReachabilityManager ()
@property (readwrite, nonatomic, assign) SCNetworkReachabilityRef networkReachability;
@property (readwrite, nonatomic, assign) AFNetworkReachabilityAssociation networkReachabilityAssociation;
@property (readonly, nonatomic, assign) SCNetworkReachabilityRef networkReachability;
@property (readwrite, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus;
@property (readwrite, nonatomic, copy) AFNetworkReachabilityStatusBlock networkReachabilityStatusBlock;
@end
@@ -108,12 +119,7 @@ + (instancetype)sharedManager {
static AFNetworkReachabilityManager *_sharedManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_len = sizeof(address);
address.sin_family = AF_INET;

_sharedManager = [self managerForAddress:&address];
_sharedManager = [self manager];
});

return _sharedManager;
@@ -123,38 +129,62 @@ + (instancetype)managerForDomain:(NSString *)domain {
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [domain UTF8String]);

AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability];
manager.networkReachabilityAssociation = AFNetworkReachabilityForName;

CFRelease(reachability);

return manager;
}

+ (instancetype)managerForAddress:(const struct sockaddr_in *)address {
+ (instancetype)managerForAddress:(const void *)address {
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)address);

AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability];
manager.networkReachabilityAssociation = AFNetworkReachabilityForAddress;

CFRelease(reachability);

return manager;
}

+ (instancetype)manager
{
#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)
struct sockaddr_in6 address;
bzero(&address, sizeof(address));
address.sin6_len = sizeof(address);
address.sin6_family = AF_INET6;
#else
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_len = sizeof(address);
address.sin_family = AF_INET;
#endif
return [self managerForAddress:&address];
}

- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability {
self = [super init];
if (!self) {
return nil;
}

self.networkReachability = reachability;
_networkReachability = CFRetain(reachability);
self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown;

return self;
}

- (instancetype)init
{
@throw [NSException exceptionWithName:NSGenericException
reason:@"`-init` unavailable. Use `-initWithReachability:` instead"
userInfo:nil];
return nil;
}

- (void)dealloc {
[self stopMonitoring];

if (_networkReachability) {
if (_networkReachability != NULL) {
CFRelease(_networkReachability);
_networkReachability = NULL;
}
}

@@ -182,42 +212,27 @@ - (void)startMonitoring {
}

__weak __typeof(self)weakSelf = self;
AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
AFNetworkReachabilityStatusCallback callback = ^(AFNetworkReachabilityStatus status) {
__strong __typeof(weakSelf)strongSelf = weakSelf;

strongSelf.networkReachabilityStatus = status;
if (strongSelf.networkReachabilityStatusBlock) {
strongSelf.networkReachabilityStatusBlock(status);
}


return strongSelf;
};

SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL};
SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context);
SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);

switch (self.networkReachabilityAssociation) {
case AFNetworkReachabilityForName:
break;
case AFNetworkReachabilityForAddress:
case AFNetworkReachabilityForAddressPair:
default: {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
SCNetworkReachabilityFlags flags;
SCNetworkReachabilityGetFlags(self.networkReachability, &flags);
AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags);
dispatch_async(dispatch_get_main_queue(), ^{
callback(status);

NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:@{ AFNetworkingReachabilityNotificationStatusItem: @(status) }];


});
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
SCNetworkReachabilityFlags flags;
if (SCNetworkReachabilityGetFlags(self.networkReachability, &flags)) {
AFPostReachabilityStatusChange(flags, callback);
}
break;
}
});
}

- (void)stopMonitoring {
@@ -251,3 +266,4 @@ + (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key {
}

@end
#endif
11 changes: 4 additions & 7 deletions Examples/AFNetworking/AFNetworking/AFNetworking.h
Original file line number Diff line number Diff line change
@@ -22,23 +22,20 @@

#import <Foundation/Foundation.h>
#import <Availability.h>
#import <TargetConditionals.h>

#ifndef _AFNETWORKING_
#define _AFNETWORKING_

#import "AFURLRequestSerialization.h"
#import "AFURLResponseSerialization.h"
#import "AFSecurityPolicy.h"
#import "AFNetworkReachabilityManager.h"

#import "AFURLConnectionOperation.h"
#import "AFHTTPRequestOperation.h"
#import "AFHTTPRequestOperationManager.h"
#if !TARGET_OS_WATCH
#import "AFNetworkReachabilityManager.h"
#endif

#if ( ( defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) || \
( defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 ) )
#import "AFURLSessionManager.h"
#import "AFHTTPSessionManager.h"
#endif

#endif /* _AFNETWORKING_ */
75 changes: 43 additions & 32 deletions Examples/AFNetworking/AFNetworking/AFSecurityPolicy.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// AFSecurity.h
//
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
// AFSecurityPolicy.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -31,43 +30,56 @@ typedef NS_ENUM(NSUInteger, AFSSLPinningMode) {

/**
`AFSecurityPolicy` evaluates server trust against pinned X.509 certificates and public keys over secure connections.
Adding pinned SSL certificates to your app helps prevent man-in-the-middle attacks and other vulnerabilities. Applications dealing with sensitive customer data or financial information are strongly encouraged to route all communication over an HTTPS connection with SSL pinning configured and enabled.
*/
@interface AFSecurityPolicy : NSObject

NS_ASSUME_NONNULL_BEGIN

@interface AFSecurityPolicy : NSObject <NSSecureCoding, NSCopying>

/**
The criteria by which server trust should be evaluated against the pinned SSL certificates. Defaults to `AFSSLPinningModeNone`.
*/
@property (nonatomic, assign) AFSSLPinningMode SSLPinningMode;
@property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode;

/**
Whether to evaluate an entire SSL certificate chain, or just the leaf certificate. Defaults to `YES`.
*/
@property (nonatomic, assign) BOOL validatesCertificateChain;
The certificates used to evaluate server trust according to the SSL pinning mode.
/**
The certificates used to evaluate server trust according to the SSL pinning mode. By default, this property is set to any (`.cer`) certificates included in the app bundle.
By default, this property is set to any (`.cer`) certificates included in the target compiling AFNetworking. Note that if you are using AFNetworking as embedded framework, no certificates will be pinned by default. Use `certificatesInBundle` to load certificates from your target, and then create a new policy by calling `policyWithPinningMode:withPinnedCertificates`.
Note that if pinning is enabled, `evaluateServerTrust:forDomain:` will return true if any pinned certificate matches.
*/
@property (nonatomic, strong) NSArray *pinnedCertificates;
@property (nonatomic, strong, nullable) NSSet <NSData *> *pinnedCertificates;

/**
Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`.
*/
@property (nonatomic, assign) BOOL allowInvalidCertificates;

/**
Whether or not to validate the domain name in the certificates CN field. Defaults to `YES` for `AFSSLPinningModePublicKey` or `AFSSLPinningModeCertificate`, otherwise `NO`.
Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES`.
*/
@property (nonatomic, assign) BOOL validatesDomainName;

///-----------------------------------------
/// @name Getting Certificates from the Bundle
///-----------------------------------------

/**
Returns any certificates included in the bundle. If you are using AFNetworking as an embedded framework, you must use this method to find the certificates you have included in your app bundle, and use them when creating your security policy by calling `policyWithPinningMode:withPinnedCertificates`.
@return The certificates included in the given bundle.
*/
+ (NSSet <NSData *> *)certificatesInBundle:(NSBundle *)bundle;

///-----------------------------------------
/// @name Getting Specific Security Policies
///-----------------------------------------

/**
Returns the shared default security policy, which does not accept invalid certificates, and does not validate against pinned certificates or public keys.
Returns the shared default security policy, which does not allow invalid certificates, validates domain name, and does not validate against pinned certificates or public keys.
@return The default security policy.
*/
+ (instancetype)defaultPolicy;
@@ -78,13 +90,23 @@ typedef NS_ENUM(NSUInteger, AFSSLPinningMode) {

/**
Creates and returns a security policy with the specified pinning mode.
@param pinningMode The SSL pinning mode.
@return A new security policy.
*/
+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode;

/**
Creates and returns a security policy with the specified pinning mode.
@param pinningMode The SSL pinning mode.
@param pinnedCertificates The certificates to pin against.
@return A new security policy.
*/
+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode withPinnedCertificates:(NSSet <NSData *> *)pinnedCertificates;

///------------------------------
/// @name Evaluating Server Trust
///------------------------------
@@ -94,29 +116,18 @@ typedef NS_ENUM(NSUInteger, AFSSLPinningMode) {
This method should be used when responding to an authentication challenge from a server.
@param serverTrust The X.509 certificate trust of the server.
@return Whether or not to trust the server.
@warning This method has been deprecated in favor of `-evaluateServerTrust:forDomain:`.
*/
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust DEPRECATED_ATTRIBUTE;

/**
Whether or not the specified server trust should be accepted, based on the security policy.
This method should be used when responding to an authentication challenge from a server.
@param serverTrust The X.509 certificate trust of the server.
@param domain The domain of serverTrust. If `nil`, the domain will not be validated.
@return Whether or not to trust the server.
*/
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
forDomain:(NSString *)domain;
forDomain:(nullable NSString *)domain;

@end

NS_ASSUME_NONNULL_END

///----------------
/// @name Constants
///----------------
190 changes: 107 additions & 83 deletions Examples/AFNetworking/AFNetworking/AFSecurityPolicy.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// AFSecurity.m
//
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
// AFSecurityPolicy.m
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -22,31 +21,13 @@

#import "AFSecurityPolicy.h"

// Equivalent of macro in <AssertMacros.h>, without causing compiler warning:
// "'DebugAssert' is deprecated: first deprecated in OS X 10.8"
#ifndef AF_Require
#define AF_Require(assertion, exceptionLabel) \
do { \
if (__builtin_expect(!(assertion), 0)) { \
goto exceptionLabel; \
} \
} while (0)
#endif

#ifndef AF_Require_noErr
#define AF_Require_noErr(errorCode, exceptionLabel) \
do { \
if (__builtin_expect(0 != (errorCode), 0)) { \
goto exceptionLabel; \
} \
} while (0)
#endif
#import <AssertMacros.h>

#if !defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#if !TARGET_OS_IOS && !TARGET_OS_WATCH && !TARGET_OS_TV
static NSData * AFSecKeyGetData(SecKeyRef key) {
CFDataRef data = NULL;

AF_Require_noErr(SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data), _out);
__Require_noErr_Quiet(SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data), _out);

return (__bridge_transfer NSData *)data;

@@ -60,7 +41,7 @@
#endif

static BOOL AFSecKeyIsEqualToKey(SecKeyRef key1, SecKeyRef key2) {
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#if TARGET_OS_IOS || TARGET_OS_WATCH || TARGET_OS_TV
return [(__bridge id)key1 isEqual:(__bridge id)key2];
#else
return [AFSecKeyGetData(key1) isEqual:AFSecKeyGetData(key2)];
@@ -70,21 +51,16 @@ static BOOL AFSecKeyIsEqualToKey(SecKeyRef key1, SecKeyRef key2) {
static id AFPublicKeyForCertificate(NSData *certificate) {
id allowedPublicKey = nil;
SecCertificateRef allowedCertificate;
SecCertificateRef allowedCertificates[1];
CFArrayRef tempCertificates = nil;
SecPolicyRef policy = nil;
SecTrustRef allowedTrust = nil;
SecTrustResultType result;

allowedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificate);
AF_Require(allowedCertificate != NULL, _out);

allowedCertificates[0] = allowedCertificate;
tempCertificates = CFArrayCreate(NULL, (const void **)allowedCertificates, 1, NULL);
__Require_Quiet(allowedCertificate != NULL, _out);

policy = SecPolicyCreateBasicX509();
AF_Require_noErr(SecTrustCreateWithCertificates(tempCertificates, policy, &allowedTrust), _out);
AF_Require_noErr(SecTrustEvaluate(allowedTrust, &result), _out);
__Require_noErr_Quiet(SecTrustCreateWithCertificates(allowedCertificate, policy, &allowedTrust), _out);
__Require_noErr_Quiet(SecTrustEvaluate(allowedTrust, &result), _out);

allowedPublicKey = (__bridge_transfer id)SecTrustCopyPublicKey(allowedTrust);

@@ -97,10 +73,6 @@ static id AFPublicKeyForCertificate(NSData *certificate) {
CFRelease(policy);
}

if (tempCertificates) {
CFRelease(tempCertificates);
}

if (allowedCertificate) {
CFRelease(allowedCertificate);
}
@@ -111,7 +83,7 @@ static id AFPublicKeyForCertificate(NSData *certificate) {
static BOOL AFServerTrustIsValid(SecTrustRef serverTrust) {
BOOL isValid = NO;
SecTrustResultType result;
AF_Require_noErr(SecTrustEvaluate(serverTrust, &result), _out);
__Require_noErr_Quiet(SecTrustEvaluate(serverTrust, &result), _out);

isValid = (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed);

@@ -142,10 +114,10 @@ static BOOL AFServerTrustIsValid(SecTrustRef serverTrust) {
CFArrayRef certificates = CFArrayCreate(NULL, (const void **)someCertificates, 1, NULL);

SecTrustRef trust;
AF_Require_noErr(SecTrustCreateWithCertificates(certificates, policy, &trust), _out);
__Require_noErr_Quiet(SecTrustCreateWithCertificates(certificates, policy, &trust), _out);

SecTrustResultType result;
AF_Require_noErr(SecTrustEvaluate(trust, &result), _out);
__Require_noErr_Quiet(SecTrustEvaluate(trust, &result), _out);

[trustChain addObject:(__bridge_transfer id)SecTrustCopyPublicKey(trust)];

@@ -168,25 +140,30 @@ static BOOL AFServerTrustIsValid(SecTrustRef serverTrust) {
#pragma mark -

@interface AFSecurityPolicy()
@property (readwrite, nonatomic, strong) NSArray *pinnedPublicKeys;
@property (readwrite, nonatomic, assign) AFSSLPinningMode SSLPinningMode;
@property (readwrite, nonatomic, strong) NSSet *pinnedPublicKeys;
@end

@implementation AFSecurityPolicy

+ (NSArray *)defaultPinnedCertificates {
static NSArray *_defaultPinnedCertificates = nil;
+ (NSSet *)certificatesInBundle:(NSBundle *)bundle {
NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"."];

NSMutableSet *certificates = [NSMutableSet setWithCapacity:[paths count]];
for (NSString *path in paths) {
NSData *certificateData = [NSData dataWithContentsOfFile:path];
[certificates addObject:certificateData];
}

return [NSSet setWithSet:certificates];
}

+ (NSSet *)defaultPinnedCertificates {
static NSSet *_defaultPinnedCertificates = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"."];

NSMutableArray *certificates = [NSMutableArray arrayWithCapacity:[paths count]];
for (NSString *path in paths) {
NSData *certificateData = [NSData dataWithContentsOfFile:path];
[certificates addObject:certificateData];
}

_defaultPinnedCertificates = [[NSArray alloc] initWithArray:certificates];
_defaultPinnedCertificates = [self certificatesInBundle:bundle];
});

return _defaultPinnedCertificates;
@@ -200,54 +177,65 @@ + (instancetype)defaultPolicy {
}

+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode {
return [self policyWithPinningMode:pinningMode withPinnedCertificates:[self defaultPinnedCertificates]];
}

+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode withPinnedCertificates:(NSSet *)pinnedCertificates {
AFSecurityPolicy *securityPolicy = [[self alloc] init];
securityPolicy.SSLPinningMode = pinningMode;
securityPolicy.validatesDomainName = YES;
[securityPolicy setPinnedCertificates:[self defaultPinnedCertificates]];

[securityPolicy setPinnedCertificates:pinnedCertificates];

return securityPolicy;
}

- (id)init {
- (instancetype)init {
self = [super init];
if (!self) {
return nil;
}

self.validatesCertificateChain = YES;
self.validatesDomainName = YES;

return self;
}

#pragma mark -

- (void)setPinnedCertificates:(NSArray *)pinnedCertificates {
- (void)setPinnedCertificates:(NSSet *)pinnedCertificates {
_pinnedCertificates = pinnedCertificates;

if (self.pinnedCertificates) {
NSMutableArray *mutablePinnedPublicKeys = [NSMutableArray arrayWithCapacity:[self.pinnedCertificates count]];
NSMutableSet *mutablePinnedPublicKeys = [NSMutableSet setWithCapacity:[self.pinnedCertificates count]];
for (NSData *certificate in self.pinnedCertificates) {
id publicKey = AFPublicKeyForCertificate(certificate);
if (!publicKey) {
continue;
}
[mutablePinnedPublicKeys addObject:publicKey];
}
self.pinnedPublicKeys = [NSArray arrayWithArray:mutablePinnedPublicKeys];
self.pinnedPublicKeys = [NSSet setWithSet:mutablePinnedPublicKeys];
} else {
self.pinnedPublicKeys = nil;
}
}

#pragma mark -

- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust {
return [self evaluateServerTrust:serverTrust forDomain:nil];
}

- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
forDomain:(NSString *)domain
{
if (domain && self.allowInvalidCertificates && self.validatesDomainName && (self.SSLPinningMode == AFSSLPinningModeNone || [self.pinnedCertificates count] == 0)) {
// https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/OverridingSSLChainValidationCorrectly.html
// According to the docs, you should only trust your provided certs for evaluation.
// Pinned certificates are added to the trust. Without pinned certificates,
// there is nothing to evaluate against.
//
// From Apple Docs:
// "Do not implicitly trust self-signed certificates as anchors (kSecTrustOptionImplicitAnchors).
// Instead, add your own (self-signed) CA certificate to the list of trusted anchors."
NSLog(@"In order to validate a domain name for self signed certificates, you MUST use pinning.");
return NO;
}

NSMutableArray *policies = [NSMutableArray array];
if (self.validatesDomainName) {
[policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)];
@@ -257,14 +245,16 @@ - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust

SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies);

if (!AFServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) {
if (self.SSLPinningMode == AFSSLPinningModeNone) {
return self.allowInvalidCertificates || AFServerTrustIsValid(serverTrust);
} else if (!AFServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) {
return NO;
}

NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust);
switch (self.SSLPinningMode) {
case AFSSLPinningModeNone:
return YES;
default:
return NO;
case AFSSLPinningModeCertificate: {
NSMutableArray *pinnedCertificates = [NSMutableArray array];
for (NSData *certificateData in self.pinnedCertificates) {
@@ -276,25 +266,20 @@ - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
return NO;
}

if (!self.validatesCertificateChain) {
return YES;
}

NSUInteger trustedCertificateCount = 0;
for (NSData *trustChainCertificate in serverCertificates) {
// obtain the chain after being validated, which *should* contain the pinned certificate in the last position (if it's the Root CA)
NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust);

for (NSData *trustChainCertificate in [serverCertificates reverseObjectEnumerator]) {
if ([self.pinnedCertificates containsObject:trustChainCertificate]) {
trustedCertificateCount++;
return YES;
}
}

return trustedCertificateCount == [serverCertificates count];
return NO;
}
case AFSSLPinningModePublicKey: {
NSUInteger trustedPublicKeyCount = 0;
NSArray *publicKeys = AFPublicKeyTrustChainForServerTrust(serverTrust);
if (!self.validatesCertificateChain && [publicKeys count] > 0) {
publicKeys = @[[publicKeys firstObject]];
}

for (id trustChainPublicKey in publicKeys) {
for (id pinnedPublicKey in self.pinnedPublicKeys) {
@@ -303,8 +288,7 @@ - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
}
}
}

return trustedPublicKeyCount > 0 && ((self.validatesCertificateChain && trustedPublicKeyCount == [serverCertificates count]) || (!self.validatesCertificateChain && trustedPublicKeyCount >= 1));
return trustedPublicKeyCount > 0;
}
}

@@ -317,4 +301,44 @@ + (NSSet *)keyPathsForValuesAffectingPinnedPublicKeys {
return [NSSet setWithObject:@"pinnedCertificates"];
}

#pragma mark - NSSecureCoding

+ (BOOL)supportsSecureCoding {
return YES;
}

- (instancetype)initWithCoder:(NSCoder *)decoder {

self = [self init];
if (!self) {
return nil;
}

self.SSLPinningMode = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(SSLPinningMode))] unsignedIntegerValue];
self.allowInvalidCertificates = [decoder decodeBoolForKey:NSStringFromSelector(@selector(allowInvalidCertificates))];
self.validatesDomainName = [decoder decodeBoolForKey:NSStringFromSelector(@selector(validatesDomainName))];
self.pinnedCertificates = [decoder decodeObjectOfClass:[NSArray class] forKey:NSStringFromSelector(@selector(pinnedCertificates))];

return self;
}

- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:[NSNumber numberWithUnsignedInteger:self.SSLPinningMode] forKey:NSStringFromSelector(@selector(SSLPinningMode))];
[coder encodeBool:self.allowInvalidCertificates forKey:NSStringFromSelector(@selector(allowInvalidCertificates))];
[coder encodeBool:self.validatesDomainName forKey:NSStringFromSelector(@selector(validatesDomainName))];
[coder encodeObject:self.pinnedCertificates forKey:NSStringFromSelector(@selector(pinnedCertificates))];
}

#pragma mark - NSCopying

- (instancetype)copyWithZone:(NSZone *)zone {
AFSecurityPolicy *securityPolicy = [[[self class] allocWithZone:zone] init];
securityPolicy.SSLPinningMode = self.SSLPinningMode;
securityPolicy.allowInvalidCertificates = self.allowInvalidCertificates;
securityPolicy.validatesDomainName = self.validatesDomainName;
securityPolicy.pinnedCertificates = [self.pinnedCertificates copyWithZone:zone];

return securityPolicy;
}

@end
328 changes: 0 additions & 328 deletions Examples/AFNetworking/AFNetworking/AFURLConnectionOperation.h

This file was deleted.

789 changes: 0 additions & 789 deletions Examples/AFNetworking/AFNetworking/AFURLConnectionOperation.m

This file was deleted.

161 changes: 98 additions & 63 deletions Examples/AFNetworking/AFNetworking/AFURLRequestSerialization.h

Large diffs are not rendered by default.

390 changes: 237 additions & 153 deletions Examples/AFNetworking/AFNetworking/AFURLRequestSerialization.m

Large diffs are not rendered by default.

83 changes: 52 additions & 31 deletions Examples/AFNetworking/AFNetworking/AFURLResponseSerialization.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
// AFSerialization.h
//
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
// AFURLResponseSerialization.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// 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
@@ -23,6 +22,13 @@
#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>

NS_ASSUME_NONNULL_BEGIN

/**
Recursively removes `NSNull` values from a JSON object.
*/
id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingOptions readingOptions);

/**
The `AFURLResponseSerialization` protocol is adopted by an object that decodes data into a more useful object representation, according to details in the server response. Response serializers may additionally perform validation on the incoming response and data.
@@ -39,9 +45,9 @@
@return The object decoded from the specified response data.
*/
- (id)responseObjectForResponse:(NSURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)error;
- (nullable id)responseObjectForResponse:(nullable NSURLResponse *)response
data:(nullable NSData *)data
error:(NSError * _Nullable __autoreleasing *)error NS_SWIFT_NOTHROW;

@end

@@ -54,10 +60,9 @@
*/
@interface AFHTTPResponseSerializer : NSObject <AFURLResponseSerialization>

/**
The string encoding used to serialize parameters.
*/
@property (nonatomic, assign) NSStringEncoding stringEncoding;
- (instancetype)init;

@property (nonatomic, assign) NSStringEncoding stringEncoding DEPRECATED_MSG_ATTRIBUTE("The string encoding is never used. AFHTTPResponseSerializer only validates status codes and content types but does not try to decode the received data in any way.");

/**
Creates and returns a serializer with default configuration.
@@ -73,12 +78,12 @@
See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
*/
@property (nonatomic, copy) NSIndexSet *acceptableStatusCodes;
@property (nonatomic, copy, nullable) NSIndexSet *acceptableStatusCodes;

/**
The acceptable MIME types for responses. When non-`nil`, responses with a `Content-Type` with MIME types that do not intersect with the set will result in an error during validation.
*/
@property (nonatomic, copy) NSSet *acceptableContentTypes;
@property (nonatomic, copy, nullable) NSSet <NSString *> *acceptableContentTypes;

/**
Validates the specified response and data.
@@ -91,9 +96,9 @@
@return `YES` if the response is valid, otherwise `NO`.
*/
- (BOOL)validateResponse:(NSHTTPURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)error;
- (BOOL)validateResponse:(nullable NSHTTPURLResponse *)response
data:(nullable NSData *)data
error:(NSError * _Nullable __autoreleasing *)error;

@end

@@ -108,9 +113,13 @@
- `application/json`
- `text/json`
- `text/javascript`
In RFC 7159 - Section 8.1, it states that JSON text is required to be encoded in UTF-8, UTF-16, or UTF-32, and the default encoding is UTF-8. NSJSONSerialization provides support for all the encodings listed in the specification, and recommends UTF-8 for efficiency. Using an unsupported encoding will result in serialization error. See the `NSJSONSerialization` documentation for more details.
*/
@interface AFJSONResponseSerializer : AFHTTPResponseSerializer

- (instancetype)init;

/**
Options for reading the response JSON data and creating the Foundation objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONReadingOptions". `0` by default.
*/
@@ -133,9 +142,9 @@
#pragma mark -

/**
`AFXMLParserSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLParser` objects.
`AFXMLParserResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLParser` objects.
By default, `AFXMLParserSerializer` accepts the following MIME types, which includes the official standard, `application/xml`, as well as other commonly-used types:
By default, `AFXMLParserResponseSerializer` accepts the following MIME types, which includes the official standard, `application/xml`, as well as other commonly-used types:
- `application/xml`
- `text/xml`
@@ -149,17 +158,19 @@
#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED

/**
`AFXMLDocumentSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLDocument` objects.
`AFXMLDocumentResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLDocument` objects.
By default, `AFXMLDocumentSerializer` accepts the following MIME types, which includes the official standard, `application/xml`, as well as other commonly-used types:
By default, `AFXMLDocumentResponseSerializer` accepts the following MIME types, which includes the official standard, `application/xml`, as well as other commonly-used types:
- `application/xml`
- `text/xml`
*/
@interface AFXMLDocumentResponseSerializer : AFHTTPResponseSerializer

- (instancetype)init;

/**
Input and output options specifically intended for `NSXMLDocument` objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONReadingOptions". `0` by default.
Input and output options specifically intended for `NSXMLDocument` objects. For possible values, see the `NSXMLDocument` documentation section "Input and Output Options". `0` by default.
*/
@property (nonatomic, assign) NSUInteger options;

@@ -177,14 +188,16 @@
#pragma mark -

/**
`AFPropertyListSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLDocument` objects.
`AFPropertyListResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLDocument` objects.
By default, `AFPropertyListSerializer` accepts the following MIME types:
By default, `AFPropertyListResponseSerializer` accepts the following MIME types:
- `application/x-plist`
*/
@interface AFPropertyListResponseSerializer : AFHTTPResponseSerializer

- (instancetype)init;

/**
The property list format. Possible values are described in "NSPropertyListFormat".
*/
@@ -209,9 +222,9 @@
#pragma mark -

/**
`AFImageSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes image responses.
`AFImageResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes image responses.
By default, `AFImageSerializer` accepts the following MIME types, which correspond to the image formats supported by UIImage or NSImage:
By default, `AFImageResponseSerializer` accepts the following MIME types, which correspond to the image formats supported by UIImage or NSImage:
- `image/tiff`
- `image/jpeg`
@@ -226,7 +239,7 @@
*/
@interface AFImageResponseSerializer : AFHTTPResponseSerializer

#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH
/**
The scale factor used when interpreting the image data to construct `responseImage`. Specifying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the size property. This is set to the value of scale of the main screen by default, which automatically scales images for retina displays, for instance.
*/
@@ -250,14 +263,14 @@
/**
The component response serializers.
*/
@property (readonly, nonatomic, copy) NSArray *responseSerializers;
@property (readonly, nonatomic, copy) NSArray <id<AFURLResponseSerialization>> *responseSerializers;

/**
Creates and returns a compound serializer comprised of the specified response serializers.
@warning Each response serializer specified must be a subclass of `AFHTTPResponseSerializer`, and response to `-validateResponse:data:error:`.
*/
+ (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers;
+ (instancetype)compoundSerializerWithResponseSerializers:(NSArray <id<AFURLResponseSerialization>> *)responseSerializers;

@end

@@ -277,18 +290,26 @@
`AFURLResponseSerializationErrorDomain`
AFURLResponseSerializer errors. Error codes for `AFURLResponseSerializationErrorDomain` correspond to codes in `NSURLErrorDomain`.
*/
extern NSString * const AFURLResponseSerializationErrorDomain;
FOUNDATION_EXPORT NSString * const AFURLResponseSerializationErrorDomain;

/**
## User info dictionary keys
These keys may exist in the user info dictionary, in addition to those defined for NSError.
- `NSString * const AFNetworkingOperationFailingURLResponseErrorKey`
- `NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey`
### Constants
`AFNetworkingOperationFailingURLResponseErrorKey`
The corresponding value is an `NSURLResponse` containing the response of the operation associated with an error. This key is only present in the `AFURLResponseSerializationErrorDomain`.
`AFNetworkingOperationFailingURLResponseDataErrorKey`
The corresponding value is an `NSData` containing the original data of the operation associated with an error. This key is only present in the `AFURLResponseSerializationErrorDomain`.
*/
extern NSString * const AFNetworkingOperationFailingURLResponseErrorKey;
FOUNDATION_EXPORT NSString * const AFNetworkingOperationFailingURLResponseErrorKey;

FOUNDATION_EXPORT NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey;

NS_ASSUME_NONNULL_END
264 changes: 152 additions & 112 deletions Examples/AFNetworking/AFNetworking/AFURLResponseSerialization.m

Large diffs are not rendered by default.

285 changes: 139 additions & 146 deletions Examples/AFNetworking/AFNetworking/AFURLSessionManager.h

Large diffs are not rendered by default.

675 changes: 475 additions & 200 deletions Examples/AFNetworking/AFNetworking/AFURLSessionManager.m

Large diffs are not rendered by default.

160 changes: 160 additions & 0 deletions Examples/AFNetworking/UIKit+AFNetworking/AFAutoPurgingImageCache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// AFAutoPurgingImageCache.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// 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 <TargetConditionals.h>
#import <Foundation/Foundation.h>

#if TARGET_OS_IOS || TARGET_OS_TV
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

/**
The `AFImageCache` protocol defines a set of APIs for adding, removing and fetching images from a cache synchronously.
*/
@protocol AFImageCache <NSObject>

/**
Adds the image to the cache with the given identifier.
@param image The image to cache.
@param identifier The unique identifier for the image in the cache.
*/
- (void)addImage:(UIImage *)image withIdentifier:(NSString *)identifier;

/**
Removes the image from the cache matching the given identifier.
@param identifier The unique identifier for the image in the cache.
@return A BOOL indicating whether or not the image was removed from the cache.
*/
- (BOOL)removeImageWithIdentifier:(NSString *)identifier;

/**
Removes all images from the cache.
@return A BOOL indicating whether or not all images were removed from the cache.
*/
- (BOOL)removeAllImages;

/**
Returns the image in the cache associated with the given identifier.
@param identifier The unique identifier for the image in the cache.
@return An image for the matching identifier, or nil.
*/
- (nullable UIImage *)imageWithIdentifier:(NSString *)identifier;
@end


/**
The `ImageRequestCache` protocol extends the `ImageCache` protocol by adding methods for adding, removing and fetching images from a cache given an `NSURLRequest` and additional identifier.
*/
@protocol AFImageRequestCache <AFImageCache>

/**
Asks if the image should be cached using an identifier created from the request and additional identifier.
@param image The image to be cached.
@param request The unique URL request identifing the image asset.
@param identifier The additional identifier to apply to the URL request to identify the image.
@return A BOOL indicating whether or not the image should be added to the cache. YES will cache, NO will prevent caching.
*/
- (BOOL)shouldCacheImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;

/**
Adds the image to the cache using an identifier created from the request and additional identifier.
@param image The image to cache.
@param request The unique URL request identifing the image asset.
@param identifier The additional identifier to apply to the URL request to identify the image.
*/
- (void)addImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;

/**
Removes the image from the cache using an identifier created from the request and additional identifier.
@param request The unique URL request identifing the image asset.
@param identifier The additional identifier to apply to the URL request to identify the image.
@return A BOOL indicating whether or not all images were removed from the cache.
*/
- (BOOL)removeImageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;

/**
Returns the image from the cache associated with an identifier created from the request and additional identifier.
@param request The unique URL request identifing the image asset.
@param identifier The additional identifier to apply to the URL request to identify the image.
@return An image for the matching request and identifier, or nil.
*/
- (nullable UIImage *)imageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;

@end

/**
The `AutoPurgingImageCache` in an in-memory image cache used to store images up to a given memory capacity. When the memory capacity is reached, the image cache is sorted by last access date, then the oldest image is continuously purged until the preferred memory usage after purge is met. Each time an image is accessed through the cache, the internal access date of the image is updated.
*/
@interface AFAutoPurgingImageCache : NSObject <AFImageRequestCache>

/**
The total memory capacity of the cache in bytes.
*/
@property (nonatomic, assign) UInt64 memoryCapacity;

/**
The preferred memory usage after purge in bytes. During a purge, images will be purged until the memory capacity drops below this limit.
*/
@property (nonatomic, assign) UInt64 preferredMemoryUsageAfterPurge;

/**
The current total memory usage in bytes of all images stored within the cache.
*/
@property (nonatomic, assign, readonly) UInt64 memoryUsage;

/**
Initialies the `AutoPurgingImageCache` instance with default values for memory capacity and preferred memory usage after purge limit. `memoryCapcity` defaults to `100 MB`. `preferredMemoryUsageAfterPurge` defaults to `60 MB`.
@return The new `AutoPurgingImageCache` instance.
*/
- (instancetype)init;

/**
Initialies the `AutoPurgingImageCache` instance with the given memory capacity and preferred memory usage
after purge limit.
@param memoryCapacity The total memory capacity of the cache in bytes.
@param preferredMemoryCapacity The preferred memory usage after purge in bytes.
@return The new `AutoPurgingImageCache` instance.
*/
- (instancetype)initWithMemoryCapacity:(UInt64)memoryCapacity preferredMemoryCapacity:(UInt64)preferredMemoryCapacity;

@end

NS_ASSUME_NONNULL_END

#endif

205 changes: 205 additions & 0 deletions Examples/AFNetworking/UIKit+AFNetworking/AFAutoPurgingImageCache.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
// AFAutoPurgingImageCache.m
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// 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 <TargetConditionals.h>

#if TARGET_OS_IOS || TARGET_OS_TV

#import "AFAutoPurgingImageCache.h"

@interface AFCachedImage : NSObject

@property (nonatomic, strong) UIImage *image;
@property (nonatomic, copy) NSString *identifier;
@property (nonatomic, assign) UInt64 totalBytes;
@property (nonatomic, strong) NSDate *lastAccessDate;
@property (nonatomic, assign) UInt64 currentMemoryUsage;

@end

@implementation AFCachedImage

- (instancetype)initWithImage:(UIImage *)image identifier:(NSString *)identifier {
if (self = [self init]) {
self.image = image;
self.identifier = identifier;

CGSize imageSize = CGSizeMake(image.size.width * image.scale, image.size.height * image.scale);
CGFloat bytesPerPixel = 4.0;
CGFloat bytesPerSize = imageSize.width * imageSize.height;
self.totalBytes = (UInt64)bytesPerPixel * (UInt64)bytesPerSize;
self.lastAccessDate = [NSDate date];
}
return self;
}

- (UIImage *)accessImage {
self.lastAccessDate = [NSDate date];
return self.image;
}

- (NSString *)description {
NSString *descriptionString = [NSString stringWithFormat:@"Idenfitier: %@ lastAccessDate: %@ ", self.identifier, self.lastAccessDate];
return descriptionString;

}

@end

@interface AFAutoPurgingImageCache ()
@property (nonatomic, strong) NSMutableDictionary <NSString* , AFCachedImage*> *cachedImages;
@property (nonatomic, assign) UInt64 currentMemoryUsage;
@property (nonatomic, strong) dispatch_queue_t synchronizationQueue;
@end

@implementation AFAutoPurgingImageCache

- (instancetype)init {
return [self initWithMemoryCapacity:100 * 1024 * 1024 preferredMemoryCapacity:60 * 1024 * 1024];
}

- (instancetype)initWithMemoryCapacity:(UInt64)memoryCapacity preferredMemoryCapacity:(UInt64)preferredMemoryCapacity {
if (self = [super init]) {
self.memoryCapacity = memoryCapacity;
self.preferredMemoryUsageAfterPurge = preferredMemoryCapacity;
self.cachedImages = [[NSMutableDictionary alloc] init];

NSString *queueName = [NSString stringWithFormat:@"com.alamofire.autopurgingimagecache-%@", [[NSUUID UUID] UUIDString]];
self.synchronizationQueue = dispatch_queue_create([queueName cStringUsingEncoding:NSASCIIStringEncoding], DISPATCH_QUEUE_CONCURRENT);

[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(removeAllImages)
name:UIApplicationDidReceiveMemoryWarningNotification
object:nil];

}
return self;
}

- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (UInt64)memoryUsage {
__block UInt64 result = 0;
dispatch_sync(self.synchronizationQueue, ^{
result = self.currentMemoryUsage;
});
return result;
}

- (void)addImage:(UIImage *)image withIdentifier:(NSString *)identifier {
dispatch_barrier_async(self.synchronizationQueue, ^{
AFCachedImage *cacheImage = [[AFCachedImage alloc] initWithImage:image identifier:identifier];

AFCachedImage *previousCachedImage = self.cachedImages[identifier];
if (previousCachedImage != nil) {
self.currentMemoryUsage -= previousCachedImage.totalBytes;
}

self.cachedImages[identifier] = cacheImage;
self.currentMemoryUsage += cacheImage.totalBytes;
});

dispatch_barrier_async(self.synchronizationQueue, ^{
if (self.currentMemoryUsage > self.memoryCapacity) {
UInt64 bytesToPurge = self.currentMemoryUsage - self.preferredMemoryUsageAfterPurge;
NSMutableArray <AFCachedImage*> *sortedImages = [NSMutableArray arrayWithArray:self.cachedImages.allValues];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastAccessDate"
ascending:YES];
[sortedImages sortUsingDescriptors:@[sortDescriptor]];

UInt64 bytesPurged = 0;

for (AFCachedImage *cachedImage in sortedImages) {
[self.cachedImages removeObjectForKey:cachedImage.identifier];
bytesPurged += cachedImage.totalBytes;
if (bytesPurged >= bytesToPurge) {
break ;
}
}
self.currentMemoryUsage -= bytesPurged;
}
});
}

- (BOOL)removeImageWithIdentifier:(NSString *)identifier {
__block BOOL removed = NO;
dispatch_barrier_sync(self.synchronizationQueue, ^{
AFCachedImage *cachedImage = self.cachedImages[identifier];
if (cachedImage != nil) {
[self.cachedImages removeObjectForKey:identifier];
self.currentMemoryUsage -= cachedImage.totalBytes;
removed = YES;
}
});
return removed;
}

- (BOOL)removeAllImages {
__block BOOL removed = NO;
dispatch_barrier_sync(self.synchronizationQueue, ^{
if (self.cachedImages.count > 0) {
[self.cachedImages removeAllObjects];
self.currentMemoryUsage = 0;
removed = YES;
}
});
return removed;
}

- (nullable UIImage *)imageWithIdentifier:(NSString *)identifier {
__block UIImage *image = nil;
dispatch_sync(self.synchronizationQueue, ^{
AFCachedImage *cachedImage = self.cachedImages[identifier];
image = [cachedImage accessImage];
});
return image;
}

- (void)addImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)identifier {
[self addImage:image withIdentifier:[self imageCacheKeyFromURLRequest:request withAdditionalIdentifier:identifier]];
}

- (BOOL)removeImageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)identifier {
return [self removeImageWithIdentifier:[self imageCacheKeyFromURLRequest:request withAdditionalIdentifier:identifier]];
}

- (nullable UIImage *)imageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)identifier {
return [self imageWithIdentifier:[self imageCacheKeyFromURLRequest:request withAdditionalIdentifier:identifier]];
}

- (NSString *)imageCacheKeyFromURLRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)additionalIdentifier {
NSString *key = request.URL.absoluteString;
if (additionalIdentifier != nil) {
key = [key stringByAppendingString:additionalIdentifier];
}
return key;
}

- (BOOL)shouldCacheImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier {
return YES;
}

@end

#endif
171 changes: 171 additions & 0 deletions Examples/AFNetworking/UIKit+AFNetworking/AFImageDownloader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
// AFImageDownloader.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// 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 <TargetConditionals.h>

#if TARGET_OS_IOS || TARGET_OS_TV

#import <Foundation/Foundation.h>
#import "AFAutoPurgingImageCache.h"
#import "AFHTTPSessionManager.h"

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSInteger, AFImageDownloadPrioritization) {
AFImageDownloadPrioritizationFIFO,
AFImageDownloadPrioritizationLIFO
};

/**
The `AFImageDownloadReceipt` is an object vended by the `AFImageDownloader` when starting a data task. It can be used to cancel active tasks running on the `AFImageDownloader` session. As a general rule, image data tasks should be cancelled using the `AFImageDownloadReceipt` instead of calling `cancel` directly on the `task` itself. The `AFImageDownloader` is optimized to handle duplicate task scenarios as well as pending versus active downloads.
*/
@interface AFImageDownloadReceipt : NSObject

/**
The data task created by the `AFImageDownloader`.
*/
@property (nonatomic, strong) NSURLSessionDataTask *task;

/**
The unique identifier for the success and failure blocks when duplicate requests are made.
*/
@property (nonatomic, strong) NSUUID *receiptID;
@end

/** The `AFImageDownloader` class is responsible for downloading images in parallel on a prioritized queue. Incoming downloads are added to the front or back of the queue depending on the download prioritization. Each downloaded image is cached in the underlying `NSURLCache` as well as the in-memory image cache. By default, any download request with a cached image equivalent in the image cache will automatically be served the cached image representation.
*/
@interface AFImageDownloader : NSObject

/**
The image cache used to store all downloaded images in. `AFAutoPurgingImageCache` by default.
*/
@property (nonatomic, strong, nullable) id <AFImageRequestCache> imageCache;

/**
The `AFHTTPSessionManager` used to download images. By default, this is configured with an `AFImageResponseSerializer`, and a shared `NSURLCache` for all image downloads.
*/
@property (nonatomic, strong) AFHTTPSessionManager *sessionManager;

/**
Defines the order prioritization of incoming download requests being inserted into the queue. `AFImageDownloadPrioritizationFIFO` by default.
*/
@property (nonatomic, assign) AFImageDownloadPrioritization downloadPrioritizaton;

/**
The shared default instance of `AFImageDownloader` initialized with default values.
*/
+ (instancetype)defaultInstance;

/**
Creates a default `NSURLCache` with common usage parameter values.
@returns The default `NSURLCache` instance.
*/
+ (NSURLCache *)defaultURLCache;

/**
The default `NSURLSessionConfiguration` with common usage parameter values.
*/
+ (NSURLSessionConfiguration *)defaultURLSessionConfiguration;

/**
Default initializer
@return An instance of `AFImageDownloader` initialized with default values.
*/
- (instancetype)init;

/**
Initializer with specific `URLSessionConfiguration`
@param configuration The `NSURLSessionConfiguration` to be be used
@return An instance of `AFImageDownloader` initialized with default values and custom `NSURLSessionConfiguration`
*/
- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration;

/**
Initializes the `AFImageDownloader` instance with the given session manager, download prioritization, maximum active download count and image cache.
@param sessionManager The session manager to use to download images.
@param downloadPrioritization The download prioritization of the download queue.
@param maximumActiveDownloads The maximum number of active downloads allowed at any given time. Recommend `4`.
@param imageCache The image cache used to store all downloaded images in.
@return The new `AFImageDownloader` instance.
*/
- (instancetype)initWithSessionManager:(AFHTTPSessionManager *)sessionManager
downloadPrioritization:(AFImageDownloadPrioritization)downloadPrioritization
maximumActiveDownloads:(NSInteger)maximumActiveDownloads
imageCache:(nullable id <AFImageRequestCache>)imageCache;

/**
Creates a data task using the `sessionManager` instance for the specified URL request.
If the same data task is already in the queue or currently being downloaded, the success and failure blocks are
appended to the already existing task. Once the task completes, all success or failure blocks attached to the
task are executed in the order they were added.
@param request The URL request.
@param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`.
@param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred.
@return The image download receipt for the data task if available. `nil` if the image is stored in the cache.
cache and the URL request cache policy allows the cache to be used.
*/
- (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *responseObject))success
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;

/**
Creates a data task using the `sessionManager` instance for the specified URL request.
If the same data task is already in the queue or currently being downloaded, the success and failure blocks are
appended to the already existing task. Once the task completes, all success or failure blocks attached to the
task are executed in the order they were added.
@param request The URL request.
@param receiptID The identifier to use for the download receipt that will be created for this request. This must be a unique identifier that does not represent any other request.
@param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`.
@param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred.
@return The image download receipt for the data task if available. `nil` if the image is stored in the cache.
cache and the URL request cache policy allows the cache to be used.
*/
- (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request
withReceiptID:(NSUUID *)receiptID
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *responseObject))success
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;

/**
Cancels the data task in the receipt by removing the corresponding success and failure blocks and cancelling the data task if necessary.
If the data task is pending in the queue, it will be cancelled if no other success and failure blocks are registered with the data task. If the data task is currently executing or is already completed, the success and failure blocks are removed and will not be called when the task finishes.
@param imageDownloadReceipt The image download receipt to cancel.
*/
- (void)cancelTaskForImageDownloadReceipt:(AFImageDownloadReceipt *)imageDownloadReceipt;

@end

#endif

NS_ASSUME_NONNULL_END
417 changes: 417 additions & 0 deletions Examples/AFNetworking/UIKit+AFNetworking/AFImageDownloader.m

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// AFNetworkActivityIndicatorManager.h
//
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -22,24 +21,27 @@

#import <Foundation/Foundation.h>

#import <Availability.h>
#import <TargetConditionals.h>

#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#if TARGET_OS_IOS

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

/**
`AFNetworkActivityIndicatorManager` manages the state of the network activity indicator in the status bar. When enabled, it will listen for notifications indicating that a network request operation has started or finished, and start or stop animating the indicator accordingly. The number of active requests is incremented and decremented much like a stack or a semaphore, and the activity indicator will animate so long as that number is greater than zero.
`AFNetworkActivityIndicatorManager` manages the state of the network activity indicator in the status bar. When enabled, it will listen for notifications indicating that a session task has started or finished, and start or stop animating the indicator accordingly. The number of active requests is incremented and decremented much like a stack or a semaphore, and the activity indicator will animate so long as that number is greater than zero.
You should enable the shared instance of `AFNetworkActivityIndicatorManager` when your application finishes launching. In `AppDelegate application:didFinishLaunchingWithOptions:` you can do so with the following code:
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
By setting `isNetworkActivityIndicatorVisible` to `YES` for `sharedManager`, the network activity indicator will show and hide automatically as requests start and finish. You should not ever need to call `incrementActivityCount` or `decrementActivityCount` yourself.
By setting `enabled` to `YES` for `sharedManager`, the network activity indicator will show and hide automatically as requests start and finish. You should not ever need to call `incrementActivityCount` or `decrementActivityCount` yourself.
See the Apple Human Interface Guidelines section about the Network Activity Indicator for more information:
http://developer.apple.com/library/iOS/#documentation/UserExperience/Conceptual/MobileHIG/UIElementGuidelines/UIElementGuidelines.html#//apple_ref/doc/uid/TP40006556-CH13-SW44
*/
NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropriate instead.")
@interface AFNetworkActivityIndicatorManager : NSObject

/**
@@ -50,9 +52,25 @@
@property (nonatomic, assign, getter = isEnabled) BOOL enabled;

/**
A Boolean value indicating whether the network activity indicator is currently displayed in the status bar.
A Boolean value indicating whether the network activity indicator manager is currently active.
*/
@property (readonly, nonatomic, assign, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;

/**
A time interval indicating the minimum duration of networking activity that should occur before the activity indicator is displayed. The default value 1 second. If the network activity indicator should be displayed immediately when network activity occurs, this value should be set to 0 seconds.
Apple's HIG describes the following:
> Display the network activity indicator to provide feedback when your app accesses the network for more than a couple of seconds. If the operation finishes sooner than that, you don’t have to show the network activity indicator, because the indicator is likely to disappear before users notice its presence.
*/
@property (readonly, nonatomic, assign) BOOL isNetworkActivityIndicatorVisible;
@property (nonatomic, assign) NSTimeInterval activationDelay;

/**
A time interval indicating the duration of time of no networking activity required before the activity indicator is disabled. This allows for continuous display of the network activity indicator across multiple requests. The default value is 0.17 seconds.
*/

@property (nonatomic, assign) NSTimeInterval completionDelay;

/**
Returns the shared network activity indicator manager object for the system.
@@ -71,6 +89,15 @@
*/
- (void)decrementActivityCount;

/**
Set the a custom method to be executed when the network activity indicator manager should be hidden/shown. By default, this is null, and the UIApplication Network Activity Indicator will be managed automatically. If this block is set, it is the responsiblity of the caller to manager the network activity indicator going forward.
@param block A block to be executed when the network activity indicator status changes.
*/
- (void)setNetworkingActivityActionWithBlock:(nullable void (^)(BOOL networkActivityIndicatorVisible))block;

@end

NS_ASSUME_NONNULL_END

#endif
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// AFNetworkActivityIndicatorManager.m
//
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -22,41 +21,42 @@

#import "AFNetworkActivityIndicatorManager.h"

#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED)

#import "AFHTTPRequestOperation.h"

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
#if TARGET_OS_IOS
#import "AFURLSessionManager.h"
#endif

static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.17;
typedef NS_ENUM(NSInteger, AFNetworkActivityManagerState) {
AFNetworkActivityManagerStateNotActive,
AFNetworkActivityManagerStateDelayingStart,
AFNetworkActivityManagerStateActive,
AFNetworkActivityManagerStateDelayingEnd
};

static NSURLRequest * AFNetworkRequestFromNotification(NSNotification *notification) {
if ([[notification object] isKindOfClass:[AFURLConnectionOperation class]]) {
return [(AFURLConnectionOperation *)[notification object] request];
}
static NSTimeInterval const kDefaultAFNetworkActivityManagerActivationDelay = 1.0;
static NSTimeInterval const kDefaultAFNetworkActivityManagerCompletionDelay = 0.17;

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
static NSURLRequest * AFNetworkRequestFromNotification(NSNotification *notification) {
if ([[notification object] respondsToSelector:@selector(originalRequest)]) {
return [(NSURLSessionTask *)[notification object] originalRequest];
} else {
return nil;
}
#endif

return nil;
}

typedef void (^AFNetworkActivityActionBlock)(BOOL networkActivityIndicatorVisible);

@interface AFNetworkActivityIndicatorManager ()
@property (readwrite, nonatomic, assign) NSInteger activityCount;
@property (readwrite, nonatomic, strong) NSTimer *activityIndicatorVisibilityTimer;
@property (readonly, nonatomic, getter = isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;
@property (readwrite, nonatomic, strong) NSTimer *activationDelayTimer;
@property (readwrite, nonatomic, strong) NSTimer *completionDelayTimer;
@property (readonly, nonatomic, getter = isNetworkActivityOccurring) BOOL networkActivityOccurring;
@property (nonatomic, copy) AFNetworkActivityActionBlock networkActivityActionBlock;
@property (nonatomic, assign) AFNetworkActivityManagerState currentState;
@property (nonatomic, assign, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;

- (void)updateNetworkActivityIndicatorVisibility;
- (void)updateNetworkActivityIndicatorVisibilityDelayed;
- (void)updateCurrentStateForNetworkActivityChange;
@end

@implementation AFNetworkActivityIndicatorManager
@dynamic networkActivityIndicatorVisible;

+ (instancetype)sharedManager {
static AFNetworkActivityIndicatorManager *_sharedManager = nil;
@@ -68,62 +68,67 @@ + (instancetype)sharedManager {
return _sharedManager;
}

+ (NSSet *)keyPathsForValuesAffectingIsNetworkActivityIndicatorVisible {
return [NSSet setWithObject:@"activityCount"];
}

- (id)init {
- (instancetype)init {
self = [super init];
if (!self) {
return nil;
}

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidStart:) name:AFNetworkingOperationDidStartNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingOperationDidFinishNotification object:nil];

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
self.currentState = AFNetworkActivityManagerStateNotActive;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidStart:) name:AFNetworkingTaskDidResumeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidSuspendNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidCompleteNotification object:nil];
#endif
self.activationDelay = kDefaultAFNetworkActivityManagerActivationDelay;
self.completionDelay = kDefaultAFNetworkActivityManagerCompletionDelay;

return self;
}

- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];

[_activityIndicatorVisibilityTimer invalidate];
[_activationDelayTimer invalidate];
[_completionDelayTimer invalidate];
}

- (void)updateNetworkActivityIndicatorVisibilityDelayed {
if (self.enabled) {
// Delay hiding of activity indicator for a short interval, to avoid flickering
if (![self isNetworkActivityIndicatorVisible]) {
[self.activityIndicatorVisibilityTimer invalidate];
self.activityIndicatorVisibilityTimer = [NSTimer timerWithTimeInterval:kAFNetworkActivityIndicatorInvisibilityDelay target:self selector:@selector(updateNetworkActivityIndicatorVisibility) userInfo:nil repeats:NO];
[[NSRunLoop mainRunLoop] addTimer:self.activityIndicatorVisibilityTimer forMode:NSRunLoopCommonModes];
} else {
[self performSelectorOnMainThread:@selector(updateNetworkActivityIndicatorVisibility) withObject:nil waitUntilDone:NO modes:@[NSRunLoopCommonModes]];
}
- (void)setEnabled:(BOOL)enabled {
_enabled = enabled;
if (enabled == NO) {
[self setCurrentState:AFNetworkActivityManagerStateNotActive];
}
}

- (BOOL)isNetworkActivityIndicatorVisible {
return self.activityCount > 0;
- (void)setNetworkingActivityActionWithBlock:(void (^)(BOOL networkActivityIndicatorVisible))block {
self.networkActivityActionBlock = block;
}

- (void)updateNetworkActivityIndicatorVisibility {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:[self isNetworkActivityIndicatorVisible]];
- (BOOL)isNetworkActivityOccurring {
@synchronized(self) {
return self.activityCount > 0;
}
}

- (void)setNetworkActivityIndicatorVisible:(BOOL)networkActivityIndicatorVisible {
if (_networkActivityIndicatorVisible != networkActivityIndicatorVisible) {
[self willChangeValueForKey:@"networkActivityIndicatorVisible"];
@synchronized(self) {
_networkActivityIndicatorVisible = networkActivityIndicatorVisible;
}
[self didChangeValueForKey:@"networkActivityIndicatorVisible"];
if (self.networkActivityActionBlock) {
self.networkActivityActionBlock(networkActivityIndicatorVisible);
} else {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:networkActivityIndicatorVisible];
}
}
}

- (void)setActivityCount:(NSInteger)activityCount {
@synchronized(self) {
_activityCount = activityCount;
}

dispatch_async(dispatch_get_main_queue(), ^{
[self updateNetworkActivityIndicatorVisibilityDelayed];
[self updateCurrentStateForNetworkActivityChange];
});
}

@@ -133,24 +138,21 @@ - (void)incrementActivityCount {
_activityCount++;
}
[self didChangeValueForKey:@"activityCount"];

dispatch_async(dispatch_get_main_queue(), ^{
[self updateNetworkActivityIndicatorVisibilityDelayed];
[self updateCurrentStateForNetworkActivityChange];
});
}

- (void)decrementActivityCount {
[self willChangeValueForKey:@"activityCount"];
@synchronized(self) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
_activityCount = MAX(_activityCount - 1, 0);
#pragma clang diagnostic pop
}
[self didChangeValueForKey:@"activityCount"];

dispatch_async(dispatch_get_main_queue(), ^{
[self updateNetworkActivityIndicatorVisibilityDelayed];
[self updateCurrentStateForNetworkActivityChange];
});
}

@@ -166,6 +168,92 @@ - (void)networkRequestDidFinish:(NSNotification *)notification {
}
}

#pragma mark - Internal State Management
- (void)setCurrentState:(AFNetworkActivityManagerState)currentState {
@synchronized(self) {
if (_currentState != currentState) {
[self willChangeValueForKey:@"currentState"];
_currentState = currentState;
switch (currentState) {
case AFNetworkActivityManagerStateNotActive:
[self cancelActivationDelayTimer];
[self cancelCompletionDelayTimer];
[self setNetworkActivityIndicatorVisible:NO];
break;
case AFNetworkActivityManagerStateDelayingStart:
[self startActivationDelayTimer];
break;
case AFNetworkActivityManagerStateActive:
[self cancelCompletionDelayTimer];
[self setNetworkActivityIndicatorVisible:YES];
break;
case AFNetworkActivityManagerStateDelayingEnd:
[self startCompletionDelayTimer];
break;
}
[self didChangeValueForKey:@"currentState"];
}

}
}

- (void)updateCurrentStateForNetworkActivityChange {
if (self.enabled) {
switch (self.currentState) {
case AFNetworkActivityManagerStateNotActive:
if (self.isNetworkActivityOccurring) {
[self setCurrentState:AFNetworkActivityManagerStateDelayingStart];
}
break;
case AFNetworkActivityManagerStateDelayingStart:
//No op. Let the delay timer finish out.
break;
case AFNetworkActivityManagerStateActive:
if (!self.isNetworkActivityOccurring) {
[self setCurrentState:AFNetworkActivityManagerStateDelayingEnd];
}
break;
case AFNetworkActivityManagerStateDelayingEnd:
if (self.isNetworkActivityOccurring) {
[self setCurrentState:AFNetworkActivityManagerStateActive];
}
break;
}
}
}

- (void)startActivationDelayTimer {
self.activationDelayTimer = [NSTimer
timerWithTimeInterval:self.activationDelay target:self selector:@selector(activationDelayTimerFired) userInfo:nil repeats:NO];
[[NSRunLoop mainRunLoop] addTimer:self.activationDelayTimer forMode:NSRunLoopCommonModes];
}

- (void)activationDelayTimerFired {
if (self.networkActivityOccurring) {
[self setCurrentState:AFNetworkActivityManagerStateActive];
} else {
[self setCurrentState:AFNetworkActivityManagerStateNotActive];
}
}

- (void)startCompletionDelayTimer {
[self.completionDelayTimer invalidate];
self.completionDelayTimer = [NSTimer timerWithTimeInterval:self.completionDelay target:self selector:@selector(completionDelayTimerFired) userInfo:nil repeats:NO];
[[NSRunLoop mainRunLoop] addTimer:self.completionDelayTimer forMode:NSRunLoopCommonModes];
}

- (void)completionDelayTimerFired {
[self setCurrentState:AFNetworkActivityManagerStateNotActive];
}

- (void)cancelActivationDelayTimer {
[self.activationDelayTimer invalidate];
}

- (void)cancelCompletionDelayTimer {
[self.completionDelayTimer invalidate];
}

@end

#endif
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// UIActivityIndicatorView+AFNetworking.h
//
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -22,16 +21,14 @@

#import <Foundation/Foundation.h>

#import <Availability.h>
#import <TargetConditionals.h>

#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#if TARGET_OS_IOS || TARGET_OS_TV

#import <UIKit/UIKit.h>

@class AFURLConnectionOperation;

/**
This category adds methods to the UIKit framework's `UIActivityIndicatorView` class. The methods in this category provide support for automatically starting and stopping animation depending on the loading state of a request operation or session task.
This category adds methods to the UIKit framework's `UIActivityIndicatorView` class. The methods in this category provide support for automatically starting and stopping animation depending on the loading state of a session task.
*/
@interface UIActivityIndicatorView (AFNetworking)

@@ -44,20 +41,7 @@
@param task The task. If `nil`, automatic updating from any previously specified operation will be disabled.
*/
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task;
#endif

///---------------------------------------
/// @name Animating for Request Operations
///---------------------------------------

/**
Binds the animating state to the execution state of the specified operation.
@param operation The operation. If `nil`, automatic updating from any previously specified operation will be disabled.
*/
- (void)setAnimatingWithStateOfOperation:(AFURLConnectionOperation *)operation;
- (void)setAnimatingWithStateOfTask:(nullable NSURLSessionTask *)task;

@end

Loading