// // NetworkRequestManager.m // MingMen // // Created by 罗云飞 on 2017/3/13. // Copyright © 2017年 罗云飞. All rights reserved. // #import "NetworkRequestManager.h" #include #import "AFNetworking.h" #import "AFNetworkActivityIndicatorManager.h" #import "NewUtils.h" #import "NewLoginViewController.h" @implementation NetworkRequestManager static BOOL isNetwork; #pragma mark - 有无网络 +(BOOL) connectedToNetwork { return isNetwork; /* 感觉sockaddr_in 不兼容IPV6 也不会写sockaddr_in6 struct sockaddr_in zeroAddress; bzero(&zeroAddress, sizeof(zeroAddress)); zeroAddress.sin_len = sizeof(zeroAddress); zeroAddress.sin_family = AF_INET; SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress); SCNetworkReachabilityFlags flags; BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags); CFRelease(defaultRouteReachability); if (!didRetrieveFlags) { printf("Error. Could not recover network reachability flags\n"); return NO; } BOOL isReachable = ((flags & kSCNetworkFlagsReachable) != 0); BOOL needsConnection = ((flags & kSCNetworkFlagsConnectionRequired) != 0); return (isReachable && !needsConnection) ? YES : NO; */ } #pragma mark - 观察网络状态 + (void)observeNetworkStatus { AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager]; [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { switch (status) { case AFNetworkReachabilityStatusUnknown: isNetwork = YES; NSLog(@"未知网络"); break; case AFNetworkReachabilityStatusNotReachable: isNetwork = NO; NSLog(@"无网络"); break; case AFNetworkReachabilityStatusReachableViaWWAN: isNetwork = YES; NSLog(@"正在使用手机流量"); break; case AFNetworkReachabilityStatusReachableViaWiFi: isNetwork = YES; NSLog(@"正在使用手机WIFI"); break; } }]; [manager startMonitoring]; } #pragma mark - GET请求 + (void)requestGetWithInterfacePrefix:(NSString*)_ifPrefix parameters:(id)parameters onSuccess:(ResponseTask)succeed onFailure:(CallbackTask)failed { //接入参数由协议参数和业务参数共同组成,业务接口中会介绍每个业务接口的输入/输出参数 //为了确保数据传输过程中的数据真实性和完整性,我们需要对数据进行签名校验。 //HTTP请求中传递的参数中,需要对token、安全码、设备编号进行MD5加密处理,构成待签名数据 appKey /* NSString *token = [NewUtils sharedInstance].token; NSString *securityCode = [NewUtils sharedInstance].securityCode; NSString *appKey =[NewUtils md5:[NSString stringWithFormat:@"%@%@%@",token,securityCode,deviceNumber]]; [parameters safeSetObject:@"json" forKey:@"format"]; [parameters safeSetObject:VersionNumber forKey:@"v"]; [parameters safeSetObject:[NewUtils get_publicInterface_time] forKey:@"timestamp"]; [parameters safeSetObject:appKey forKey:@"appKey"]; [parameters safeSetObject:securityCode forKey:@"securityCode"]; */ /* //字符串进行UTF-8编码:输出str字符串的UTF-8格式 [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //解码:把str字符串以UTF-8规则进行解码 [str stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; */ NSString *serverUrl = [NSString stringWithFormat:@"%@%@",SERVER_URL,_ifPrefix]; // if ([UserEntity sharedInstance].token.length>0 && ![[UserEntity sharedInstance].token isKindOfClass:[NSNull class]]) { // [parameters safeSetObject:[UserEntity sharedInstance].token forKey:@"token"]; // } //NSLog(@"上传参数: %@",parameters); AFHTTPSessionManager *manager = [self createAFHTTPSessionManager]; [manager GET:serverUrl parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) { //这里面是进度 } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { if ([NewLogSwitch isEqualToString:@"0"] && [SERVER_URL isEqualToString:@"http://192.168.1.109:8080/"]) { /* 这段代码写在AFNetWorking库里 那里面打印不了值 故用NSUserDefaults那边存 这边取 if ([[mutableRequest.URL absoluteString] rangeOfString:@"http://119.23.152.19/mmapp/"].location!=NSNotFound) { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setValue:[mutableRequest.URL absoluteString] forKey:@"NewNetworkRequestLink"]; [defaults synchronize]; } */ NSLog(@"接口链接: %@",[[NSUserDefaults standardUserDefaults] valueForKey:@"NewNetworkRequestLink"]); } if (succeed) { if (responseObject) { //本来AF直接返回的就是NSDictionary了,因为之前写的代码直接是解Data,所以为了兼容转成Data然后使用的时候又转成NSDictionary for (NSDictionary *dic in responseObject[@"error"]) { NSString *currVersion = [NSString getMyApplicationVersion]; NSString *oldVersion = [NewUtils userDefaultsStringKey:NewAPPVersion]; if (oldVersion.length > 0 && [oldVersion isEqualToString:currVersion]) { if ([dic[@"field"] isEqualToString:@"403"]) { [[AppDelegate shareDelegate] forceLogoutLogin]; } }else{ if ([dic[@"field"] isEqualToString:@"403"]) { [[AppDelegate shareDelegate] forceLogoutLogin]; } } } // if ([_ifPrefix isEqualToString:JT_userInfo]) { // //由于APP自动登录慢 只能这么处理~ // [[AppDelegate shareDelegate] forceLogoutLogin]; // } succeed(responseObject); }else{ if (failed) { failed(); } } } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { if (failed) { failed(); } }]; } #pragma mark - Post请求 + (void)requestPostWithInterfacePrefix:(NSString*)_ifPrefix parameters:(id)parameters onSuccess:(ResponseTask)succeed onFailure:(CallbackTask)failed { NSString *serverUrl = [NSString stringWithFormat:@"%@%@",SERVER_URL,_ifPrefix]; // NSString *serverUrl = [NSString stringWithFormat:@"%@%@",@"http://192.168.0.101:8080/mmapp/",_ifPrefix]; //NSLog(@"上传参数: %@",parameters); AFHTTPSessionManager *manager = [self createAFHTTPSessionManager]; [manager POST:serverUrl parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) { //这里面是进度 } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { if ([NewLogSwitch isEqualToString:@"1"] && [SERVER_URL isEqualToString:@"http://uat.jishutao.com/"]) { /* 这段代码写在AFNetWorking库里 那里面打印不了值 故用NSUserDefaults那边存 这边取 if ([[mutableRequest.URL absoluteString] rangeOfString:@"http://119.23.152.19/mmapp/"].location!=NSNotFound) { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setValue:[mutableRequest.URL absoluteString] forKey:@"NewNetworkRequestLink"]; [defaults synchronize]; } */ NSLog(@"接口链接: %@",[[NSUserDefaults standardUserDefaults] valueForKey:@"NewNetworkRequestLink"]); } if (succeed) { if (responseObject) { //本来AF直接返回的就是NSDictionary了,因为之前写的代码直接是解Data,所以为了兼容转成Data然后使用的时候又转成NSDictionary // NSData *responseData = [NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingPrettyPrinted error:nil]; for (NSDictionary *dic in responseObject[@"error"]) { NSString *currVersion = [NSString getMyApplicationVersion]; NSString *oldVersion = [NewUtils userDefaultsStringKey:NewAPPVersion]; if (oldVersion.length > 0 && [oldVersion isEqualToString:currVersion]) { if ([dic[@"field"] isEqualToString:@"403"]) { [[AppDelegate shareDelegate] forceLogoutLogin]; } }else{ if ([dic[@"field"] isEqualToString:@"403"]) { [[AppDelegate shareDelegate] forceLogoutLogin]; } } } succeed(responseObject); }else{ if (failed) { failed(); } } } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { if (failed) { failed(); } }]; } #pragma mark - 设置AFHTTPSessionManager相关属性 + (AFHTTPSessionManager *)createAFHTTPSessionManager { //打开状态栏的等待菊花 [AFNetworkActivityIndicatorManager sharedManager].enabled = YES; AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //设置请求参数的类型:HTTP (AFJSONRequestSerializer,AFHTTPRequestSerializer) manager.requestSerializer = [AFHTTPRequestSerializer serializer]; //设置服务器返回结果的类型:JSON (AFJSONResponseSerializer,AFHTTPResponseSerializer) manager.responseSerializer = [AFJSONResponseSerializer serializer]; //NSURLRequest添加请求头 [manager.requestSerializer setValue:@"AFT" forHTTPHeaderField:@"User-Agent"]; manager.responseSerializer.acceptableContentTypes = [NSSet setWithArray:@[@"application/json", @"text/html", @"text/json", @"text/plain", @"text/javascript", @"text/xml", @"image/*"]]; //设置请求的超时时间 [manager.requestSerializer willChangeValueForKey:@"timeoutInterval"]; manager.requestSerializer.timeoutInterval = 60.f; [manager.requestSerializer didChangeValueForKey:@"timeoutInterval"]; return manager; } #pragma mark - Post请求 Body上传参数 + (void)requestPostWithInterfacePrefix:(NSString*)prefix parameters:(id)parameters bodyParameters:(id)bodyParameters onSuccess:(ResponseTask)succeed onFailure:(CallbackTask)failed { //NSLog(@"上传参数: %@",parameters); NSString *serverUrl = [NSString stringWithFormat:@"%@%@",SERVER_URL,prefix]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:serverUrl parameters:parameters error:nil]; [request setValue:@"AFT" forHTTPHeaderField:@"User-Agent"]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; //设置请求的超时时间 [request willChangeValueForKey:@"timeoutInterval"]; request.timeoutInterval = 60.f; [request didChangeValueForKey:@"timeoutInterval"]; NSError *error = nil; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:bodyParameters options:NSJSONWritingPrettyPrinted error:&error]; NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; NSData* bodyData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; [request setHTTPBody:bodyData]; AFHTTPResponseSerializer *responseSerializer = [AFHTTPResponseSerializer serializer]; responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html", @"text/json", @"text/javascript", @"text/plain", nil]; manager.responseSerializer = responseSerializer; manager.responseSerializer = [AFJSONResponseSerializer serializer];//服务器返回JSON数据 [[manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { // if ([NewLogSwitch isEqualToString:@"1"] && [SERVER_URL isEqualToString:Log_SERVER_URL]) { NSLog(@"POST接口链接: %@",[[NSUserDefaults standardUserDefaults] valueForKey:@"NewNetworkRequestLink"]); // } if (succeed) { if (responseObject) { succeed(responseObject); // if ([responseObject[@"error"] isEqualToString:@"000"]) { // [[AppDelegate shareDelegate] forceLogoutLogin]; // } }else{ if (failed) { failed(); } } } }] resume]; } #pragma mark - Post请求 上传图片 + (void)requestPostWithInterfacePrefix:(NSString*)prefix serverFileName:(NSString *)serverFileName parameters:(id)parameters arrayParameters:(id)arrayParameters imagetype:(NSString *)imagetype onSuccess:(ResponseTask)succeed onFailure:(CallbackTask)failed { NSString *serverUrl = [NSString stringWithFormat:@"%@%@",SERVER_URL,prefix]; //if ([arrayParameters isEqual:[NSArray class]]) {} NSArray *array = [NSArray arrayWithArray:arrayParameters]; AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //设置请求的超时时间 manager.requestSerializer.timeoutInterval = 60.f; //设置请求参数的类型:HTTP (AFJSONRequestSerializer,AFHTTPRequestSerializer) manager.requestSerializer = [AFHTTPRequestSerializer serializer]; //设置服务器返回结果的类型:JSON (AFJSONResponseSerializer,AFHTTPResponseSerializer) manager.responseSerializer = [AFJSONResponseSerializer serializer]; //NSURLRequest添加请求头 [manager.requestSerializer setValue:@"AFT" forHTTPHeaderField:@"User-Agent"]; //设置ContentType manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects: @"text/plain", @"multipart/form-data", @"application/json", @"text/html", @"image/jpeg", @"image/png", @"application/octet-stream", @"text/json", nil]; // 在parameters里存放照片以外的对象 // [parameters safeSetObject:[UserEntity sharedInstance].token forKey:@"token"];//公共参数token [manager POST:serverUrl parameters:parameters constructingBodyWithBlock:^(id _Nonnull formData) { // formData: 专门用于拼接需要上传的数据,在此位置生成一个要上传的数据体 // 这里的_photoArr是你存放图片的数组 for (int i = 0; i < array.count; i++) { NSData *imageData = [NSData dataWithData:array[i]]; // 在网络开发中,上传文件时,是文件不允许被覆盖,文件重名 // 要解决此问题, // 可以在上传时使用当前的系统事件作为文件名 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; // 设置时间格式 [formatter setDateFormat:@"yyyyMMddHHmmss"]; NSString *dateString = [formatter stringFromDate:[NSDate date]]; //拼接图片名称 当前时间+4位随机数 NSString *fileName = [NSString stringWithFormat:@"%@_%@.%@", dateString,[NewUtils randomCount:4],imagetype]; //该方法的参数 //1. appendPartWithFileData:要上传的照片[二进制流] //2. name:对应网站上[upload.php中]处理文件的字段(比如upload) //3. fileName:要保存在服务器上的文件名 //4. mimeType:上传的文件的类型 [formData appendPartWithFileData:imageData name:serverFileName fileName:fileName mimeType:@"image/jpeg"]; // } } progress:^(NSProgress * _Nonnull uploadProgress) { NSLog(@"```上传进度```%f",uploadProgress.fractionCompleted); } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { if (succeed) { if (responseObject) { succeed(responseObject); }else{ if (failed) { failed(); } } } NSLog(@"```上传成功```"); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { if (failed) { failed(); } NSLog(@"```上传失败```"); }]; } @end