PageRenderTime 105ms CodeModel.GetById 3ms RepoModel.GetById 2ms app.codeStats 1ms

/TeamTalk/Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.m

https://gitlab.com/lisit1003/TTiOSClient
Objective C | 779 lines | 555 code | 197 blank | 27 comment | 100 complexity | 7dd53d5fdfc3570353d1e70154244f25 MD5 | raw file
  1. // AFSerialization.h
  2. //
  3. // Copyright (c) 2013-2014 AFNetworking (http://afnetworking.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. #import "AFURLResponseSerialization.h"
  23. #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
  24. #import <UIKit/UIKit.h>
  25. #elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
  26. #import <Cocoa/Cocoa.h>
  27. #endif
  28. NSString * const AFURLResponseSerializationErrorDomain = @"com.alamofire.error.serialization.response";
  29. NSString * const AFNetworkingOperationFailingURLResponseErrorKey = @"com.alamofire.serialization.response.error.response";
  30. static NSError * AFErrorWithUnderlyingError(NSError *error, NSError *underlyingError) {
  31. if (!error) {
  32. return underlyingError;
  33. }
  34. if (!underlyingError || error.userInfo[NSUnderlyingErrorKey]) {
  35. return error;
  36. }
  37. NSMutableDictionary *mutableUserInfo = [error.userInfo mutableCopy];
  38. mutableUserInfo[NSUnderlyingErrorKey] = underlyingError;
  39. return [[NSError alloc] initWithDomain:error.domain code:error.code userInfo:mutableUserInfo];
  40. }
  41. static BOOL AFErrorOrUnderlyingErrorHasCodeInDomain(NSError *error, NSInteger code, NSString *domain) {
  42. if ([error.domain isEqualToString:domain] && error.code == code) {
  43. return YES;
  44. } else if (error.userInfo[NSUnderlyingErrorKey]) {
  45. return AFErrorOrUnderlyingErrorHasCodeInDomain(error.userInfo[NSUnderlyingErrorKey], code, domain);
  46. }
  47. return NO;
  48. }
  49. static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingOptions readingOptions) {
  50. if ([JSONObject isKindOfClass:[NSArray class]]) {
  51. NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:[(NSArray *)JSONObject count]];
  52. for (id value in (NSArray *)JSONObject) {
  53. [mutableArray addObject:AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions)];
  54. }
  55. return (readingOptions & NSJSONReadingMutableContainers) ? mutableArray : [NSArray arrayWithArray:mutableArray];
  56. } else if ([JSONObject isKindOfClass:[NSDictionary class]]) {
  57. NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:JSONObject];
  58. for (id <NSCopying> key in [(NSDictionary *)JSONObject allKeys]) {
  59. id value = [(NSDictionary *)JSONObject objectForKey:key];
  60. if (!value || [value isEqual:[NSNull null]]) {
  61. [mutableDictionary removeObjectForKey:key];
  62. } else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) {
  63. [mutableDictionary setObject:AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions) forKey:key];
  64. }
  65. }
  66. return (readingOptions & NSJSONReadingMutableContainers) ? mutableDictionary : [NSDictionary dictionaryWithDictionary:mutableDictionary];
  67. }
  68. return JSONObject;
  69. }
  70. @implementation AFHTTPResponseSerializer
  71. + (instancetype)serializer {
  72. return [[self alloc] init];
  73. }
  74. - (instancetype)init {
  75. self = [super init];
  76. if (!self) {
  77. return nil;
  78. }
  79. self.stringEncoding = NSUTF8StringEncoding;
  80. self.acceptableStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)];
  81. self.acceptableContentTypes = nil;
  82. return self;
  83. }
  84. #pragma mark -
  85. - (BOOL)validateResponse:(NSHTTPURLResponse *)response
  86. data:(NSData *)data
  87. error:(NSError * __autoreleasing *)error
  88. {
  89. BOOL responseIsValid = YES;
  90. NSError *validationError = nil;
  91. if (response && [response isKindOfClass:[NSHTTPURLResponse class]]) {
  92. if (self.acceptableContentTypes && ![self.acceptableContentTypes containsObject:[response MIMEType]]) {
  93. if ([data length] > 0) {
  94. NSDictionary *userInfo = @{
  95. NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: unacceptable content-type: %@", @"AFNetworking", nil), [response MIMEType]],
  96. NSURLErrorFailingURLErrorKey:[response URL],
  97. AFNetworkingOperationFailingURLResponseErrorKey: response
  98. };
  99. validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo], validationError);
  100. }
  101. responseIsValid = NO;
  102. }
  103. if (self.acceptableStatusCodes && ![self.acceptableStatusCodes containsIndex:(NSUInteger)response.statusCode]) {
  104. NSDictionary *userInfo = @{
  105. NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: %@ (%ld)", @"AFNetworking", nil), [NSHTTPURLResponse localizedStringForStatusCode:response.statusCode], (long)response.statusCode],
  106. NSURLErrorFailingURLErrorKey:[response URL],
  107. AFNetworkingOperationFailingURLResponseErrorKey: response
  108. };
  109. validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorBadServerResponse userInfo:userInfo], validationError);
  110. responseIsValid = NO;
  111. }
  112. }
  113. if (error && !responseIsValid) {
  114. *error = validationError;
  115. }
  116. return responseIsValid;
  117. }
  118. #pragma mark - AFURLResponseSerialization
  119. - (id)responseObjectForResponse:(NSURLResponse *)response
  120. data:(NSData *)data
  121. error:(NSError *__autoreleasing *)error
  122. {
  123. [self validateResponse:(NSHTTPURLResponse *)response data:data error:error];
  124. return data;
  125. }
  126. #pragma mark - NSecureCoding
  127. + (BOOL)supportsSecureCoding {
  128. return YES;
  129. }
  130. - (id)initWithCoder:(NSCoder *)decoder {
  131. self = [self init];
  132. if (!self) {
  133. return nil;
  134. }
  135. self.acceptableStatusCodes = [decoder decodeObjectOfClass:[NSIndexSet class] forKey:NSStringFromSelector(@selector(acceptableStatusCodes))];
  136. self.acceptableContentTypes = [decoder decodeObjectOfClass:[NSIndexSet class] forKey:NSStringFromSelector(@selector(acceptableContentTypes))];
  137. return self;
  138. }
  139. - (void)encodeWithCoder:(NSCoder *)coder {
  140. [coder encodeObject:self.acceptableStatusCodes forKey:NSStringFromSelector(@selector(acceptableStatusCodes))];
  141. [coder encodeObject:self.acceptableContentTypes forKey:NSStringFromSelector(@selector(acceptableContentTypes))];
  142. }
  143. #pragma mark - NSCopying
  144. - (id)copyWithZone:(NSZone *)zone {
  145. AFHTTPResponseSerializer *serializer = [[[self class] allocWithZone:zone] init];
  146. serializer.acceptableStatusCodes = [self.acceptableStatusCodes copyWithZone:zone];
  147. serializer.acceptableContentTypes = [self.acceptableContentTypes copyWithZone:zone];
  148. return serializer;
  149. }
  150. @end
  151. #pragma mark -
  152. @implementation AFJSONResponseSerializer
  153. + (instancetype)serializer {
  154. return [self serializerWithReadingOptions:0];
  155. }
  156. + (instancetype)serializerWithReadingOptions:(NSJSONReadingOptions)readingOptions {
  157. AFJSONResponseSerializer *serializer = [[self alloc] init];
  158. serializer.readingOptions = readingOptions;
  159. return serializer;
  160. }
  161. - (instancetype)init {
  162. self = [super init];
  163. if (!self) {
  164. return nil;
  165. }
  166. self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil];
  167. return self;
  168. }
  169. #pragma mark - AFURLResponseSerialization
  170. - (id)responseObjectForResponse:(NSURLResponse *)response
  171. data:(NSData *)data
  172. error:(NSError *__autoreleasing *)error
  173. {
  174. if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) {
  175. if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) {
  176. return nil;
  177. }
  178. }
  179. // Workaround for behavior of Rails to return a single space for `head :ok` (a workaround for a bug in Safari), which is not interpreted as valid input by NSJSONSerialization.
  180. // See https://github.com/rails/rails/issues/1742
  181. NSStringEncoding stringEncoding = self.stringEncoding;
  182. if (response.textEncodingName) {
  183. CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)response.textEncodingName);
  184. if (encoding != kCFStringEncodingInvalidId) {
  185. stringEncoding = CFStringConvertEncodingToNSStringEncoding(encoding);
  186. }
  187. }
  188. id responseObject = nil;
  189. NSError *serializationError = nil;
  190. @autoreleasepool {
  191. NSString *responseString = [[NSString alloc] initWithData:data encoding:stringEncoding];
  192. if (responseString && ![responseString isEqualToString:@" "]) {
  193. // Workaround for a bug in NSJSONSerialization when Unicode character escape codes are used instead of the actual character
  194. // See http://stackoverflow.com/a/12843465/157142
  195. data = [responseString dataUsingEncoding:NSUTF8StringEncoding];
  196. if (data) {
  197. if ([data length] > 0) {
  198. responseObject = [NSJSONSerialization JSONObjectWithData:data options:self.readingOptions error:&serializationError];
  199. } else {
  200. return nil;
  201. }
  202. } else {
  203. NSDictionary *userInfo = @{
  204. NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"Data failed decoding as a UTF-8 string", nil, @"AFNetworking"),
  205. NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Could not decode string: %@", nil, @"AFNetworking"), responseString]
  206. };
  207. serializationError = [NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo];
  208. }
  209. }
  210. }
  211. if (self.removesKeysWithNullValues && responseObject) {
  212. responseObject = AFJSONObjectByRemovingKeysWithNullValues(responseObject, self.readingOptions);
  213. }
  214. if (error) {
  215. *error = AFErrorWithUnderlyingError(serializationError, *error);;
  216. }
  217. return responseObject;
  218. }
  219. #pragma mark - NSecureCoding
  220. - (id)initWithCoder:(NSCoder *)decoder {
  221. self = [super initWithCoder:decoder];
  222. if (!self) {
  223. return nil;
  224. }
  225. self.readingOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(readingOptions))] unsignedIntegerValue];
  226. return self;
  227. }
  228. - (void)encodeWithCoder:(NSCoder *)coder {
  229. [super encodeWithCoder:coder];
  230. [coder encodeObject:@(self.readingOptions) forKey:NSStringFromSelector(@selector(readingOptions))];
  231. }
  232. #pragma mark - NSCopying
  233. - (id)copyWithZone:(NSZone *)zone {
  234. AFJSONResponseSerializer *serializer = [[[self class] allocWithZone:zone] init];
  235. serializer.readingOptions = self.readingOptions;
  236. return serializer;
  237. }
  238. @end
  239. #pragma mark -
  240. @implementation AFXMLParserResponseSerializer
  241. + (instancetype)serializer {
  242. AFXMLParserResponseSerializer *serializer = [[self alloc] init];
  243. return serializer;
  244. }
  245. - (instancetype)init {
  246. self = [super init];
  247. if (!self) {
  248. return nil;
  249. }
  250. self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml", nil];
  251. return self;
  252. }
  253. #pragma mark - AFURLResponseSerialization
  254. - (id)responseObjectForResponse:(NSHTTPURLResponse *)response
  255. data:(NSData *)data
  256. error:(NSError *__autoreleasing *)error
  257. {
  258. if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) {
  259. if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) {
  260. return nil;
  261. }
  262. }
  263. return [[NSXMLParser alloc] initWithData:data];
  264. }
  265. @end
  266. #pragma mark -
  267. #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED
  268. @implementation AFXMLDocumentResponseSerializer
  269. + (instancetype)serializer {
  270. return [self serializerWithXMLDocumentOptions:0];
  271. }
  272. + (instancetype)serializerWithXMLDocumentOptions:(NSUInteger)mask {
  273. AFXMLDocumentResponseSerializer *serializer = [[self alloc] init];
  274. serializer.options = mask;
  275. return serializer;
  276. }
  277. - (instancetype)init {
  278. self = [super init];
  279. if (!self) {
  280. return nil;
  281. }
  282. self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml", nil];
  283. return self;
  284. }
  285. #pragma mark - AFURLResponseSerialization
  286. - (id)responseObjectForResponse:(NSURLResponse *)response
  287. data:(NSData *)data
  288. error:(NSError *__autoreleasing *)error
  289. {
  290. if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) {
  291. if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) {
  292. return nil;
  293. }
  294. }
  295. NSError *serializationError = nil;
  296. NSXMLDocument *document = [[NSXMLDocument alloc] initWithData:data options:self.options error:&serializationError];
  297. if (error) {
  298. *error = AFErrorWithUnderlyingError(serializationError, *error);
  299. }
  300. return document;
  301. }
  302. #pragma mark - NSecureCoding
  303. - (id)initWithCoder:(NSCoder *)decoder {
  304. self = [super initWithCoder:decoder];
  305. if (!self) {
  306. return nil;
  307. }
  308. self.options = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(options))] unsignedIntegerValue];
  309. return self;
  310. }
  311. - (void)encodeWithCoder:(NSCoder *)coder {
  312. [super encodeWithCoder:coder];
  313. [coder encodeObject:@(self.options) forKey:NSStringFromSelector(@selector(options))];
  314. }
  315. #pragma mark - NSCopying
  316. - (id)copyWithZone:(NSZone *)zone {
  317. AFXMLDocumentResponseSerializer *serializer = [[[self class] allocWithZone:zone] init];
  318. serializer.options = self.options;
  319. return serializer;
  320. }
  321. @end
  322. #endif
  323. #pragma mark -
  324. @implementation AFPropertyListResponseSerializer
  325. + (instancetype)serializer {
  326. return [self serializerWithFormat:NSPropertyListXMLFormat_v1_0 readOptions:0];
  327. }
  328. + (instancetype)serializerWithFormat:(NSPropertyListFormat)format
  329. readOptions:(NSPropertyListReadOptions)readOptions
  330. {
  331. AFPropertyListResponseSerializer *serializer = [[self alloc] init];
  332. serializer.format = format;
  333. serializer.readOptions = readOptions;
  334. return serializer;
  335. }
  336. - (instancetype)init {
  337. self = [super init];
  338. if (!self) {
  339. return nil;
  340. }
  341. self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/x-plist", nil];
  342. return self;
  343. }
  344. #pragma mark - AFURLResponseSerialization
  345. - (id)responseObjectForResponse:(NSURLResponse *)response
  346. data:(NSData *)data
  347. error:(NSError *__autoreleasing *)error
  348. {
  349. if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) {
  350. if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) {
  351. return nil;
  352. }
  353. }
  354. id responseObject;
  355. NSError *serializationError = nil;
  356. if (data) {
  357. responseObject = [NSPropertyListSerialization propertyListWithData:data options:self.readOptions format:NULL error:&serializationError];
  358. }
  359. if (error) {
  360. *error = AFErrorWithUnderlyingError(serializationError, *error);
  361. }
  362. return responseObject;
  363. }
  364. #pragma mark - NSecureCoding
  365. - (id)initWithCoder:(NSCoder *)decoder {
  366. self = [super initWithCoder:decoder];
  367. if (!self) {
  368. return nil;
  369. }
  370. self.format = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(format))] unsignedIntegerValue];
  371. self.readOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(readOptions))] unsignedIntegerValue];
  372. return self;
  373. }
  374. - (void)encodeWithCoder:(NSCoder *)coder {
  375. [super encodeWithCoder:coder];
  376. [coder encodeObject:@(self.format) forKey:NSStringFromSelector(@selector(format))];
  377. [coder encodeObject:@(self.readOptions) forKey:NSStringFromSelector(@selector(readOptions))];
  378. }
  379. #pragma mark - NSCopying
  380. - (id)copyWithZone:(NSZone *)zone {
  381. AFPropertyListResponseSerializer *serializer = [[[self class] allocWithZone:zone] init];
  382. serializer.format = self.format;
  383. serializer.readOptions = self.readOptions;
  384. return serializer;
  385. }
  386. @end
  387. #pragma mark -
  388. #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
  389. #import <CoreGraphics/CoreGraphics.h>
  390. static UIImage * AFImageWithDataAtScale(NSData *data, CGFloat scale) {
  391. UIImage *image = [[UIImage alloc] initWithData:data];
  392. return [[UIImage alloc] initWithCGImage:[image CGImage] scale:scale orientation:image.imageOrientation];
  393. }
  394. static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *response, NSData *data, CGFloat scale) {
  395. if (!data || [data length] == 0) {
  396. return nil;
  397. }
  398. CGImageRef imageRef = NULL;
  399. CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
  400. if ([response.MIMEType isEqualToString:@"image/png"]) {
  401. imageRef = CGImageCreateWithPNGDataProvider(dataProvider, NULL, true, kCGRenderingIntentDefault);
  402. } else if ([response.MIMEType isEqualToString:@"image/jpeg"]) {
  403. imageRef = CGImageCreateWithJPEGDataProvider(dataProvider, NULL, true, kCGRenderingIntentDefault);
  404. // CGImageCreateWithJPEGDataProvider does not properly handle CMKY, so if so, fall back to AFImageWithDataAtScale
  405. if (imageRef) {
  406. CGColorSpaceRef imageColorSpace = CGImageGetColorSpace(imageRef);
  407. CGColorSpaceModel imageColorSpaceModel = CGColorSpaceGetModel(imageColorSpace);
  408. if (imageColorSpaceModel == kCGColorSpaceModelCMYK) {
  409. CGImageRelease(imageRef);
  410. imageRef = NULL;
  411. }
  412. }
  413. }
  414. CGDataProviderRelease(dataProvider);
  415. UIImage *image = AFImageWithDataAtScale(data, scale);
  416. if (!imageRef) {
  417. if (image.images || !image) {
  418. return image;
  419. }
  420. imageRef = CGImageCreateCopy([image CGImage]);
  421. if (!imageRef) {
  422. return nil;
  423. }
  424. }
  425. size_t width = CGImageGetWidth(imageRef);
  426. size_t height = CGImageGetHeight(imageRef);
  427. size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef);
  428. if (width * height > 1024 * 1024 || bitsPerComponent > 8) {
  429. CGImageRelease(imageRef);
  430. return image;
  431. }
  432. size_t bytesPerRow = 0; // CGImageGetBytesPerRow() calculates incorrectly in iOS 5.0, so defer to CGBitmapContextCreate
  433. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  434. CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);
  435. CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
  436. if (colorSpaceModel == kCGColorSpaceModelRGB) {
  437. uint32_t alpha = (bitmapInfo & kCGBitmapAlphaInfoMask);
  438. if (alpha == kCGImageAlphaNone) {
  439. bitmapInfo &= ~kCGBitmapAlphaInfoMask;
  440. bitmapInfo |= kCGImageAlphaNoneSkipFirst;
  441. } else if (!(alpha == kCGImageAlphaNoneSkipFirst || alpha == kCGImageAlphaNoneSkipLast)) {
  442. bitmapInfo &= ~kCGBitmapAlphaInfoMask;
  443. bitmapInfo |= kCGImageAlphaPremultipliedFirst;
  444. }
  445. }
  446. CGContextRef context = CGBitmapContextCreate(NULL, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo);
  447. CGColorSpaceRelease(colorSpace);
  448. if (!context) {
  449. CGImageRelease(imageRef);
  450. return image;
  451. }
  452. CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), imageRef);
  453. CGImageRef inflatedImageRef = CGBitmapContextCreateImage(context);
  454. CGContextRelease(context);
  455. UIImage *inflatedImage = [[UIImage alloc] initWithCGImage:inflatedImageRef scale:scale orientation:image.imageOrientation];
  456. CGImageRelease(inflatedImageRef);
  457. CGImageRelease(imageRef);
  458. return inflatedImage;
  459. }
  460. #endif
  461. @implementation AFImageResponseSerializer
  462. - (instancetype)init {
  463. self = [super init];
  464. if (!self) {
  465. return nil;
  466. }
  467. self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"image/tiff", @"image/jpeg", @"image/gif", @"image/png", @"image/ico", @"image/x-icon", @"image/bmp", @"image/x-bmp", @"image/x-xbitmap", @"image/x-win-bitmap", nil];
  468. #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
  469. self.imageScale = [[UIScreen mainScreen] scale];
  470. self.automaticallyInflatesResponseImage = YES;
  471. #endif
  472. return self;
  473. }
  474. #pragma mark - AFURLResponseSerializer
  475. - (id)responseObjectForResponse:(NSURLResponse *)response
  476. data:(NSData *)data
  477. error:(NSError *__autoreleasing *)error
  478. {
  479. if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) {
  480. if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) {
  481. return nil;
  482. }
  483. }
  484. #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
  485. if (self.automaticallyInflatesResponseImage) {
  486. return AFInflatedImageFromResponseWithDataAtScale((NSHTTPURLResponse *)response, data, self.imageScale);
  487. } else {
  488. return AFImageWithDataAtScale(data, self.imageScale);
  489. }
  490. #elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
  491. // Ensure that the image is set to it's correct pixel width and height
  492. NSBitmapImageRep *bitimage = [[NSBitmapImageRep alloc] initWithData:data];
  493. NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize([bitimage pixelsWide], [bitimage pixelsHigh])];
  494. [image addRepresentation:bitimage];
  495. return image;
  496. #endif
  497. return nil;
  498. }
  499. #pragma mark - NSecureCoding
  500. - (id)initWithCoder:(NSCoder *)decoder {
  501. self = [super initWithCoder:decoder];
  502. if (!self) {
  503. return nil;
  504. }
  505. #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
  506. NSNumber *imageScale = [decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(imageScale))];
  507. #if CGFLOAT_IS_DOUBLE
  508. self.imageScale = [imageScale doubleValue];
  509. #else
  510. self.imageScale = [imageScale floatValue];
  511. #endif
  512. self.automaticallyInflatesResponseImage = [decoder decodeBoolForKey:NSStringFromSelector(@selector(automaticallyInflatesResponseImage))];
  513. #endif
  514. return self;
  515. }
  516. - (void)encodeWithCoder:(NSCoder *)coder {
  517. [super encodeWithCoder:coder];
  518. #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
  519. [coder encodeObject:@(self.imageScale) forKey:NSStringFromSelector(@selector(imageScale))];
  520. [coder encodeBool:self.automaticallyInflatesResponseImage forKey:NSStringFromSelector(@selector(automaticallyInflatesResponseImage))];
  521. #endif
  522. }
  523. #pragma mark - NSCopying
  524. - (id)copyWithZone:(NSZone *)zone {
  525. AFImageResponseSerializer *serializer = [[[self class] allocWithZone:zone] init];
  526. #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
  527. serializer.imageScale = self.imageScale;
  528. serializer.automaticallyInflatesResponseImage = self.automaticallyInflatesResponseImage;
  529. #endif
  530. return serializer;
  531. }
  532. @end
  533. #pragma mark -
  534. @interface AFCompoundResponseSerializer ()
  535. @property (readwrite, nonatomic, copy) NSArray *responseSerializers;
  536. @end
  537. @implementation AFCompoundResponseSerializer
  538. + (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers {
  539. AFCompoundResponseSerializer *serializer = [[self alloc] init];
  540. serializer.responseSerializers = responseSerializers;
  541. return serializer;
  542. }
  543. #pragma mark - AFURLResponseSerialization
  544. - (id)responseObjectForResponse:(NSURLResponse *)response
  545. data:(NSData *)data
  546. error:(NSError *__autoreleasing *)error
  547. {
  548. for (id <AFURLResponseSerialization> serializer in self.responseSerializers) {
  549. if (![serializer isKindOfClass:[AFHTTPResponseSerializer class]]) {
  550. continue;
  551. }
  552. NSError *serializerError = nil;
  553. id responseObject = [serializer responseObjectForResponse:response data:data error:&serializerError];
  554. if (responseObject) {
  555. if (error) {
  556. *error = AFErrorWithUnderlyingError(serializerError, *error);
  557. }
  558. return responseObject;
  559. }
  560. }
  561. return [super responseObjectForResponse:response data:data error:error];
  562. }
  563. #pragma mark - NSecureCoding
  564. - (id)initWithCoder:(NSCoder *)decoder {
  565. self = [super initWithCoder:decoder];
  566. if (!self) {
  567. return nil;
  568. }
  569. self.responseSerializers = [decoder decodeObjectOfClass:[NSArray class] forKey:NSStringFromSelector(@selector(responseSerializers))];
  570. return self;
  571. }
  572. - (void)encodeWithCoder:(NSCoder *)coder {
  573. [super encodeWithCoder:coder];
  574. [coder encodeObject:self.responseSerializers forKey:NSStringFromSelector(@selector(responseSerializers))];
  575. }
  576. #pragma mark - NSCopying
  577. - (id)copyWithZone:(NSZone *)zone {
  578. AFCompoundResponseSerializer *serializer = [[[self class] allocWithZone:zone] init];
  579. serializer.responseSerializers = self.responseSerializers;
  580. return serializer;
  581. }
  582. @end