diff --git a/AFNetworking/AFHTTPClient.h b/AFNetworking/AFHTTPClient.h index e7083f5..3826b6f 100644 --- a/AFNetworking/AFHTTPClient.h +++ b/AFNetworking/AFHTTPClient.h @@ -118,7 +118,7 @@ typedef enum { @property (nonatomic, assign) NSStringEncoding stringEncoding; /** - The `AFHTTPClientParameterEncoding` value corresponding to how parameters are encoded into a request body. This is `AFFormURLParameterEncoding` by default. + The `AFHTTPClientParameterEncoding` value corresponding to how parameters are encoded into a request body for request methods other than `GET`, `HEAD` or `DELETE`. This is `AFFormURLParameterEncoding` by default. @warning Some nested parameter structures, such as a keyed array of hashes containing inconsistent keys (i.e. `@{@"": @[@{@"a" : @(1)}, @{@"b" : @(2)}]}`), cannot be unambiguously represented in query strings. It is strongly recommended that an unambiguous encoding, such as `AFJSONParameterEncoding`, is used when posting complicated or nondeterministic parameter structures. */ diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 5ead060..303ff89 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -254,15 +254,24 @@ NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) { }]; [self setDefaultHeader:@"Accept-Language" value:[acceptLanguagesComponents componentsJoinedByString:@", "]]; + NSString *userAgent = nil; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43 - [self setDefaultHeader:@"User-Agent" value:[NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], (__bridge id)CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] ? [[UIScreen mainScreen] scale] : 1.0f)]]; + userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], (__bridge id)CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] ? [[UIScreen mainScreen] scale] : 1.0f)]; #elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) - [self setDefaultHeader:@"User-Agent" value:[NSString stringWithFormat:@"%@/%@ (Mac OS X %@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]]]; + userAgent = [NSString stringWithFormat:@"%@/%@ (Mac OS X %@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]]; #endif #pragma clang diagnostic pop + if (userAgent) { + if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) { + NSMutableString *mutableUserAgent = [userAgent mutableCopy]; + CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, kCFStringTransformToLatin, false); + userAgent = mutableUserAgent; + } + [self setDefaultHeader:@"User-Agent" value:userAgent]; + } #ifdef _SYSTEMCONFIGURATION_H self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown; diff --git a/AFNetworking/UIImageView+AFNetworking.m b/AFNetworking/UIImageView+AFNetworking.m index b577cf1..f0f8274 100644 --- a/AFNetworking/UIImageView+AFNetworking.m +++ b/AFNetworking/UIImageView+AFNetworking.m @@ -101,13 +101,13 @@ static char kAFImageRequestOperationObjectKey; UIImage *cachedImage = [[[self class] af_sharedImageCache] cachedImageForRequest:urlRequest]; if (cachedImage) { + self.af_imageRequestOperation = nil; + if (success) { success(nil, nil, cachedImage); } else { self.image = cachedImage; } - - self.af_imageRequestOperation = nil; } else { if (placeholderImage) { self.image = placeholderImage; @@ -116,27 +116,27 @@ static char kAFImageRequestOperationObjectKey; AFImageRequestOperation *requestOperation = [[AFImageRequestOperation alloc] initWithRequest:urlRequest]; [requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { if ([urlRequest isEqual:[self.af_imageRequestOperation request]]) { + if (self.af_imageRequestOperation == operation) { + self.af_imageRequestOperation = nil; + } + if (success) { success(operation.request, operation.response, responseObject); } else if (responseObject) { self.image = responseObject; } - - if (self.af_imageRequestOperation == operation) { - self.af_imageRequestOperation = nil; - } } [[[self class] af_sharedImageCache] cacheImage:responseObject forRequest:urlRequest]; } failure:^(AFHTTPRequestOperation *operation, NSError *error) { if ([urlRequest isEqual:[self.af_imageRequestOperation request]]) { - if (failure) { - failure(operation.request, operation.response, error); - } - if (self.af_imageRequestOperation == operation) { self.af_imageRequestOperation = nil; } + + if (failure) { + failure(operation.request, operation.response, error); + } } }]; diff --git a/README.md b/README.md index 916d99c..4d2f226 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ AFNetworking is architected to be as small and modular as possible, in order to