Parcourir la source

1.从Apex Drivers中抽取工具类。

Pen Li il y a 7 ans
Parent
commit
15465e4249

+ 30 - 0
common/Network/NetworkUtils.h

@@ -0,0 +1,30 @@
+//
+//  NetworkUtils.h
+//  AntsContract
+//
+//  Created by Ray on 12/26/16.
+//  Copyright © 2016 United Software Applications, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "const.h"
+#import "RAConvertor.h"
+typedef NSMutableDictionary*(^resultBlock)(NSMutableDictionary* result);
+typedef NSMutableDictionary*(^decryptBlock)(NSMutableDictionary* result);
+
+
+typedef void(^resultHandler)(NSMutableDictionary *result);
+typedef void(^progressHandler)(NSURLSessionTask *task,double progress);
+
+@interface NetworkUtils : NSObject
++(bool) IsNetworkAvailable;
++(NSData*)get_json : (NSString*) url parameters:(NSMutableDictionary *) params file:(NSString*)file_path err_recorder:(NSString* )recorder_url result_handler:(resultBlock)resultBlock decrypt_handler:(decryptBlock)decryptBlock;
++(NSDictionary*)err_log:(NSString*) up_params result:(NSString*)result module:(NSString*) module code:(int) code;
+
+
++ (NSURLSessionTask *)upload:(NSString *)filePath Params:(NSDictionary *)params ToHost:(NSString *)url Result:(resultHandler)r Progress:(progressHandler)p DecryptHandler:(id(^)(NSString *result))decrypt;
+
++ (NSURLSessionTask *)upload:(NSData *)filedata  FileName:(NSString*) filename Params:(NSDictionary *)params ToHost:(NSString *)urlString Result:(resultHandler)r Progress:(progressHandler)p DecryptHandler:(id (^)(NSString *))decrypt;
+
++ (NSURLSessionDataTask *)downloadFileOffset:(NSUInteger)offset Param:(NSDictionary *)param from:(NSString *)url method:(NSString *)method toPath:(NSString *)path progressHandler:(progressHandler)progressHandler completionHandler:(resultHandler)result;
+@end

+ 553 - 0
common/Network/NetworkUtils.m

@@ -0,0 +1,553 @@
+//
+//  NetworkUtils.m
+//  AntsContract
+//
+//  Created by Ray on 12/26/16.
+//  Copyright © 2016 United Software Applications, Inc. All rights reserved.
+//
+
+#import "NetworkUtils.h"
+#import "RAUtils.h"
+#import "Reachability.h"
+#import "RANetworkTaskDelegate.h"
+
+
+#define BOUNDARY @"AaB03x"
+
+@implementation NetworkUtils
+
+
+//+(NSDictionary*) error_dict:(NSError*)error
+//{
+//    if(error==nil)
+//        return nil;
+//    NSMutableDictionary* ret = [[NSMutableDictionary alloc] init];
+//    [ret setValue:[NSString stringWithFormat:@"%d",error.code] forKey:@"error_code"];
+//    [ret setValue:error.domain forKey:@"err_domain"];
+//    [ret setValue:[error localizedDescription] forKey:@"err_message"];
+//    // [ret setObject:error.userInfo forKey:@"user_info"];
+//    return ret;
+//}
+
++(bool) IsNetworkAvailable
+{
+    
+    if (([Reachability reachabilityForInternetConnection].currentReachabilityStatus == NotReachable) &&
+        ([Reachability reachabilityForLocalWiFi].currentReachabilityStatus == NotReachable))
+        return false;
+    return true;
+}
+
++(NSData*)get_json : (NSString*) url parameters:(NSMutableDictionary *) params file:(NSString*)file_path err_recorder:(NSString* )recorder_url result_handler:(resultBlock)resultBlock decrypt_handler:(decryptBlock)decryptBlock
+{
+    int retry = 0;
+    
+
+    
+    
+repeat:
+    {
+        
+        //    return [self fake_json:url];
+        
+        //    AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
+        //分界线的标识符
+        NSString *TWITTERFON_FORM_BOUNDARY = @"AaB03x";
+        //根据url初始化request
+        NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]
+                                                               cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
+                                                           timeoutInterval:JSON_TIMEOUT];
+        //分界线 --AaB03x
+        NSString *MPboundary=[[NSString alloc]initWithFormat:@"--%@",TWITTERFON_FORM_BOUNDARY];
+        //结束符 AaB03x--
+        NSString *endMPboundary=[[NSString alloc]initWithFormat:@"%@--",MPboundary];
+        //要上传的图片
+        //    UIImage *image=[params objectForKey:@"pic"];
+        //得到图片的data
+            NSData* data = [NSData dataWithContentsOfFile:file_path];
+        //http body的字符串
+        NSMutableString *body=[[NSMutableString alloc]init];
+        
+        //    NSMutableDictionary* params = [[NSMutableDictionary alloc] init];
+        //     [params setValue:@"handset_login" forKey:@"action"];
+        //    [headers setValue:[NSString stringWithFormat:@"%d",dataLength] forKey:@"Content-Length"];
+        
+        //    [params setValue:appDelegate.sessionid forKey:@"sessionid"];
+        //   [params setValue:password forKey:@"password"];
+        //    [params setValue:[NSString stringWithFormat:@"%d",ver]  forKey:@"auth_ver"];
+        
+        
+        
+        //    [headers setValue:headQuerlString forKey:@"param"];
+        
+        //参数的集合的所有key的集合
+        NSArray *keys= [params allKeys];
+        DebugLog(@"================parms==================");
+        //遍历keys
+        for(int i=0;i<[keys count];i++)
+        {
+            //得到当前key
+            NSString *key=[keys objectAtIndex:i];
+            //如果key不是pic,说明value是字符类型,比如name:Boris
+            if(![key isEqualToString:@"pic"])
+            {
+                //添加分界线,换行
+                [body appendFormat:@"%@\r\n",MPboundary];
+                //添加字段名称,换2行
+                [body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key];
+                //添加字段的值
+                [body appendFormat:@"%@\r\n",[params objectForKey:key]];
+                DebugLog(@"parameter: key=%@   value=%@",key,[params objectForKey:key]);
+            }
+        }
+        DebugLog(@"================parms==================");
+        ////添加分界线,换行
+        [body appendFormat:@"%@\r\n",MPboundary];
+        //声明pic字段,文件名为boris.png
+        
+        NSString * file_format=[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"upfile\"; filename=\"%@\"\r\n", [file_path lastPathComponent]];
+
+        
+        
+        [body appendFormat:@"%@", file_format];
+        //声明上传文件的格式
+        [body appendFormat:@"Content-Type: application/zip\r\n\r\n"];
+        
+        //声明结束符:--AaB03x--
+        NSString *end=[[NSString alloc]initWithFormat:@"\r\n%@",endMPboundary];
+        //声明myRequestData,用来放入http body
+        NSMutableData *myRequestData=[NSMutableData data];
+        //将body字符串转化为UTF8格式的二进制
+        [myRequestData appendData:[body dataUsingEncoding:NSUTF8StringEncoding]];
+        //将image的data加入
+            [myRequestData appendData:data];
+        //加入结束符--AaB03x--
+        [myRequestData appendData:[end dataUsingEncoding:NSUTF8StringEncoding]];
+        
+        //设置HTTPHeader中Content-Type的值
+        NSString *content=[[NSString alloc]initWithFormat:@"multipart/form-data; boundary=%@",TWITTERFON_FORM_BOUNDARY];
+        //设置HTTPHeader
+        [request setValue:content forHTTPHeaderField:@"Content-Type"];
+        
+        [request setValue:@"multipart/form-data" forHTTPHeaderField:@"enctype"];
+        
+        // 关闭keep alive
+        [request setValue:@"close" forHTTPHeaderField:@"Connection"];
+        //设置Content-Length
+        [request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[myRequestData length]] forHTTPHeaderField:@"Content-Length"];
+        //设置http body
+        [request setHTTPBody:myRequestData];
+        //http method
+        [request setHTTPMethod:@"POST"];
+        
+        
+        NSHTTPURLResponse* urlResponse = nil;
+        
+        NSError *error = nil;
+        NSLog(@"begin request %@",url);
+
+        NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&error];
+        
+        
+        DebugLog(@"url: %@",url);
+        
+        DebugLog(@"response: %@",[NSHTTPURLResponse localizedStringForStatusCode:urlResponse.statusCode]);
+        
+        
+        NSLog(@"get response");
+        if (responseData==nil) {
+            
+            //            DebugLog(@"response error:%@", [error localizedDescription]);
+            
+            
+            NSMutableDictionary* ret = [[NSMutableDictionary alloc] init];
+            //#define RESULT_FALSE 0
+            //#define RESULT_TRUE		 2
+            //#define RESULT_NET_ERROR			 -3
+            //#define RESULT_NET_NOTAVAILABLE		  -4
+            //#define RESULT_ERROR				 -5
+            //#define RESULT_LOCALFILE_ERROR			 -7
+            //#define RESULT_USERAUTH_ERROR			 -9
+            //#define RESULT_UPDATE_USERAUTH_ERROR	 -11
+            //#define RESULT_SESSION_EXPIRED			  -13
+            //#define RESULT_VER_LOW
+            
+            //     NSString * moreinfo = error.description ;
+            
+            NSString* err_msg = [error localizedDescription];
+            
+            
+            //-----------------retry 3 times for error code -1005------------------------
+            if(error.code==-1005&&retry<3)
+            {
+                retry++;
+                goto repeat;
+                
+            }
+            //-----------------end retry 3 times for error code -1005------------------------
+            
+            NSDictionary* error_json = [RAUtils error_dict:error];
+            [ret setObject:error_json forKey:@"err_obj"];
+            NSString* resp_msg= nil;
+            
+            if(err_msg.length==0)
+            {
+                err_msg =[NSHTTPURLResponse localizedStringForStatusCode:urlResponse.statusCode];
+                resp_msg = err_msg;
+            }
+            [ret setValue:[NSString stringWithFormat:@"%d",RESULT_NET_ERROR] forKey:@"result"];
+            [ret setValue:err_msg forKey:@"err_msg"];
+            [ret setValue:resp_msg forKey:@"resp_msg"];
+            [ret setValue:[NSString stringWithFormat:@"%ld",(long)urlResponse.statusCode] forKey:@"resp_code"];
+            
+            
+            NSData *jsonData = [NSJSONSerialization dataWithJSONObject:ret
+                                                               options:0
+                                                                 error:nil];
+            if(![url isEqualToString:recorder_url])
+            {
+                [self err_log:[RAUtils base64en:[RAConvertor dict2string:params]] result:[RAUtils base64en:[RAConvertor dict2string:ret]] module:url code:RESULT_NET_ERROR];
+            }
+            return jsonData;
+            
+        }
+        else
+        {
+          //  NSString* err_msg = [error localizedDescription];
+            NSMutableString *str = [[NSMutableString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
+            
+            DebugLog(@"data string: %@",str);
+            NSError *error1 = nil;
+            
+            NSMutableDictionary* jsobj = [[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error1] mutableCopy];
+            
+            if(jsobj==nil)// 服务器返回不是json
+            {
+                
+                jsobj=[[NSMutableDictionary alloc] init];
+                [jsobj setValue:[NSNumber numberWithInt:RESULT_NO_RESPONSE] forKey:@"result"];
+                
+            }
+            if([jsobj[@"encrypt"] boolValue]==true)
+            {
+                jsobj = decryptBlock(jsobj);
+            }
+            if (resultBlock) {
+                jsobj = resultBlock(jsobj);
+            }
+            
+            int result=[[jsobj valueForKey:@"result"] intValue];
+            if(![url isEqualToString:recorder_url]&&/*![url isEqualToString:URL_DOWNLOAD_OFFLINE]&&*/result!=2&&result!=99)
+            {
+                [self err_log:[RAUtils base64en:[RAConvertor dict2string:params]] result:[RAUtils base64en:str] module:url code:result];
+            }
+            NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsobj
+                                                               options:0
+                                                                 error:nil];
+            return jsonData;
+            
+        }
+        return responseData;
+    }
+}
+
++(NSDictionary*)err_log:(NSString*) up_params result:(NSString*)result module:(NSString*) module code:(int) code//device:(NSString*) device
+{
+    //    NSMutableDictionary* params = [[NSMutableDictionary alloc] init];
+    //    AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
+    //    if(appDelegate.user!=nil)
+    //        [params setValue:appDelegate.user forKey:@"user"];
+    //
+    //    [params setValue:up_params forKey:@"upparam"];
+    //
+    //    [params setValue:[NSNumber numberWithInt:code ] forKey:@"code"];
+    //
+    //    [params setValue:result forKey:@"result"];
+    //    [params setValue:module forKey:@"interfac"];
+    //
+    //    [params setValue:[RAUtils base64en:[RAUtils dict2string: [RAUtils device_info]]] forKey:@"device"];
+    //
+    //
+    //    //     [params setValue:module forKey:@"module"];
+    //
+    //    //  [[UIDevice currentDevice]  name];
+    //
+    //    //    if(appDelegate.offline_mode)
+    //    //    {
+    //    //        return [OLDataProvider offline_notimpl];
+    //    //    }
+    //    if(![self IsNetworkAvailable])
+    //        return [RAUtils error_json:RESULT_NET_NOTAVAILABLE err_msg:nil];
+    //
+    //    NSData* json=[self get_json:URL_ERR_LOG parameters:params];
+    //    if(json==nil)
+    //        return nil;
+    //    NSError *error=nil;
+    //    NSDictionary *jsobj = [NSJSONSerialization JSONObjectWithData:json options:NSJSONReadingMutableLeaves error:&error];
+    //    return jsobj;
+    NSMutableDictionary* jsobj = [@{@"result":@"2"} mutableCopy];
+    return jsobj;
+}
++ (NSURLSessionTask *)upload:(NSData *)filedata  FileName:(NSString*) filename Params:(NSDictionary *)params ToHost:(NSString *)urlString Result:(resultHandler)r Progress:(progressHandler)p DecryptHandler:(id (^)(NSString *))decrypt {
+    
+    
+//    NSString *fileName = [filePath lastPathComponent];
+    
+    NSMutableData *dataM = [NSMutableData data];
+    
+    NSMutableString *stringM = [NSMutableString string];
+    
+    
+    DebugLog(@"================parms==================");
+    
+    
+    
+    for (NSString *key in params) {
+        
+        [stringM appendString:[NSString stringWithFormat:@"--%@\r\n",BOUNDARY]];
+        [stringM appendFormat:@"Content-Type: text/plain; charset=UTF-8\r\n"];
+        [stringM appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key];
+        [stringM appendFormat:@"%@\r\n",[params objectForKey:key]];
+        
+        
+        DebugLog(@"parameter: key=%@   value=%@",key,[params objectForKey:key]);
+    }
+    DebugLog(@"================parms==================");
+    // Apex Drivers 2018.5.5
+    if (filedata) {
+        
+        [stringM appendString:[NSString stringWithFormat:@"--%@\r\n",BOUNDARY]];
+        
+        [stringM appendFormat:@"Content-Disposition: form-data; name=\"upfile\"; filename=%@\r\n",filename];
+        [stringM appendString:@"Content-Type: application/mac-binary\r\n"];
+        [stringM appendString:@"\r\n"];
+        
+        NSData *stringM_data = [stringM dataUsingEncoding:NSUTF8StringEncoding];
+        [dataM appendData:stringM_data];
+        
+        //    NSData *file_data = [NSData dataWithContentsOfFile:filePath];
+        [dataM appendData:filedata];
+        
+        NSString *end = [NSString stringWithFormat:@"\r\n--%@--",BOUNDARY];
+        [dataM appendData:[end dataUsingEncoding:NSUTF8StringEncoding]];
+        
+    } else {
+        
+        NSData *stringM_data = [stringM dataUsingEncoding:NSUTF8StringEncoding];
+        [dataM appendData:stringM_data];
+        NSString *end = [NSString stringWithFormat:@"\r\n--%@--",BOUNDARY];
+        [dataM appendData:[end dataUsingEncoding:NSUTF8StringEncoding]];
+    }
+    
+    // Data
+    NSData *data = dataM;
+    
+    
+    // 可变请求
+    NSURL *url = [NSURL URLWithString:urlString];
+    NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:url
+                                                            cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:JSON_TIMEOUT];
+    // line note
+    requestM.HTTPMethod = @"POST";
+    
+    // request header
+    [requestM addValue:@"close" forHTTPHeaderField:@"Connection"];
+    
+    [requestM addValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",BOUNDARY] forHTTPHeaderField:@"Content-Type"];
+    
+    [requestM addValue:@"multipart/form-data" forHTTPHeaderField:@"enctype"];
+    
+    [requestM addValue:[NSString stringWithFormat:@"%lu", (unsigned long)[data length]] forHTTPHeaderField:@"Content-Length"];
+    
+    // request body
+    requestM.HTTPBody = data;
+    
+    
+    
+    NSURLSession *urlSession = [self standSession];
+    
+    if (urlSession.delegate) {
+        if ([urlSession.delegate isKindOfClass:[RANetworkTaskDelegate class]]) {
+            
+            RANetworkTaskDelegate *delegate = (RANetworkTaskDelegate *)urlSession.delegate;
+            
+            if (p) {
+                delegate.p = p;
+            }
+            
+            if (r) {
+                delegate.r = r;
+            }
+            
+            if (decrypt) {
+                delegate.decryptHandler = decrypt;
+            }
+            
+        }
+    }
+    
+    NSURLSessionDataTask *dataTask = [urlSession uploadTaskWithRequest:requestM fromData:data];
+    
+    [dataTask resume];
+    
+    return dataTask;
+}
++ (NSURLSessionTask *)upload:(NSString *)filePath  Params:(NSDictionary *)params ToHost:(NSString *)urlString Result:(resultHandler)r Progress:(progressHandler)p DecryptHandler:(id (^)(NSString *))decrypt {
+    
+    
+    NSString *fileName = [filePath lastPathComponent];
+    
+    
+        NSData *file_data = [NSData dataWithContentsOfFile:filePath];
+    
+    return [self upload:file_data FileName:fileName Params:params ToHost:urlString Result:r Progress:p DecryptHandler:decrypt];
+//
+//    NSMutableData *dataM = [NSMutableData data];
+//
+//    NSMutableString *stringM = [NSMutableString string];
+//
+//
+//    DebugLog(@"================parms==================");
+//
+//
+//
+//    for (NSString *key in params) {
+//
+//        [stringM appendString:[NSString stringWithFormat:@"--%@\r\n",BOUNDARY]];
+//        [stringM appendFormat:@"Content-Type: text/plain; charset=UTF-8\r\n"];
+//        [stringM appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key];
+//        [stringM appendFormat:@"%@\r\n",[params objectForKey:key]];
+//
+//
+//        DebugLog(@"parameter: key=%@   value=%@",key,[params objectForKey:key]);
+//    }
+//    DebugLog(@"================parms==================");
+//    [stringM appendString:[NSString stringWithFormat:@"--%@\r\n",BOUNDARY]];
+//
+//    [stringM appendFormat:@"Content-Disposition: form-data; name=\"upfile\"; filename=%@\r\n",fileName];
+//    [stringM appendString:@"Content-Type: application/mac-binary\r\n"];
+//    [stringM appendString:@"\r\n"];
+//
+//    NSData *stringM_data = [stringM dataUsingEncoding:NSUTF8StringEncoding];
+//    [dataM appendData:stringM_data];
+//
+//    NSData *file_data = [NSData dataWithContentsOfFile:filePath];
+//    [dataM appendData:file_data];
+//
+//    NSString *end = [NSString stringWithFormat:@"\r\n--%@--",BOUNDARY];
+//    [dataM appendData:[end dataUsingEncoding:NSUTF8StringEncoding]];
+//
+//    // Data
+//    NSData *data = dataM;
+//
+//
+//    // 可变请求
+//    NSURL *url = [NSURL URLWithString:urlString];
+//    NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:url
+//                                                            cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:JSON_TIMEOUT];
+//    // line note
+//    requestM.HTTPMethod = @"POST";
+//
+//    // request header
+//    [requestM addValue:@"close" forHTTPHeaderField:@"Connection"];
+//
+//    [requestM addValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",BOUNDARY] forHTTPHeaderField:@"Content-Type"];
+//
+//    [requestM addValue:[NSString stringWithFormat:@"%lu", (unsigned long)[data length]] forHTTPHeaderField:@"Content-Length"];
+//
+//    // request body
+//    requestM.HTTPBody = data;
+//
+//
+//
+//    NSURLSession *urlSession = [self standSession];
+//
+//    if (urlSession.delegate) {
+//        if ([urlSession.delegate isKindOfClass:[RANetworkTaskDelegate class]]) {
+//
+//            RANetworkTaskDelegate *delegate = (RANetworkTaskDelegate *)urlSession.delegate;
+//
+//            if (p) {
+//                delegate.p = p;
+//            }
+//
+//            if (r) {
+//                delegate.r = r;
+//            }
+//
+//            if (decrypt) {
+//                delegate.decryptHandler = decrypt;
+//            }
+//
+//        }
+//    }
+//
+//    NSURLSessionDataTask *dataTask = [urlSession uploadTaskWithRequest:requestM fromData:data];
+//
+//    [dataTask resume];
+//
+//    return dataTask;
+}
+
+
+
+
++ (NSURLSession *)standSession {
+    NSURLSession *session = nil;
+    
+    RANetworkTaskDelegate *delegate = [RANetworkTaskDelegate sharedInstance];
+    
+    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
+    config.timeoutIntervalForRequest = JSON_TIMEOUT;
+    
+    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
+    
+    session = [NSURLSession sessionWithConfiguration:config delegate:delegate delegateQueue:queue];
+    
+    return session;
+}
+
++ (NSURLSessionDataTask *)downloadFileOffset:(NSUInteger)offset Param:(NSDictionary *)param from:(NSString *)url method:(NSString *)method toPath:(NSString *)path progressHandler:(progressHandler)progressHandler completionHandler:(resultHandler)result {
+    
+    NSURLSession *sessoin = [self standSession];
+    
+    RANetworkTaskDelegate *delegate = (RANetworkTaskDelegate *)sessoin.delegate;
+    delegate.downloadTask = YES;
+    delegate.fileCachePath = path;
+    if (progressHandler) {
+        delegate.p = progressHandler;
+    }
+    
+    if (result) {
+        delegate.r = result;
+    }
+    
+    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
+    
+    req.HTTPMethod = method;
+    
+    if (offset > 0) {
+        [req addValue:[NSString stringWithFormat:@"bytes=%ld-",(unsigned long)offset] forHTTPHeaderField:@"Range"];
+    }
+    
+    // 拼接参数
+    if (param && param.allValues.count > 0) {
+        __block NSMutableArray *paramArr = [NSMutableArray array];
+        [param enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
+            [paramArr addObject:[NSString stringWithFormat:@"%@=%@",key,obj]];
+        }];
+        NSString *paramStr = [paramArr componentsJoinedByString:@"&"];
+        
+        req.HTTPBody = [paramStr dataUsingEncoding:NSUTF8StringEncoding];
+    }
+
+    NSURLSessionDataTask *downloadTask = [sessoin dataTaskWithRequest:req];
+    
+    [downloadTask resume];
+        
+    return downloadTask;
+
+    
+}
+
+@end

+ 27 - 0
common/Network/RANetworkTaskDelegate.h

@@ -0,0 +1,27 @@
+//
+//  JKNetworkSessionDelegate.h
+//  Test Upload Progress
+//
+//  Created by Jack on 2017/1/11.
+//  Copyright © 2017年 mini1. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+//#import "JKNetworkResult.h"
+
+typedef void(^resultHandler)(NSMutableDictionary *result);
+typedef void(^progressHandler)(NSURLSessionTask *task,double progress);
+
+
+@interface RANetworkTaskDelegate : NSObject <NSURLSessionDataDelegate>
+
+@property (nonatomic,assign,getter=isDownloadTask) BOOL downloadTask;
+@property (nonatomic,copy) NSString *fileCachePath;
+
+@property (nonatomic,copy) progressHandler p;
+@property (nonatomic,copy) resultHandler r;
+@property (nonatomic,copy) id(^decryptHandler)(NSString *encryptString);
+
++ (instancetype)sharedInstance;
+
+@end

+ 269 - 0
common/Network/RANetworkTaskDelegate.m

@@ -0,0 +1,269 @@
+//
+//  JKNetworkSessionDelegate.m
+//  Test Upload Progress
+//
+//  Created by Jack on 2017/1/11.
+//  Copyright © 2017年 mini1. All rights reserved.
+//
+
+#import "RANetworkTaskDelegate.h"
+
+
+@interface JLFileStream : NSObject
+
+@property (nonatomic,copy) NSString *filePath;
+@property (nonatomic,strong) NSInputStream *inputStream;
+@property (nonatomic,strong) NSOutputStream *outputStream;
+
+@end
+
+@implementation JLFileStream
+
+#pragma mark - life
+
++ (instancetype)jl_fileStreamOfPath:(NSString *)path {
+    
+    JLFileStream *stream = [[JLFileStream alloc] init];
+    stream.filePath = path;
+    
+    return stream;
+}
+
+- (void)setFilePath:(NSString *)filePath {
+    _filePath = filePath;
+    
+    if (!filePath) {
+        return;
+    }
+    
+    if (_outputStream) {
+        [_outputStream close];
+    }
+    
+    _outputStream = [NSOutputStream outputStreamToFileAtPath:self.filePath append:YES];
+    [_outputStream open];
+    
+}
+
+#pragma mark - out put stream
+
+- (void)jl_writeData:(NSData *)data {
+    
+    [self writeData:data toPath:self.filePath];
+    
+}
+
+- (void)writeData:(NSData *)data toPath:(NSString *)path {
+    
+    [self.outputStream write:data.bytes maxLength:data.length];
+    
+}
+
+- (void)jl_closeWriter {
+    
+    [self.outputStream close];
+    
+}
+
+@end
+
+
+@interface RANetworkTaskDelegate ()
+
+@property (nonatomic,strong) NSMutableData *recvData;
+//@property (nonatomic,strong) NSMutableDictionary *result;
+
+@property (nonatomic,strong) JLFileStream *fileStream;
+
+@end
+
+@implementation RANetworkTaskDelegate
+
++ (instancetype)sharedInstance {
+    RANetworkTaskDelegate *obj = nil;
+    obj = [[RANetworkTaskDelegate alloc] init];
+    obj.recvData = [NSMutableData data];
+//    obj.result = [[JKNetworkResult alloc] init];
+    printf("new network delegate\n");
+    return obj;
+}
+
+#pragma mark - NSURLSessionTaskDelegate
+
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend {
+    
+    double progress = (double)totalBytesSent / totalBytesExpectedToSend;
+    
+    if (self.p) {
+        self.p(task,progress);
+    }
+}
+
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
+    
+//    if (self.decryptHandler) {
+//        
+//        self.result.decryptHandler = self.decryptHandler;
+//        
+//    }
+//    
+//    if (error) {
+//
+//        self.result.error = error;
+//        
+//        NSLog(@"Delegate recv Error: %@",error.localizedDescription);
+//        
+//    }
+//        
+//    self.result.data = self.recvData;
+//
+//    NSLog(@"Delegate recv data %@",self.recvData);
+//    
+//
+//
+    
+    if (self.isDownloadTask) {
+        
+        [self.fileStream jl_closeWriter];
+        
+        if (error) {
+            if (error.code != -999) {
+                if (self.r) {
+                    
+                    NSMutableDictionary *resutlDic = [@{
+                                                        @"result" : @0,
+                                                        @"msg"    : error.localizedDescription
+                                                        } mutableCopy];
+                    self.r(resutlDic);
+                }
+            } else {
+                
+                NSLog(@"download task canceled");
+                
+            }
+            
+            // 失败删除文件
+            BOOL isDir = NO;
+            if ([[NSFileManager defaultManager] fileExistsAtPath:self.fileCachePath isDirectory:&isDir]) {
+                
+                if (!isDir) {
+                    [[NSFileManager defaultManager] removeItemAtPath:self.fileCachePath error:nil];
+                }
+                
+            }
+            
+        } else {
+            if (self.r) {
+                
+                NSMutableDictionary *resutlDic = [@{
+                                                    @"result" : @2,
+                                                    @"path"   : self.fileCachePath,
+                                                    @"msg"    : @"download complete"
+                                                    } mutableCopy];
+                self.r(resutlDic);
+            }
+        }
+    } else {
+        
+        if (self.r) {
+            
+            
+            if(self.recvData==nil)
+            {
+                self.r(nil);
+                return;
+                
+            }
+            
+            NSMutableString *str = [[NSMutableString alloc] initWithData:self.recvData encoding:NSUTF8StringEncoding];
+            
+            NSLog(@"data string: %@",str);
+            
+            NSError *error1=nil;
+            NSDictionary *jsobj = [NSJSONSerialization JSONObjectWithData:self.recvData options:NSJSONReadingMutableLeaves error:&error1];
+            if(jsobj==nil)// 服务器返回不是json
+            {
+                
+                jsobj=[NSMutableDictionary new];
+                [jsobj setValue:@"-30" forKey:@"result"];
+                [jsobj setValue:@"Can not upload to server, please contact administrator." forKey:@"msg"];
+                
+                
+                
+            }
+            
+            self.r([jsobj mutableCopy]);
+            
+        }
+    }
+
+    printf("net work complete\n");
+    
+//
+    [session invalidateAndCancel];
+}
+
+#pragma mark - NSURLSessionDataDelegate
+
+- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
+    
+    NSLog(@"Delegate recv response: %@",response);
+    
+    if (self.isDownloadTask) {
+        
+        // 文件保存地址
+        if (!self.fileCachePath) {
+            self.fileCachePath = NSTemporaryDirectory();
+        }
+        NSString *desPath = self.fileCachePath;
+        NSError *err;
+        BOOL isDir = NO;
+        [[NSFileManager defaultManager] fileExistsAtPath:desPath isDirectory:&isDir];
+        if (isDir) {
+            if (response.suggestedFilename) {
+                desPath = [self.fileCachePath stringByAppendingPathComponent:response.suggestedFilename];
+            } else {
+                desPath = [self.fileCachePath stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
+            }
+        }
+        
+        // 如果文件存在
+        if ([[NSFileManager defaultManager] fileExistsAtPath:desPath]) {
+            
+            [[NSFileManager defaultManager] removeItemAtPath:desPath error:&err];
+            if (err) {
+                completionHandler(NSURLSessionResponseCancel);
+                return;
+            }
+        }
+        
+        self.fileCachePath = desPath;
+        
+        self.fileStream = [JLFileStream jl_fileStreamOfPath:self.fileCachePath];
+    }
+    
+//    self.result.response = response;
+    completionHandler(NSURLSessionResponseAllow);
+    
+}
+
+- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
+    
+    if (!self.isDownloadTask) {
+        [self.recvData appendData:data];
+    } else {
+        
+        
+        if (self.p) {
+            int64_t totalExpectedRevc = [dataTask countOfBytesExpectedToReceive];
+            int64_t totalRevc = [dataTask countOfBytesReceived];
+            double progress = (double)totalRevc / totalExpectedRevc;
+            self.p(dataTask,progress);
+        }
+        
+        [self.fileStream jl_writeData:data];
+
+    }
+}
+
+@end

+ 21 - 0
common/Network/RAReachability.h

@@ -0,0 +1,21 @@
+//
+//  RAReachability.h
+//  Apex And Drivers
+//
+//  Created by Jack on 2018/10/23.
+//  Copyright © 2018年 USAI. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface RAReachability : NSObject
+
++ (instancetype)defaultReachability;
+- (void)startNotifier:(void(^)(BOOL reachable))reachableBlk;
+- (void)stopNotifier;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 127 - 0
common/Network/RAReachability.m

@@ -0,0 +1,127 @@
+//
+//  RAReachability.m
+//  Apex And Drivers
+//
+//  Created by Jack on 2018/10/23.
+//  Copyright © 2018年 USAI. All rights reserved.
+//
+
+#import "RAReachability.h"
+#import "Reachability.h"
+
+#define host @"https://ra.apexshipping.com"
+
+@interface RAReachability ()
+
+@property (nonatomic,copy) void(^ReachabilityBlk)(BOOL);
+
+@end
+
+@implementation RAReachability {
+    Reachability *_hostReachability; ///< 服务器可达
+    Reachability *_connectionReachability; ///< 本机网络状态
+}
+
++ (instancetype)defaultReachability {
+    static RAReachability *reachability;
+    static dispatch_once_t token;
+    dispatch_once(&token, ^{
+        reachability = [[RAReachability alloc] _init];
+    });
+    return reachability;
+}
+
+- (instancetype)_init {
+    if (self = [super init]) {
+        self->_hostReachability = [Reachability reachabilityWithHostName:host];
+        self->_connectionReachability = [Reachability reachabilityForInternetConnection];
+        
+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityConnectionChanged:) name:kReachabilityChangedNotification object:nil];
+    }
+    return self;
+}
+
+- (void)dealloc {
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+- (void)startNotifier:(void(^)(BOOL reachable))reachableBlk {
+    
+    self.ReachabilityBlk = reachableBlk;
+    
+    dispatch_async(dispatch_get_global_queue(0, 0), ^{
+        
+        [self->_hostReachability startNotifier];
+        [self->_connectionReachability startNotifier];
+        
+        [[NSRunLoop currentRunLoop] run];
+    });
+}
+
+- (void)stopNotifier {
+    self.ReachabilityBlk = nil;
+    [self->_hostReachability stopNotifier];
+    [self->_connectionReachability stopNotifier];
+}
+
+- (void)reachabilityConnectionChanged:(NSNotification *)notification {
+    
+    Reachability *reachability = [notification object];
+    if ([reachability isMemberOfClass:[Reachability class]]) {
+        
+        NetworkStatus status = reachability.currentReachabilityStatus;
+        
+        dispatch_async(dispatch_get_main_queue(), ^{
+            
+            if (reachability == self->_hostReachability) {
+                
+                switch (status) {
+                    case NotReachable: {
+                        if (self.ReachabilityBlk) {
+                            self.ReachabilityBlk(false);
+                        }
+                    }
+                        break;
+                    case ReachableViaWiFi: {
+                        if (self.ReachabilityBlk) {
+                            self.ReachabilityBlk(true);
+                        }
+                    }
+                        break;
+                    case ReachableViaWWAN: {
+                        if (self.ReachabilityBlk) {
+                            self.ReachabilityBlk(true);
+                        }
+                    }
+                        break;
+                        
+                    default:
+                        break;
+                }
+                
+            }
+            else if (reachability == self->_connectionReachability) {
+                
+                switch (status) {
+                    case NotReachable: {
+                        if (self.ReachabilityBlk) {
+                            self.ReachabilityBlk(false);
+                        }
+                    }
+                        break;
+                        
+                    default: {
+                        if (self.ReachabilityBlk) {
+                            self.ReachabilityBlk(true);
+                        }
+                    }
+                        break;
+                }
+            }
+            
+        });
+        
+    }
+}
+
+@end

+ 100 - 0
common/Network/Reachability.h

@@ -0,0 +1,100 @@
+/*
+     File: Reachability.h
+ Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
+  Version: 3.5
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+ 
+ */
+
+#import <Foundation/Foundation.h>
+#import <SystemConfiguration/SystemConfiguration.h>
+#import <netinet/in.h>
+
+
+typedef enum : NSInteger {
+	NotReachable = 0,
+	ReachableViaWiFi,
+	ReachableViaWWAN
+} NetworkStatus;
+
+
+extern NSString *kReachabilityChangedNotification;
+
+
+@interface Reachability : NSObject
+
+/*!
+ * Use to check the reachability of a given host name.
+ */
++ (instancetype)reachabilityWithHostName:(NSString *)hostName;
+
+/*!
+ * Use to check the reachability of a given IP address.
+ */
++ (instancetype)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress;
+
+/*!
+ * Checks whether the default route is available. Should be used by applications that do not connect to a particular host.
+ */
++ (instancetype)reachabilityForInternetConnection;
+
+/*!
+ * Checks whether a local WiFi connection is available.
+ */
++ (instancetype)reachabilityForLocalWiFi;
+
+/*!
+ * Start listening for reachability notifications on the current run loop.
+ */
+- (BOOL)startNotifier;
+- (void)stopNotifier;
+
+- (NetworkStatus)currentReachabilityStatus;
+
+/*!
+ * WWAN may be available, but not active until a connection has been established. WiFi may require a connection for VPN on Demand.
+ */
+- (BOOL)connectionRequired;
+
+@end
+
+

+ 314 - 0
common/Network/Reachability.m

@@ -0,0 +1,314 @@
+/*
+     File: Reachability.m
+ Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
+  Version: 3.5
+ 
+ Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms.  If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+ 
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple.  Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+ 
+ The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ 
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ 
+ Copyright (C) 2014 Apple Inc. All Rights Reserved.
+ 
+ */
+
+ 
+
+
+#import <arpa/inet.h>
+#import <ifaddrs.h>
+#import <netdb.h>
+#import <sys/socket.h>
+
+#import <CoreFoundation/CoreFoundation.h>
+
+#import "Reachability.h"
+
+
+NSString *kReachabilityChangedNotification = @"kNetworkReachabilityChangedNotification";
+
+
+#pragma mark - Supporting functions
+
+#define kShouldPrintReachabilityFlags 1
+
+static void PrintReachabilityFlags(SCNetworkReachabilityFlags flags, const char* comment)
+{
+#if kShouldPrintReachabilityFlags
+
+    NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n",
+          (flags & kSCNetworkReachabilityFlagsIsWWAN)				? 'W' : '-',
+          (flags & kSCNetworkReachabilityFlagsReachable)            ? 'R' : '-',
+
+          (flags & kSCNetworkReachabilityFlagsTransientConnection)  ? 't' : '-',
+          (flags & kSCNetworkReachabilityFlagsConnectionRequired)   ? 'c' : '-',
+          (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic)  ? 'C' : '-',
+          (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
+          (flags & kSCNetworkReachabilityFlagsConnectionOnDemand)   ? 'D' : '-',
+          (flags & kSCNetworkReachabilityFlagsIsLocalAddress)       ? 'l' : '-',
+          (flags & kSCNetworkReachabilityFlagsIsDirect)             ? 'd' : '-',
+          comment
+          );
+#endif
+}
+
+
+static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
+{
+#pragma unused (target, flags)
+	NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback");
+	NSCAssert([(__bridge NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback");
+
+    Reachability* noteObject = (__bridge Reachability *)info;
+    // Post a notification to notify the client that the network reachability changed.
+    [[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject];
+}
+
+
+#pragma mark - Reachability implementation
+
+@implementation Reachability
+{
+	BOOL _alwaysReturnLocalWiFiStatus; //default is NO
+	SCNetworkReachabilityRef _reachabilityRef;
+}
+
++ (instancetype)reachabilityWithHostName:(NSString *)hostName
+{
+	Reachability* returnValue = NULL;
+	SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
+	if (reachability != NULL)
+	{
+		returnValue= [[self alloc] init];
+		if (returnValue != NULL)
+		{
+			returnValue->_reachabilityRef = reachability;
+			returnValue->_alwaysReturnLocalWiFiStatus = NO;
+		}
+	}
+	return returnValue;
+}
+
+
++ (instancetype)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress
+{
+	SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)hostAddress);
+
+	Reachability* returnValue = NULL;
+
+	if (reachability != NULL)
+	{
+		returnValue = [[self alloc] init];
+		if (returnValue != NULL)
+		{
+			returnValue->_reachabilityRef = reachability;
+			returnValue->_alwaysReturnLocalWiFiStatus = NO;
+		}
+	}
+	return returnValue;
+}
+
+
+
++ (instancetype)reachabilityForInternetConnection
+{
+	struct sockaddr_in zeroAddress;
+	bzero(&zeroAddress, sizeof(zeroAddress));
+	zeroAddress.sin_len = sizeof(zeroAddress);
+	zeroAddress.sin_family = AF_INET;
+    
+	return [self reachabilityWithAddress:&zeroAddress];
+}
+
+
++ (instancetype)reachabilityForLocalWiFi
+{
+	struct sockaddr_in localWifiAddress;
+	bzero(&localWifiAddress, sizeof(localWifiAddress));
+	localWifiAddress.sin_len = sizeof(localWifiAddress);
+	localWifiAddress.sin_family = AF_INET;
+
+	// IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0.
+	localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
+
+	Reachability* returnValue = [self reachabilityWithAddress: &localWifiAddress];
+	if (returnValue != NULL)
+	{
+		returnValue->_alwaysReturnLocalWiFiStatus = YES;
+	}
+    
+	return returnValue;
+}
+
+
+#pragma mark - Start and stop notifier
+
+- (BOOL)startNotifier
+{
+	BOOL returnValue = NO;
+	SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};
+
+	if (SCNetworkReachabilitySetCallback(_reachabilityRef, ReachabilityCallback, &context))
+	{
+		if (SCNetworkReachabilityScheduleWithRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode))
+		{
+			returnValue = YES;
+		}
+	}
+    
+	return returnValue;
+}
+
+
+- (void)stopNotifier
+{
+	if (_reachabilityRef != NULL)
+	{
+		SCNetworkReachabilityUnscheduleFromRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+	}
+}
+
+
+- (void)dealloc
+{
+	[self stopNotifier];
+	if (_reachabilityRef != NULL)
+	{
+		CFRelease(_reachabilityRef);
+	}
+}
+
+
+#pragma mark - Network Flag Handling
+
+- (NetworkStatus)localWiFiStatusForFlags:(SCNetworkReachabilityFlags)flags
+{
+	PrintReachabilityFlags(flags, "localWiFiStatusForFlags");
+	NetworkStatus returnValue = NotReachable;
+
+	if ((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect))
+	{
+		returnValue = ReachableViaWiFi;
+	}
+    
+	return returnValue;
+}
+
+
+- (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags
+{
+	PrintReachabilityFlags(flags, "networkStatusForFlags");
+	if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
+	{
+		// The target host is not reachable.
+		return NotReachable;
+	}
+
+    NetworkStatus returnValue = NotReachable;
+
+	if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
+	{
+		/*
+         If the target host is reachable and no connection is required then we'll assume (for now) that you're on Wi-Fi...
+         */
+		returnValue = ReachableViaWiFi;
+	}
+
+	if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
+        (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
+	{
+        /*
+         ... and the connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs...
+         */
+
+        if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
+        {
+            /*
+             ... and no [user] intervention is needed...
+             */
+            returnValue = ReachableViaWiFi;
+        }
+    }
+
+	if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
+	{
+		/*
+         ... but WWAN connections are OK if the calling application is using the CFNetwork APIs.
+         */
+		returnValue = ReachableViaWWAN;
+	}
+    
+	return returnValue;
+}
+
+
+- (BOOL)connectionRequired
+{
+	NSAssert(_reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef");
+	SCNetworkReachabilityFlags flags;
+
+	if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags))
+	{
+		return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
+	}
+
+    return NO;
+}
+
+
+- (NetworkStatus)currentReachabilityStatus
+{
+	NSAssert(_reachabilityRef != NULL, @"currentNetworkStatus called with NULL SCNetworkReachabilityRef");
+	NetworkStatus returnValue = NotReachable;
+	SCNetworkReachabilityFlags flags;
+    
+	if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags))
+	{
+		if (_alwaysReturnLocalWiFiStatus)
+		{
+			returnValue = [self localWiFiStatusForFlags:flags];
+		}
+		else
+		{
+			returnValue = [self networkStatusForFlags:flags];
+		}
+	}
+    
+	return returnValue;
+}
+
+
+@end

+ 16 - 0
common/QuickLook/RAPreviewController.h

@@ -0,0 +1,16 @@
+//
+//  RAPreviewController.h
+//  APEX CRM
+//
+//  Created by Jack on 2018/11/27.
+//  Copyright © 2018年 USAI. All rights reserved.
+//
+
+#import <QuickLook/QuickLook.h>
+
+@interface RAPreviewController : QLPreviewController
+
++ (instancetype)ra_previewControllerWithURL:(NSURL *)url;
+
+@end
+

+ 53 - 0
common/QuickLook/RAPreviewController.m

@@ -0,0 +1,53 @@
+//
+//  RAPreviewController.m
+//  APEX CRM
+//
+//  Created by Jack on 2018/11/27.
+//  Copyright © 2018年 USAI. All rights reserved.
+//
+
+#import "RAPreviewController.h"
+
+@interface RAPreviewController () <QLPreviewControllerDataSource, QLPreviewControllerDelegate>
+
+@property (nonatomic,strong) NSURL *url;
+
+@end
+
+@implementation RAPreviewController
+
++ (instancetype)ra_previewControllerWithURL:(NSURL *)url {
+    RAPreviewController *vc = [[RAPreviewController alloc] init];
+    vc.dataSource = vc;
+    vc.delegate = vc;
+    vc.url = url;
+    return vc;
+}
+
+#pragma mark - QuickLook Data Source
+
+- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller {
+    return 1;
+}
+
+- (id <QLPreviewItem>) previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index {
+    
+    if(self.url==nil)
+        return nil;
+    return self.url;
+}
+
+#pragma mark - QuickLook Delegate
+
+- (void) previewControllerDidDismiss:(QLPreviewController *)controller {
+    
+}
+
+/**
+ * 文件内部链接点击不进行外部跳转
+ */
+- (BOOL) previewController:(QLPreviewController *)controller shouldOpenURL:(NSURL *)url forPreviewItem:(id<QLPreviewItem>)item {
+    return NO;
+}
+
+@end

+ 20 - 0
common/Share/LPShareActivity.h

@@ -0,0 +1,20 @@
+//
+//  LPShareViewController.h
+//  ShareDemo
+//
+//  Created by Jack on 2018/3/5.
+//  Copyright © 2018年 Jack. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import <MessageUI/MessageUI.h>
+@interface LPShareActivity : UIActivity<MFMailComposeViewControllerDelegate>
+
+@property (nonatomic,strong) NSArray *to;
+@property (nonatomic,copy) NSString *subject;
+@property (nonatomic,copy) NSString *filePath;
+@property (nonatomic,copy) NSString *body;
+
+@property (nonatomic,copy) void(^handle)(UIViewController *vc);
+
+@end

+ 189 - 0
common/Share/LPShareActivity.m

@@ -0,0 +1,189 @@
+//
+//  LPShareViewController.m
+//  ShareDemo
+//
+//  Created by Jack on 2018/3/5.
+//  Copyright © 2018年 Jack. All rights reserved.
+//
+
+#import "LPShareActivity.h"
+#import <MessageUI/MessageUI.h>
+
+NSString *const LPActivityType = @"com.emerys.www.share.activity";
+
+@interface LPShareActivity ()
+
+@end
+
+@implementation LPShareActivity
+
+/**
+ *  标示自定义服务的字符串
+ */
+- (NSString *)activityType {
+    
+    // 这里就迎合苹果官方的命名
+    return LPActivityType;
+}
+
+
+/**
+ *  服务的显示内容
+ */
+- (NSString *)activityTitle {
+    return @"Email";
+}
+
+/**
+ *  服务显示图标
+ */
+- (UIImage *)activityImage {
+    
+    // Note: These images need to have a transparent background and I recommend these sizes:
+    // iPadShare@2x should be 126 px, iPadShare should be 53 px, iPhoneShare@2x should be 100
+    // px, and iPhoneShare should be 50 px. I found these sizes to work for what I was making.
+    
+//    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
+//    {
+//        return [UIImage imageNamed:@"iPadShare.png"];
+//    }
+//    else
+//    {
+//        return [UIImage imageNamed:@"iPhoneShare.png"];
+//    }
+    return [UIImage imageNamed:@"ic_email"];
+}
+
+
+/**
+ *  指定空运处理的数据类型,如果可以则返回YES
+ *  当用户选择展示UIActivityViewController的自定义服务时,在调用相应处理方法之前的准备工作都在该方法中执行
+ */
+- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems {
+    return YES;
+}
+
+/**
+ *  UIActivityCategoryAction:表示在UIActivityViewController最下面一栏的操作型服务
+ *  UIActivityCategoryShare:表示在UIActivityViewController中间一栏的分享型服务(社交分享)
+ */
++ (UIActivityCategory)activityCategory {
+    return UIActivityCategoryShare;
+}
+
+- (UIViewController *)activityViewController
+{
+//    return nil;
+    NSLog(@"选中了自定义服务");
+    
+    MFMailComposeViewController *mailComposeViewController = [[MFMailComposeViewController alloc] init];
+    
+    [mailComposeViewController setToRecipients:self.to];
+    [mailComposeViewController setSubject:self.subject];
+    [mailComposeViewController setMessageBody:[NSString stringWithFormat:@"<html><p>%@</p></html>",self.body] isHTML:YES];
+    
+    if (self.filePath.length) {
+        NSData *data = [NSData dataWithContentsOfFile:self.filePath];
+        NSString *fileName = [[self.filePath stringByDeletingPathExtension] lastPathComponent];
+        [mailComposeViewController addAttachmentData:data mimeType:@"application/pdf" fileName:fileName];
+    }
+    
+    mailComposeViewController.mailComposeDelegate = self;
+//    [self activityDidFinish:YES];
+    return mailComposeViewController;
+//    if (_handle) {
+//        _handle(mailComposeViewController);
+//    }
+}
+#pragma mark -MFMailComposeViewControllerDelegate delegate
+
+- (void)mailComposeController:(MFMailComposeViewController*)controller
+          didFinishWithResult:(MFMailComposeResult)result
+                        error:(NSError*)error {
+    switch (result)
+    {
+        case MFMailComposeResultCancelled:
+            NSLog(@"Mail send canceled...");
+            break;
+        case MFMailComposeResultSaved:
+            NSLog(@"Mail saved...");
+            break;
+        case MFMailComposeResultSent:
+            NSLog(@"Mail sent...");
+            break;
+        case MFMailComposeResultFailed:
+            NSLog(@"Mail send errored: %@...", [error localizedDescription]);
+            break;
+        default:
+            break;
+    }
+//    [self dismissModalViewControllerAnimated:YES];
+    [self activityDidFinish:YES];
+}
+/**
+ *  点击自定义服务之后的操作
+ */
+- (void)performActivity {
+//
+//    MFMailComposeViewController *mailComposer = [MFMailComposeViewController new];
+//
+//    [mailComposer setToRecipients:self.to];
+//    [mailComposer setSubject:self.subject];
+//    [mailComposer setMessageBody:[NSString stringWithFormat:@"<html><p>%@</p></html>",self.body] isHTML:YES];
+//
+//    if (self.filePath.length) {
+//        NSData *data = [NSData dataWithContentsOfFile:self.filePath];
+//        NSString *fileName = [[self.filePath stringByDeletingPathExtension] lastPathComponent];
+//        [mailComposer addAttachmentData:data mimeType:@"application/pdf" fileName:fileName];
+//    }
+//
+//    mailComposer.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
+//
+//    mailComposer.modalPresentationStyle = UIModalPresentationFormSheet;
+//
+//    AppDelegate *delagate =(AppDelegate *) [[UIApplication sharedApplication]delegate];
+//
+//    mailComposer.mailComposeDelegate = [[(UINavigationController *)delagate.window.rootViewController viewControllers] lastObject]; // Set the delegate
+//
+//
+//    [(UIViewController *)[[(UINavigationController *)delagate.window.rootViewController viewControllers] lastObject] presentViewController:mailComposer animated:YES completion:nil];
+//
+////    NSLog(@"选中了自定义服务");
+////
+////    MFMailComposeViewController *mailComposeViewController = [[MFMailComposeViewController alloc] init];
+////
+////    [mailComposeViewController setToRecipients:self.to];
+////    [mailComposeViewController setSubject:self.subject];
+////    [mailComposeViewController setMessageBody:[NSString stringWithFormat:@"<html><p>%@</p></html>",self.body] isHTML:YES];
+////
+////    if (self.filePath.length) {
+////        NSData *data = [NSData dataWithContentsOfFile:self.filePath];
+////        NSString *fileName = [[self.filePath stringByDeletingPathExtension] lastPathComponent];
+////        [mailComposeViewController addAttachmentData:data mimeType:@"application/pdf" fileName:fileName];
+////    }
+//    [self activityDidFinish:YES];
+//////    return mailComposeViewController;
+////        if (_handle) {
+////            _handle(mailComposeViewController);
+////        }
+}
+
+- (void)setTo:(NSArray *)to {
+    _to = to;
+}
+
+- (void)setSubject:(NSString *)subject {
+    if (subject == nil) {
+        subject = @"";
+    }
+    _subject = subject;
+}
+
+- (void)setBody:(NSString *)body {
+    if (body == nil) {
+        body = @"";
+    }
+    _body = body;
+}
+
+@end

+ 14 - 0
common/Share/RAShareItemProvider.h

@@ -0,0 +1,14 @@
+//
+//  EmailItemProvider.h
+//  Apex Mobile
+//
+//  Created by Ray on 05/03/2018.
+//  Copyright © 2018 United Software Applications, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface RAShareItemProvider : NSObject <UIActivityItemSource>
+@property (nonatomic, strong) NSString *subject;
+@property (nonatomic, strong) NSString *body;
+@end

+ 54 - 0
common/Share/RAShareItemProvider.m

@@ -0,0 +1,54 @@
+//
+//  EmailItemProvider.m
+//  Apex Mobile
+//
+//  Created by Ray on 05/03/2018.
+//  Copyright © 2018 United Software Applications, Inc. All rights reserved.
+//
+
+#import "RAShareItemProvider.h"
+
+@implementation RAShareItemProvider
+- (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController {
+//    NSLog(@"activityViewControllerPlaceholderItem %@",activityType);
+    return _body;
+}
+
+- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType {
+    if([activityType isEqualToString:@"com.tencent.xin.sharetimeline"])
+    {
+        if (self.body) {
+            
+            
+            NSString* fname = self.subject;
+            if(fname.length==0)
+                fname=[[NSUUID UUID ] UUIDString];
+            NSString* tempDir = NSTemporaryDirectory();
+            
+            NSString *saveFileName=[NSString stringWithFormat:@"%@.txt",fname ] ;
+            NSString *newFilePath=[tempDir stringByAppendingPathComponent:saveFileName];
+            bool success=[_body writeToFile:newFilePath atomically:true encoding:NSUTF8StringEncoding error:nil];
+            
+            if(success)
+            {
+//                UIImage *imageToShare = [UIImage imageNamed:@"AppIcon"];
+                NSURL *urlToShare = [NSURL fileURLWithPath:newFilePath];
+                return urlToShare;
+//                activityItems = @[subject,urlToShare];
+            }
+            //        activityItems = @[content];
+        }
+    }
+    NSLog(@"itemForActivityType %@",activityType);
+    return _body;
+}
+
+- (NSString *)activityViewController:(UIActivityViewController *)activityViewController subjectForActivityType:(NSString *)activityType {
+    NSLog(@"subjectForActivityType %@",activityType);
+    return _subject;
+}
+//- (NSString *)activityViewController:(UIActivityViewController *)activityViewController dataTypeIdentifierForActivityType:(UIActivityType)activityType;
+//{
+//    
+//}
+@end