123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- //
- // YTKNetworkPrivate.m
- //
- // Copyright (c) 2012-2016 YTKNetwork https://github.com/yuantiku
- //
- // 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 <CommonCrypto/CommonDigest.h>
- #import "YTKNetworkPrivate.h"
- #if __has_include(<AFNetworking/AFURLRequestSerialization.h>)
- #import <AFNetworking/AFURLRequestSerialization.h>
- #else
- #import <AFNetworking/AFURLRequestSerialization.h>
- #endif
- void YTKLog(NSString *format, ...) {
- #ifdef DEBUG
- if (![YTKNetworkConfig sharedConfig].debugLogEnabled) {
- return;
- }
- va_list argptr;
- va_start(argptr, format);
- NSLogv(format, argptr);
- va_end(argptr);
- #endif
- }
- @implementation YTKNetworkUtils
- + (BOOL)validateJSON:(id)json withValidator:(id)jsonValidator {
- if ([json isKindOfClass:[NSDictionary class]] &&
- [jsonValidator isKindOfClass:[NSDictionary class]]) {
- NSDictionary * dict = json;
- NSDictionary * validator = jsonValidator;
- BOOL result = YES;
- NSEnumerator * enumerator = [validator keyEnumerator];
- NSString * key;
- while ((key = [enumerator nextObject]) != nil) {
- id value = dict[key];
- id format = validator[key];
- if ([value isKindOfClass:[NSDictionary class]]
- || [value isKindOfClass:[NSArray class]]) {
- result = [self validateJSON:value withValidator:format];
- if (!result) {
- break;
- }
- } else {
- if ([value isKindOfClass:format] == NO &&
- [value isKindOfClass:[NSNull class]] == NO) {
- result = NO;
- break;
- }
- }
- }
- return result;
- } else if ([json isKindOfClass:[NSArray class]] &&
- [jsonValidator isKindOfClass:[NSArray class]]) {
- NSArray * validatorArray = (NSArray *)jsonValidator;
- if (validatorArray.count > 0) {
- NSArray * array = json;
- NSDictionary * validator = jsonValidator[0];
- for (id item in array) {
- BOOL result = [self validateJSON:item withValidator:validator];
- if (!result) {
- return NO;
- }
- }
- }
- return YES;
- } else if ([json isKindOfClass:jsonValidator]) {
- return YES;
- } else {
- return NO;
- }
- }
- + (void)addDoNotBackupAttribute:(NSString *)path {
- NSURL *url = [NSURL fileURLWithPath:path];
- NSError *error = nil;
- [url setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
- if (error) {
- YTKLog(@"error to set do not backup attribute, error = %@", error);
- }
- }
- + (NSString *)md5StringFromString:(NSString *)string {
- NSParameterAssert(string != nil && [string length] > 0);
- const char *value = [string UTF8String];
- unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
- CC_MD5(value, (CC_LONG)strlen(value), outputBuffer);
- NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
- for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){
- [outputString appendFormat:@"%02x", outputBuffer[count]];
- }
- return outputString;
- }
- + (NSString *)appVersionString {
- return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
- }
- + (NSStringEncoding)stringEncodingWithRequest:(YTKBaseRequest *)request {
- // From AFNetworking 2.6.3
- NSStringEncoding stringEncoding = NSUTF8StringEncoding;
- NSString *encodingName = [request.response.textEncodingName copy];
- if (encodingName) {
- CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)encodingName);
- if (encoding != kCFStringEncodingInvalidId) {
- stringEncoding = CFStringConvertEncodingToNSStringEncoding(encoding);
- }
- }
- return stringEncoding;
- }
- + (BOOL)validateResumeData:(NSData *)data {
- // From http://stackoverflow.com/a/22137510/3562486
- if (!data || [data length] < 1) return NO;
- NSError *error;
- NSDictionary *resumeDictionary = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:NULL error:&error];
- if (!resumeDictionary || error) return NO;
- // Before iOS 9 & Mac OS X 10.11
- #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < 90000)\
- || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED < 101100)
- NSString *localFilePath = [resumeDictionary objectForKey:@"NSURLSessionResumeInfoLocalPath"];
- if ([localFilePath length] < 1) return NO;
- return [[NSFileManager defaultManager] fileExistsAtPath:localFilePath];
- #endif
- // After iOS 9 we can not actually detects if the cache file exists. This plist file has a somehow
- // complicated structure. Besides, the plist structure is different between iOS 9 and iOS 10.
- // We can only assume that the plist being successfully parsed means the resume data is valid.
- return YES;
- }
- @end
- @implementation YTKBaseRequest (RequestAccessory)
- - (void)toggleAccessoriesWillStartCallBack {
- for (id<YTKRequestAccessory> accessory in self.requestAccessories) {
- if ([accessory respondsToSelector:@selector(requestWillStart:)]) {
- [accessory requestWillStart:self];
- }
- }
- }
- - (void)toggleAccessoriesWillStopCallBack {
- for (id<YTKRequestAccessory> accessory in self.requestAccessories) {
- if ([accessory respondsToSelector:@selector(requestWillStop:)]) {
- [accessory requestWillStop:self];
- }
- }
- }
- - (void)toggleAccessoriesDidStopCallBack {
- for (id<YTKRequestAccessory> accessory in self.requestAccessories) {
- if ([accessory respondsToSelector:@selector(requestDidStop:)]) {
- [accessory requestDidStop:self];
- }
- }
- }
- @end
- @implementation YTKBatchRequest (RequestAccessory)
- - (void)toggleAccessoriesWillStartCallBack {
- for (id<YTKRequestAccessory> accessory in self.requestAccessories) {
- if ([accessory respondsToSelector:@selector(requestWillStart:)]) {
- [accessory requestWillStart:self];
- }
- }
- }
- - (void)toggleAccessoriesWillStopCallBack {
- for (id<YTKRequestAccessory> accessory in self.requestAccessories) {
- if ([accessory respondsToSelector:@selector(requestWillStop:)]) {
- [accessory requestWillStop:self];
- }
- }
- }
- - (void)toggleAccessoriesDidStopCallBack {
- for (id<YTKRequestAccessory> accessory in self.requestAccessories) {
- if ([accessory respondsToSelector:@selector(requestDidStop:)]) {
- [accessory requestDidStop:self];
- }
- }
- }
- @end
- @implementation YTKChainRequest (RequestAccessory)
- - (void)toggleAccessoriesWillStartCallBack {
- for (id<YTKRequestAccessory> accessory in self.requestAccessories) {
- if ([accessory respondsToSelector:@selector(requestWillStart:)]) {
- [accessory requestWillStart:self];
- }
- }
- }
- - (void)toggleAccessoriesWillStopCallBack {
- for (id<YTKRequestAccessory> accessory in self.requestAccessories) {
- if ([accessory respondsToSelector:@selector(requestWillStop:)]) {
- [accessory requestWillStop:self];
- }
- }
- }
- - (void)toggleAccessoriesDidStopCallBack {
- for (id<YTKRequestAccessory> accessory in self.requestAccessories) {
- if ([accessory respondsToSelector:@selector(requestDidStop:)]) {
- [accessory requestDidStop:self];
- }
- }
- }
- @end
|