afmotion 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. data/.gitignore +16 -0
  2. data/AFMotion.gemspec +19 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +53 -0
  5. data/README.md +135 -0
  6. data/Rakefile +14 -0
  7. data/app/app_delegate.rb +6 -0
  8. data/examples/AppDotNet/.gitignore +13 -0
  9. data/examples/AppDotNet/Gemfile +4 -0
  10. data/examples/AppDotNet/Gemfile.lock +48 -0
  11. data/examples/AppDotNet/Rakefile +10 -0
  12. data/examples/AppDotNet/app/app_delegate.rb +28 -0
  13. data/examples/AppDotNet/app/global_timeline_view_controller.rb +84 -0
  14. data/examples/AppDotNet/app/post.rb +23 -0
  15. data/examples/AppDotNet/app/post_table_view_cell.rb +44 -0
  16. data/examples/AppDotNet/app/user.rb +9 -0
  17. data/examples/AppDotNet/resources/profile-image-placeholder.png +0 -0
  18. data/examples/AppDotNet/resources/profile-image-placeholder@2x.png +0 -0
  19. data/examples/AppDotNet/spec/main_spec.rb +9 -0
  20. data/examples/AppDotNet/vendor/Podfile.lock +11 -0
  21. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFHTTPClient.h +574 -0
  22. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFHTTPClient.m +1187 -0
  23. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.h +133 -0
  24. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.m +341 -0
  25. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFImageRequestOperation.h +108 -0
  26. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFImageRequestOperation.m +237 -0
  27. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFJSONRequestOperation.h +71 -0
  28. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFJSONRequestOperation.m +136 -0
  29. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFNetworkActivityIndicatorManager.h +75 -0
  30. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFNetworkActivityIndicatorManager.m +131 -0
  31. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFNetworking.h +44 -0
  32. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFPropertyListRequestOperation.h +68 -0
  33. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFPropertyListRequestOperation.m +145 -0
  34. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.h +295 -0
  35. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.m +652 -0
  36. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFXMLRequestOperation.h +89 -0
  37. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/AFXMLRequestOperation.m +169 -0
  38. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/UIImageView+AFNetworking.h +78 -0
  39. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking/UIImageView+AFNetworking.m +180 -0
  40. data/examples/AppDotNet/vendor/Pods/AFNetworking/AFNetworking.podspec +28 -0
  41. data/examples/AppDotNet/vendor/Pods/AFNetworking/LICENSE +19 -0
  42. data/examples/AppDotNet/vendor/Pods/AFNetworking/README.md +179 -0
  43. data/examples/AppDotNet/vendor/Pods/BuildHeaders/AFNetworking/AFHTTPClient.h +574 -0
  44. data/examples/AppDotNet/vendor/Pods/BuildHeaders/AFNetworking/AFHTTPRequestOperation.h +133 -0
  45. data/examples/AppDotNet/vendor/Pods/BuildHeaders/AFNetworking/AFImageRequestOperation.h +108 -0
  46. data/examples/AppDotNet/vendor/Pods/BuildHeaders/AFNetworking/AFJSONRequestOperation.h +71 -0
  47. data/examples/AppDotNet/vendor/Pods/BuildHeaders/AFNetworking/AFNetworkActivityIndicatorManager.h +75 -0
  48. data/examples/AppDotNet/vendor/Pods/BuildHeaders/AFNetworking/AFNetworking.h +44 -0
  49. data/examples/AppDotNet/vendor/Pods/BuildHeaders/AFNetworking/AFPropertyListRequestOperation.h +68 -0
  50. data/examples/AppDotNet/vendor/Pods/BuildHeaders/AFNetworking/AFURLConnectionOperation.h +295 -0
  51. data/examples/AppDotNet/vendor/Pods/BuildHeaders/AFNetworking/AFXMLRequestOperation.h +89 -0
  52. data/examples/AppDotNet/vendor/Pods/BuildHeaders/AFNetworking/UIImageView+AFNetworking.h +78 -0
  53. data/examples/AppDotNet/vendor/Pods/Headers/AFNetworking/AFHTTPClient.h +574 -0
  54. data/examples/AppDotNet/vendor/Pods/Headers/AFNetworking/AFHTTPRequestOperation.h +133 -0
  55. data/examples/AppDotNet/vendor/Pods/Headers/AFNetworking/AFImageRequestOperation.h +108 -0
  56. data/examples/AppDotNet/vendor/Pods/Headers/AFNetworking/AFJSONRequestOperation.h +71 -0
  57. data/examples/AppDotNet/vendor/Pods/Headers/AFNetworking/AFNetworkActivityIndicatorManager.h +75 -0
  58. data/examples/AppDotNet/vendor/Pods/Headers/AFNetworking/AFNetworking.h +44 -0
  59. data/examples/AppDotNet/vendor/Pods/Headers/AFNetworking/AFPropertyListRequestOperation.h +68 -0
  60. data/examples/AppDotNet/vendor/Pods/Headers/AFNetworking/AFURLConnectionOperation.h +295 -0
  61. data/examples/AppDotNet/vendor/Pods/Headers/AFNetworking/AFXMLRequestOperation.h +89 -0
  62. data/examples/AppDotNet/vendor/Pods/Headers/AFNetworking/UIImageView+AFNetworking.h +78 -0
  63. data/examples/AppDotNet/vendor/Pods/Pods-Acknowledgements.markdown +26 -0
  64. data/examples/AppDotNet/vendor/Pods/Pods-Acknowledgements.plist +56 -0
  65. data/examples/AppDotNet/vendor/Pods/Pods-prefix.pch +12 -0
  66. data/examples/AppDotNet/vendor/Pods/Pods-resources.sh +19 -0
  67. data/examples/AppDotNet/vendor/Pods/Pods.bridgesupport +617 -0
  68. data/examples/AppDotNet/vendor/Pods/Pods.xcconfig +7 -0
  69. data/examples/AppDotNet/vendor/Pods/Pods.xcodeproj/project.pbxproj +998 -0
  70. data/examples/AppDotNet/vendor/Pods/PodsDummy_Pods.m +4 -0
  71. data/lib/afmotion/http.rb +55 -0
  72. data/lib/afmotion/http_client.rb +121 -0
  73. data/lib/afmotion/http_result.rb +25 -0
  74. data/lib/afmotion/image.rb +10 -0
  75. data/lib/afmotion/operation.rb +65 -0
  76. data/lib/afmotion/patch/NSString_NSUrl.rb +11 -0
  77. data/lib/afmotion/version.rb +5 -0
  78. data/lib/afmotion.rb +16 -0
  79. data/pkg/afmotion-0.0.1.gem +0 -0
  80. data/spec/http_client_spec.rb +104 -0
  81. data/spec/http_spec.rb +26 -0
  82. data/spec/operation_spec.rb +41 -0
  83. data/vendor/Podfile.lock +11 -0
  84. data/vendor/Pods/AFNetworking/AFNetworking/AFHTTPClient.h +574 -0
  85. data/vendor/Pods/AFNetworking/AFNetworking/AFHTTPClient.m +1187 -0
  86. data/vendor/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.h +133 -0
  87. data/vendor/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.m +341 -0
  88. data/vendor/Pods/AFNetworking/AFNetworking/AFImageRequestOperation.h +108 -0
  89. data/vendor/Pods/AFNetworking/AFNetworking/AFImageRequestOperation.m +237 -0
  90. data/vendor/Pods/AFNetworking/AFNetworking/AFJSONRequestOperation.h +71 -0
  91. data/vendor/Pods/AFNetworking/AFNetworking/AFJSONRequestOperation.m +136 -0
  92. data/vendor/Pods/AFNetworking/AFNetworking/AFNetworkActivityIndicatorManager.h +75 -0
  93. data/vendor/Pods/AFNetworking/AFNetworking/AFNetworkActivityIndicatorManager.m +131 -0
  94. data/vendor/Pods/AFNetworking/AFNetworking/AFNetworking.h +44 -0
  95. data/vendor/Pods/AFNetworking/AFNetworking/AFPropertyListRequestOperation.h +68 -0
  96. data/vendor/Pods/AFNetworking/AFNetworking/AFPropertyListRequestOperation.m +145 -0
  97. data/vendor/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.h +295 -0
  98. data/vendor/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.m +652 -0
  99. data/vendor/Pods/AFNetworking/AFNetworking/AFXMLRequestOperation.h +89 -0
  100. data/vendor/Pods/AFNetworking/AFNetworking/AFXMLRequestOperation.m +169 -0
  101. data/vendor/Pods/AFNetworking/AFNetworking/UIImageView+AFNetworking.h +78 -0
  102. data/vendor/Pods/AFNetworking/AFNetworking/UIImageView+AFNetworking.m +180 -0
  103. data/vendor/Pods/AFNetworking/AFNetworking.podspec +28 -0
  104. data/vendor/Pods/AFNetworking/LICENSE +19 -0
  105. data/vendor/Pods/AFNetworking/README.md +179 -0
  106. data/vendor/Pods/BuildHeaders/AFNetworking/AFHTTPClient.h +574 -0
  107. data/vendor/Pods/BuildHeaders/AFNetworking/AFHTTPRequestOperation.h +133 -0
  108. data/vendor/Pods/BuildHeaders/AFNetworking/AFImageRequestOperation.h +108 -0
  109. data/vendor/Pods/BuildHeaders/AFNetworking/AFJSONRequestOperation.h +71 -0
  110. data/vendor/Pods/BuildHeaders/AFNetworking/AFNetworkActivityIndicatorManager.h +75 -0
  111. data/vendor/Pods/BuildHeaders/AFNetworking/AFNetworking.h +44 -0
  112. data/vendor/Pods/BuildHeaders/AFNetworking/AFPropertyListRequestOperation.h +68 -0
  113. data/vendor/Pods/BuildHeaders/AFNetworking/AFURLConnectionOperation.h +295 -0
  114. data/vendor/Pods/BuildHeaders/AFNetworking/AFXMLRequestOperation.h +89 -0
  115. data/vendor/Pods/BuildHeaders/AFNetworking/UIImageView+AFNetworking.h +78 -0
  116. data/vendor/Pods/Headers/AFNetworking/AFHTTPClient.h +574 -0
  117. data/vendor/Pods/Headers/AFNetworking/AFHTTPRequestOperation.h +133 -0
  118. data/vendor/Pods/Headers/AFNetworking/AFImageRequestOperation.h +108 -0
  119. data/vendor/Pods/Headers/AFNetworking/AFJSONRequestOperation.h +71 -0
  120. data/vendor/Pods/Headers/AFNetworking/AFNetworkActivityIndicatorManager.h +75 -0
  121. data/vendor/Pods/Headers/AFNetworking/AFNetworking.h +44 -0
  122. data/vendor/Pods/Headers/AFNetworking/AFPropertyListRequestOperation.h +68 -0
  123. data/vendor/Pods/Headers/AFNetworking/AFURLConnectionOperation.h +295 -0
  124. data/vendor/Pods/Headers/AFNetworking/AFXMLRequestOperation.h +89 -0
  125. data/vendor/Pods/Headers/AFNetworking/UIImageView+AFNetworking.h +78 -0
  126. data/vendor/Pods/Pods-Acknowledgements.markdown +26 -0
  127. data/vendor/Pods/Pods-Acknowledgements.plist +56 -0
  128. data/vendor/Pods/Pods-prefix.pch +12 -0
  129. data/vendor/Pods/Pods-resources.sh +19 -0
  130. data/vendor/Pods/Pods.bridgesupport +617 -0
  131. data/vendor/Pods/Pods.xcconfig +7 -0
  132. data/vendor/Pods/PodsDummy_Pods.m +4 -0
  133. metadata +218 -0
@@ -0,0 +1,133 @@
1
+ // AFHTTPRequestOperation.h
2
+ //
3
+ // Copyright (c) 2011 Gowalla (http://gowalla.com/)
4
+ //
5
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ // of this software and associated documentation files (the "Software"), to deal
7
+ // in the Software without restriction, including without limitation the rights
8
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ // copies of the Software, and to permit persons to whom the Software is
10
+ // furnished to do so, subject to the following conditions:
11
+ //
12
+ // The above copyright notice and this permission notice shall be included in
13
+ // all copies or substantial portions of the Software.
14
+ //
15
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ // THE SOFTWARE.
22
+
23
+ #import <Foundation/Foundation.h>
24
+ #import "AFURLConnectionOperation.h"
25
+
26
+ /**
27
+ `AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request.
28
+ */
29
+ @interface AFHTTPRequestOperation : AFURLConnectionOperation
30
+
31
+ ///----------------------------------------------
32
+ /// @name Getting HTTP URL Connection Information
33
+ ///----------------------------------------------
34
+
35
+ /**
36
+ The last HTTP response received by the operation's connection.
37
+ */
38
+ @property (readonly, nonatomic, strong) NSHTTPURLResponse *response;
39
+
40
+ ///----------------------------------------------------------
41
+ /// @name Managing And Checking For Acceptable HTTP Responses
42
+ ///----------------------------------------------------------
43
+
44
+ /**
45
+ A Boolean value that corresponds to whether the status code of the response is within the specified set of acceptable status codes. Returns `YES` if `acceptableStatusCodes` is `nil`.
46
+ */
47
+ @property (readonly) BOOL hasAcceptableStatusCode;
48
+
49
+ /**
50
+ A Boolean value that corresponds to whether the MIME type of the response is among the specified set of acceptable content types. Returns `YES` if `acceptableContentTypes` is `nil`.
51
+ */
52
+ @property (readonly) BOOL hasAcceptableContentType;
53
+
54
+ /**
55
+ The callback dispatch queue on success. If `NULL` (default), the main queue is used.
56
+ */
57
+ @property (nonatomic, assign) dispatch_queue_t successCallbackQueue;
58
+
59
+ /**
60
+ The callback dispatch queue on failure. If `NULL` (default), the main queue is used.
61
+ */
62
+ @property (nonatomic, assign) dispatch_queue_t failureCallbackQueue;
63
+
64
+ ///------------------------------------------------------------
65
+ /// @name Managing Acceptable HTTP Status Codes & Content Types
66
+ ///------------------------------------------------------------
67
+
68
+ /**
69
+ Returns an `NSIndexSet` object containing the ranges of acceptable HTTP status codes. When non-`nil`, the operation will set the `error` property to an error in `AFErrorDomain`. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
70
+
71
+ By default, this is the range 200 to 299, inclusive.
72
+ */
73
+ + (NSIndexSet *)acceptableStatusCodes;
74
+
75
+ /**
76
+ Adds status codes to the set of acceptable HTTP status codes returned by `+acceptableStatusCodes` in subsequent calls by this class and its descendants.
77
+
78
+ @param statusCodes The status codes to be added to the set of acceptable HTTP status codes
79
+ */
80
+ + (void)addAcceptableStatusCodes:(NSIndexSet *)statusCodes;
81
+
82
+ /**
83
+ Returns an `NSSet` object containing the acceptable MIME types. When non-`nil`, the operation will set the `error` property to an error in `AFErrorDomain`. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17
84
+
85
+ By default, this is `nil`.
86
+ */
87
+ + (NSSet *)acceptableContentTypes;
88
+
89
+ /**
90
+ Adds content types to the set of acceptable MIME types returned by `+acceptableContentTypes` in subsequent calls by this class and its descendants.
91
+
92
+ @param contentTypes The content types to be added to the set of acceptable MIME types
93
+ */
94
+ + (void)addAcceptableContentTypes:(NSSet *)contentTypes;
95
+
96
+
97
+ ///-----------------------------------------------------
98
+ /// @name Determining Whether A Request Can Be Processed
99
+ ///-----------------------------------------------------
100
+
101
+ /**
102
+ A Boolean value determining whether or not the class can process the specified request. For example, `AFJSONRequestOperation` may check to make sure the content type was `application/json` or the URL path extension was `.json`.
103
+
104
+ @param urlRequest The request that is determined to be supported or not supported for this class.
105
+ */
106
+ + (BOOL)canProcessRequest:(NSURLRequest *)urlRequest;
107
+
108
+ ///-----------------------------------------------------------
109
+ /// @name Setting Completion Block Success / Failure Callbacks
110
+ ///-----------------------------------------------------------
111
+
112
+ /**
113
+ Sets the `completionBlock` property with a block that executes either the specified success or failure block, depending on the state of the request on completion. If `error` returns a value, which can be caused by an unacceptable status code or content type, then `failure` is executed. Otherwise, `success` is executed.
114
+
115
+ @param success The block to be executed on the completion of a successful request. This block has no return value and takes two arguments: the receiver operation and the object constructed from the response data of the request.
116
+ @param failure The block to be executed on the completion of an unsuccessful request. This block has no return value and takes two arguments: the receiver operation and the error that occurred during the request.
117
+
118
+ @discussion This method should be overridden in subclasses in order to specify the response object passed into the success block.
119
+ */
120
+ - (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
121
+ failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
122
+
123
+ @end
124
+
125
+ ///----------------
126
+ /// @name Functions
127
+ ///----------------
128
+
129
+ /**
130
+ Returns a set of MIME types detected in an HTTP `Accept` or `Content-Type` header.
131
+ */
132
+ extern NSSet * AFContentTypesFromHTTPHeader(NSString *string);
133
+
@@ -0,0 +1,341 @@
1
+ // AFHTTPRequestOperation.m
2
+ //
3
+ // Copyright (c) 2011 Gowalla (http://gowalla.com/)
4
+ //
5
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ // of this software and associated documentation files (the "Software"), to deal
7
+ // in the Software without restriction, including without limitation the rights
8
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ // copies of the Software, and to permit persons to whom the Software is
10
+ // furnished to do so, subject to the following conditions:
11
+ //
12
+ // The above copyright notice and this permission notice shall be included in
13
+ // all copies or substantial portions of the Software.
14
+ //
15
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ // THE SOFTWARE.
22
+
23
+ #import "AFHTTPRequestOperation.h"
24
+ #import <objc/runtime.h>
25
+
26
+ // Workaround for change in imp_implementationWithBlock() with Xcode 4.5
27
+ #if defined(__IPHONE_6_0) || defined(__MAC_10_8)
28
+ #define AF_CAST_TO_BLOCK id
29
+ #else
30
+ #define AF_CAST_TO_BLOCK __bridge void *
31
+ #endif
32
+
33
+ NSSet * AFContentTypesFromHTTPHeader(NSString *string) {
34
+ if (!string) {
35
+ return nil;
36
+ }
37
+
38
+ NSArray *mediaRanges = [string componentsSeparatedByString:@","];
39
+ NSMutableSet *mutableContentTypes = [NSMutableSet setWithCapacity:mediaRanges.count];
40
+
41
+ [mediaRanges enumerateObjectsUsingBlock:^(NSString *mediaRange, NSUInteger idx, BOOL *stop) {
42
+ NSRange parametersRange = [mediaRange rangeOfString:@";"];
43
+ if (parametersRange.location != NSNotFound) {
44
+ mediaRange = [mediaRange substringToIndex:parametersRange.location];
45
+ }
46
+
47
+ mediaRange = [mediaRange stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
48
+
49
+ if (mediaRange.length > 0) {
50
+ [mutableContentTypes addObject:mediaRange];
51
+ }
52
+ }];
53
+
54
+ return [NSSet setWithSet:mutableContentTypes];
55
+ }
56
+
57
+ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) {
58
+ NSMutableString *string = [NSMutableString string];
59
+
60
+ NSRange range = NSMakeRange([indexSet firstIndex], 1);
61
+ while (range.location != NSNotFound) {
62
+ NSUInteger nextIndex = [indexSet indexGreaterThanIndex:range.location];
63
+ while (nextIndex == range.location + range.length) {
64
+ range.length++;
65
+ nextIndex = [indexSet indexGreaterThanIndex:nextIndex];
66
+ }
67
+
68
+ if (string.length) {
69
+ [string appendString:@","];
70
+ }
71
+
72
+ if (range.length == 1) {
73
+ [string appendFormat:@"%lu", (long)range.location];
74
+ } else {
75
+ NSUInteger firstIndex = range.location;
76
+ NSUInteger lastIndex = firstIndex + range.length - 1;
77
+ [string appendFormat:@"%lu-%lu", (long)firstIndex, (long)lastIndex];
78
+ }
79
+
80
+ range.location = nextIndex;
81
+ range.length = 1;
82
+ }
83
+
84
+ return string;
85
+ }
86
+
87
+ static void AFSwizzleClassMethodWithClassAndSelectorUsingBlock(Class klass, SEL selector, id block) {
88
+ Method originalMethod = class_getClassMethod(klass, selector);
89
+ IMP implementation = imp_implementationWithBlock((AF_CAST_TO_BLOCK)block);
90
+ class_replaceMethod(objc_getMetaClass([NSStringFromClass(klass) UTF8String]), selector, implementation, method_getTypeEncoding(originalMethod));
91
+ }
92
+
93
+ #pragma mark -
94
+
95
+ @interface AFHTTPRequestOperation ()
96
+ @property (readwrite, nonatomic, strong) NSURLRequest *request;
97
+ @property (readwrite, nonatomic, strong) NSHTTPURLResponse *response;
98
+ @property (readwrite, nonatomic, strong) NSError *HTTPError;
99
+ @property (assign) long long totalContentLength;
100
+ @property (assign) long long offsetContentLength;
101
+ @end
102
+
103
+ @implementation AFHTTPRequestOperation
104
+ @synthesize HTTPError = _HTTPError;
105
+ @synthesize successCallbackQueue = _successCallbackQueue;
106
+ @synthesize failureCallbackQueue = _failureCallbackQueue;
107
+ @synthesize totalContentLength = _totalContentLength;
108
+ @synthesize offsetContentLength = _offsetContentLength;
109
+ @dynamic request;
110
+ @dynamic response;
111
+
112
+ - (void)dealloc {
113
+ if (_successCallbackQueue) {
114
+ #if !OS_OBJECT_USE_OBJC
115
+ dispatch_release(_successCallbackQueue);
116
+ #endif
117
+ _successCallbackQueue = NULL;
118
+ }
119
+
120
+ if (_failureCallbackQueue) {
121
+ #if !OS_OBJECT_USE_OBJC
122
+ dispatch_release(_failureCallbackQueue);
123
+ #endif
124
+ _failureCallbackQueue = NULL;
125
+ }
126
+ }
127
+
128
+ - (NSError *)error {
129
+ if (self.response && !self.HTTPError) {
130
+ if (![self hasAcceptableStatusCode] || ![self hasAcceptableContentType]) {
131
+ NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
132
+ [userInfo setValue:self.responseString forKey:NSLocalizedRecoverySuggestionErrorKey];
133
+ [userInfo setValue:[self.request URL] forKey:NSURLErrorFailingURLErrorKey];
134
+ [userInfo setValue:self.request forKey:AFNetworkingOperationFailingURLRequestErrorKey];
135
+ [userInfo setValue:self.response forKey:AFNetworkingOperationFailingURLResponseErrorKey];
136
+
137
+ if (![self hasAcceptableStatusCode]) {
138
+ NSUInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? (NSUInteger)[self.response statusCode] : 200;
139
+ [userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected status code in (%@), got %d", nil), AFStringFromIndexSet([[self class] acceptableStatusCodes]), statusCode] forKey:NSLocalizedDescriptionKey];
140
+ self.HTTPError = [[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorBadServerResponse userInfo:userInfo];
141
+ } else if (![self hasAcceptableContentType]) {
142
+ // Don't invalidate content type if there is no content
143
+ if ([self.responseData length] > 0) {
144
+ [userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected content type %@, got %@", nil), [[self class] acceptableContentTypes], [self.response MIMEType]] forKey:NSLocalizedDescriptionKey];
145
+ self.HTTPError = [[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo];
146
+ }
147
+ }
148
+ }
149
+ }
150
+
151
+ if (self.HTTPError) {
152
+ return self.HTTPError;
153
+ } else {
154
+ return [super error];
155
+ }
156
+ }
157
+
158
+ - (void)pause {
159
+ unsigned long long offset = 0;
160
+ if ([self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey]) {
161
+ offset = [[self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey] unsignedLongLongValue];
162
+ } else {
163
+ offset = [[self.outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey] length];
164
+ }
165
+
166
+ NSMutableURLRequest *mutableURLRequest = [self.request mutableCopy];
167
+ if ([[self.response allHeaderFields] valueForKey:@"ETag"]) {
168
+ [mutableURLRequest setValue:[[self.response allHeaderFields] valueForKey:@"ETag"] forHTTPHeaderField:@"If-Range"];
169
+ }
170
+ [mutableURLRequest setValue:[NSString stringWithFormat:@"bytes=%llu-", offset] forHTTPHeaderField:@"Range"];
171
+ self.request = mutableURLRequest;
172
+
173
+ [super pause];
174
+ }
175
+
176
+ - (BOOL)hasAcceptableStatusCode {
177
+ if (!self.response) {
178
+ return NO;
179
+ }
180
+
181
+ NSUInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? (NSUInteger)[self.response statusCode] : 200;
182
+ return ![[self class] acceptableStatusCodes] || [[[self class] acceptableStatusCodes] containsIndex:statusCode];
183
+ }
184
+
185
+ - (BOOL)hasAcceptableContentType {
186
+ if (!self.response) {
187
+ return NO;
188
+ }
189
+
190
+ // According to RFC 2616:
191
+ // Any HTTP/1.1 message containing an entity-body SHOULD include a Content-Type header field defining the media type of that body. If and only if the media type is not given by a Content-Type field, the recipient MAY attempt to guess the media type via inspection of its content and/or the name extension(s) of the URI used to identify the resource. If the media type remains unknown, the recipient SHOULD treat it as type "application/octet-stream".
192
+ // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html
193
+ NSString *contentType = [self.response MIMEType];
194
+ if (!contentType) {
195
+ contentType = @"application/octet-stream";
196
+ }
197
+
198
+ return ![[self class] acceptableContentTypes] || [[[self class] acceptableContentTypes] containsObject:contentType];
199
+ }
200
+
201
+ - (void)setSuccessCallbackQueue:(dispatch_queue_t)successCallbackQueue {
202
+ if (successCallbackQueue != _successCallbackQueue) {
203
+ if (_successCallbackQueue) {
204
+ #if !OS_OBJECT_USE_OBJC
205
+ dispatch_release(_successCallbackQueue);
206
+ #endif
207
+ _successCallbackQueue = NULL;
208
+ }
209
+
210
+ if (successCallbackQueue) {
211
+ #if !OS_OBJECT_USE_OBJC
212
+ dispatch_retain(successCallbackQueue);
213
+ #endif
214
+ _successCallbackQueue = successCallbackQueue;
215
+ }
216
+ }
217
+ }
218
+
219
+ - (void)setFailureCallbackQueue:(dispatch_queue_t)failureCallbackQueue {
220
+ if (failureCallbackQueue != _failureCallbackQueue) {
221
+ if (_failureCallbackQueue) {
222
+ #if !OS_OBJECT_USE_OBJC
223
+ dispatch_release(_failureCallbackQueue);
224
+ #endif
225
+ _failureCallbackQueue = NULL;
226
+ }
227
+
228
+ if (failureCallbackQueue) {
229
+ #if !OS_OBJECT_USE_OBJC
230
+ dispatch_retain(failureCallbackQueue);
231
+ #endif
232
+ _failureCallbackQueue = failureCallbackQueue;
233
+ }
234
+ }
235
+ }
236
+
237
+ - (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
238
+ failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
239
+ {
240
+ // completionBlock is manually nilled out in AFURLConnectionOperation to break the retain cycle.
241
+ #pragma clang diagnostic push
242
+ #pragma clang diagnostic ignored "-Warc-retain-cycles"
243
+ self.completionBlock = ^{
244
+ if ([self isCancelled]) {
245
+ return;
246
+ }
247
+
248
+ if (self.error) {
249
+ if (failure) {
250
+ dispatch_async(self.failureCallbackQueue ?: dispatch_get_main_queue(), ^{
251
+ failure(self, self.error);
252
+ });
253
+ }
254
+ } else {
255
+ if (success) {
256
+ dispatch_async(self.successCallbackQueue ?: dispatch_get_main_queue(), ^{
257
+ success(self, self.responseData);
258
+ });
259
+ }
260
+ }
261
+ };
262
+ #pragma clang diagnostic pop
263
+ }
264
+
265
+ #pragma mark - AFHTTPRequestOperation
266
+
267
+ + (NSIndexSet *)acceptableStatusCodes {
268
+ return [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)];
269
+ }
270
+
271
+ + (void)addAcceptableStatusCodes:(NSIndexSet *)statusCodes {
272
+ NSMutableIndexSet *mutableStatusCodes = [[NSMutableIndexSet alloc] initWithIndexSet:[self acceptableStatusCodes]];
273
+ [mutableStatusCodes addIndexes:statusCodes];
274
+ AFSwizzleClassMethodWithClassAndSelectorUsingBlock([self class], @selector(acceptableStatusCodes), ^(id _self) {
275
+ return mutableStatusCodes;
276
+ });
277
+ }
278
+
279
+ + (NSSet *)acceptableContentTypes {
280
+ return nil;
281
+ }
282
+
283
+ + (void)addAcceptableContentTypes:(NSSet *)contentTypes {
284
+ NSMutableSet *mutableContentTypes = [[NSMutableSet alloc] initWithSet:[self acceptableContentTypes] copyItems:YES];
285
+ [mutableContentTypes unionSet:contentTypes];
286
+ AFSwizzleClassMethodWithClassAndSelectorUsingBlock([self class], @selector(acceptableContentTypes), ^(id _self) {
287
+ return mutableContentTypes;
288
+ });
289
+ }
290
+
291
+ + (BOOL)canProcessRequest:(NSURLRequest *)request {
292
+ if ([[self class] isEqual:[AFHTTPRequestOperation class]]) {
293
+ return YES;
294
+ }
295
+
296
+ return [[self acceptableContentTypes] intersectsSet:AFContentTypesFromHTTPHeader([request valueForHTTPHeaderField:@"Accept"])];
297
+ }
298
+
299
+ #pragma mark - NSURLConnectionDelegate
300
+
301
+ - (void)connection:(NSURLConnection *)connection
302
+ didReceiveResponse:(NSURLResponse *)response
303
+ {
304
+ self.response = (NSHTTPURLResponse *)response;
305
+
306
+ // Set Content-Range header if status code of response is 206 (Partial Content)
307
+ // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7
308
+ long long totalContentLength = self.response.expectedContentLength;
309
+ long long fileOffset = 0;
310
+ NSUInteger statusCode = ([self.response isKindOfClass:[NSHTTPURLResponse class]]) ? (NSUInteger)[self.response statusCode] : 200;
311
+ if (statusCode == 206) {
312
+ NSString *contentRange = [self.response.allHeaderFields valueForKey:@"Content-Range"];
313
+ if ([contentRange hasPrefix:@"bytes"]) {
314
+ NSArray *byteRanges = [contentRange componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" -/"]];
315
+ if ([byteRanges count] == 4) {
316
+ fileOffset = [[byteRanges objectAtIndex:1] longLongValue];
317
+ totalContentLength = [[byteRanges objectAtIndex:2] longLongValue] ?: -1; // if this is "*", it's converted to 0, but -1 is default.
318
+ }
319
+ }
320
+ } else {
321
+ if ([self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey]) {
322
+ [self.outputStream setProperty:[NSNumber numberWithInteger:0] forKey:NSStreamFileCurrentOffsetKey];
323
+ } else {
324
+ if ([[self.outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey] length] > 0) {
325
+ self.outputStream = [NSOutputStream outputStreamToMemory];
326
+
327
+ NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
328
+ for (NSString *runLoopMode in self.runLoopModes) {
329
+ [self.outputStream scheduleInRunLoop:runLoop forMode:runLoopMode];
330
+ }
331
+ }
332
+ }
333
+ }
334
+
335
+ self.offsetContentLength = MAX(fileOffset, 0);
336
+ self.totalContentLength = totalContentLength;
337
+
338
+ [self.outputStream open];
339
+ }
340
+
341
+ @end
@@ -0,0 +1,108 @@
1
+ // AFImageRequestOperation.h
2
+ //
3
+ // Copyright (c) 2011 Gowalla (http://gowalla.com/)
4
+ //
5
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ // of this software and associated documentation files (the "Software"), to deal
7
+ // in the Software without restriction, including without limitation the rights
8
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ // copies of the Software, and to permit persons to whom the Software is
10
+ // furnished to do so, subject to the following conditions:
11
+ //
12
+ // The above copyright notice and this permission notice shall be included in
13
+ // all copies or substantial portions of the Software.
14
+ //
15
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ // THE SOFTWARE.
22
+
23
+ #import <Foundation/Foundation.h>
24
+ #import "AFHTTPRequestOperation.h"
25
+
26
+ #import <Availability.h>
27
+
28
+ #if __IPHONE_OS_VERSION_MIN_REQUIRED
29
+ #import <UIKit/UIKit.h>
30
+ #elif __MAC_OS_X_VERSION_MIN_REQUIRED
31
+ #import <Cocoa/Cocoa.h>
32
+ #endif
33
+
34
+ /**
35
+ `AFImageRequestOperation` is a subclass of `AFHTTPRequestOperation` for downloading an processing images.
36
+
37
+ ## Acceptable Content Types
38
+
39
+ By default, `AFImageRequestOperation` accepts the following MIME types, which correspond to the image formats supported by UIImage or NSImage:
40
+
41
+ - `image/tiff`
42
+ - `image/jpeg`
43
+ - `image/gif`
44
+ - `image/png`
45
+ - `image/ico`
46
+ - `image/x-icon`
47
+ - `image/bmp`
48
+ - `image/x-bmp`
49
+ - `image/x-xbitmap`
50
+ - `image/x-win-bitmap`
51
+ */
52
+ @interface AFImageRequestOperation : AFHTTPRequestOperation
53
+
54
+ /**
55
+ An image constructed from the response data. If an error occurs during the request, `nil` will be returned, and the `error` property will be set to the error.
56
+ */
57
+ #if __IPHONE_OS_VERSION_MIN_REQUIRED
58
+ @property (readonly, nonatomic, strong) UIImage *responseImage;
59
+ #elif __MAC_OS_X_VERSION_MIN_REQUIRED
60
+ @property (readonly, nonatomic, strong) NSImage *responseImage;
61
+ #endif
62
+
63
+ #if __IPHONE_OS_VERSION_MIN_REQUIRED
64
+ /**
65
+ 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.
66
+ */
67
+ @property (nonatomic, assign) CGFloat imageScale;
68
+ #endif
69
+
70
+ /**
71
+ Creates and returns an `AFImageRequestOperation` object and sets the specified success callback.
72
+
73
+ @param urlRequest The request object to be loaded asynchronously during execution of the operation.
74
+ @param success A block object to be executed when the request finishes successfully. This block has no return value and takes a single arguments, the image created from the response data of the request.
75
+
76
+ @return A new image request operation
77
+ */
78
+ #if __IPHONE_OS_VERSION_MIN_REQUIRED
79
+ + (AFImageRequestOperation *)imageRequestOperationWithRequest:(NSURLRequest *)urlRequest
80
+ success:(void (^)(UIImage *image))success;
81
+ #elif __MAC_OS_X_VERSION_MIN_REQUIRED
82
+ + (AFImageRequestOperation *)imageRequestOperationWithRequest:(NSURLRequest *)urlRequest
83
+ success:(void (^)(NSImage *image))success;
84
+ #endif
85
+
86
+ /**
87
+ Creates and returns an `AFImageRequestOperation` object and sets the specified success callback.
88
+
89
+ @param urlRequest The request object to be loaded asynchronously during execution of the operation.
90
+ @param imageProcessingBlock A block object to be executed after the image request finishes successfully, but before the image is returned in the `success` block. This block takes a single argument, the image loaded from the response body, and returns the processed image.
91
+ @param success A block object to be executed when the request finishes successfully, with a status code in the 2xx range, and with an acceptable content type (e.g. `image/png`). This block has no return value and takes three arguments: the request object of the operation, the response for the request, and the image created from the response data.
92
+ @param failure A block object to be executed when the request finishes unsuccessfully. This block has no return value and takes three arguments: the request object of the operation, the response for the request, and the error associated with the cause for the unsuccessful operation.
93
+
94
+ @return A new image request operation
95
+ */
96
+ #if __IPHONE_OS_VERSION_MIN_REQUIRED
97
+ + (AFImageRequestOperation *)imageRequestOperationWithRequest:(NSURLRequest *)urlRequest
98
+ imageProcessingBlock:(UIImage *(^)(UIImage *image))imageProcessingBlock
99
+ success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image))success
100
+ failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure;
101
+ #elif __MAC_OS_X_VERSION_MIN_REQUIRED
102
+ + (AFImageRequestOperation *)imageRequestOperationWithRequest:(NSURLRequest *)urlRequest
103
+ imageProcessingBlock:(NSImage *(^)(NSImage *image))imageProcessingBlock
104
+ success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSImage *image))success
105
+ failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure;
106
+ #endif
107
+
108
+ @end