一个完整的自动化工具,自动提单是非常重要的一环,bug单可以作为衡量自动化工具的产出指标,可以直接说明该自动化工具的价值。而提单离不开文件上传,接下来详细介绍一下ios的文件上传。
ios文件上传可以通过NSURLConnection、NSURLSession、AFN等方式上传,因为不想依赖于第三方框架,我这里选用了NSURLConnection
1、文件上传设置请求体的数据格式:
//请求体拼接格式//分隔符:----WebKitFormBoundaryhBDKBUWBHnAgvz9c//01.文件参数拼接格式--分隔符Content-Disposition:参数Content-Type:参数空行文件参数//02.非文件拼接参数--分隔符Content-Disposition:参数空行非文件的二进制数据//03.结尾标识--分隔符--
2、NSURLConnection的方式
举一个具体的例子,表单有两个参数,file_name和file_path,file_name表示文件的名字,file_path表示文件的内容,上传的表单格式如下:
在ios中的拼接格式如下:
/*1. 设置请求头Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryOhB08CzI96Eux6PO2. 按照固定的格式拼接请求体的数据------WebKitFormBoundaryOhB08CzI96Eux6POContent-Disposition: form-data; name="file_path"; filename="xx.zip"Content-Type: application/octet-stream空行文件参数------WebKitFormBoundaryOhB08CzI96Eux6POContent-Disposition: form-data; name="file_name"空行xx.zip------WebKitFormBoundaryOhB08CzI96Eux6PO--*/3.结尾表示--分隔符--*/
3、具体代码如下
-(void)uploadBugWithURL:(NSURL*_Nullable)furl complete:(UploadBugBoolBlock _Nullable)complete synchronous:(BOOL)synchronous{NSString *filename = [furl lastPathComponent] ;//1. 确定请求路径NSURL *url = [NSURL URLWithString:@"/bugs/api/upload_file/"];//2. 创建可变的请求对象NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:url];//3. 设置请求方法requestM.HTTPMethod = @"POST";//4. 设置请求头信息//Authorization:Token 123456789\r\n;[requestM setValue:[NSString stringWithFormat:@"Token 123456789\r\n" ] forHTTPHeaderField:@"Authorization"];//Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryOhB08CzI96Eux6PO[requestM setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"];//5. 设置请求体数据NSMutableData *fileData = [NSMutableData data];//5.1 文件参数/*--分隔符Content-Disposition: form-data; name="file_path"; filename="xx.zip"Content-Type: application/octet-stream空行文件参数*/[fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];// 拼接换行[fileData appendData:KNewLine];//name:file_path 服务器规定的参数//filename:xx.zip 文件保存到服务器上面的名称//Content-Type:文件的类型[fileData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file_path\"; filename=\"%@\"",filename] dataUsingEncoding:NSUTF8StringEncoding]];[fileData appendData:KNewLine];[fileData appendData:[@"Content-Type: application/octet-stream" dataUsingEncoding:NSUTF8StringEncoding]];[fileData appendData:KNewLine];[fileData appendData:KNewLine];//文件数据部分// NSURL --> NSDataNSData *uploadData = [NSData dataWithContentsOfURL:furl];[fileData appendData:uploadData];[fileData appendData:KNewLine];//5.2 非文件参数/*--分隔符Content-Disposition: form-data; name="file_name"空行xx.zip*/[fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];[fileData appendData:KNewLine];[fileData appendData:[@"Content-Disposition: form-data; name=\"file_name\"" dataUsingEncoding:NSUTF8StringEncoding]];[fileData appendData:KNewLine];[fileData appendData:KNewLine];[fileData appendData:[filename dataUsingEncoding:NSUTF8StringEncoding]];[fileData appendData:KNewLine];//5.3 结尾标识/*--分隔符--*/[fileData appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];//6. 设置请求体requestM.HTTPBody = fileData;//7. 发送请求if(synchronous){//同步请求BOOL isMock = [[LLDebugTool sharedTool] mockSwitch] ;if(isMock){[[LLMockHelper sharedHelper] stopMock] ;}NSData *data= [NSURLConnection sendSynchronousRequest:requestM returningResponse:nil error:nil] ;NSString *result = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding] ;NSLog(@"haleli >>> %@",result);NSDictionary *dict = [LLTool dictWithJsonString:result] ;NSNumber *ret = [dict objectForKey:@"success"] ;[self performBoolComplete:complete ret:ret filePath:furl.path] ;if(isMock){[[LLMockHelper sharedHelper] startMock] ;}}else{//异步请求BOOL isMock = [[LLDebugTool sharedTool] mockSwitch] ;if(isMock){[[LLMockHelper sharedHelper] stopMock] ;}[NSURLConnection sendAsynchronousRequest:requestM queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {//8.解析数据NSString *result = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding] ;NSLog(@"haleli >>> %@",result);NSDictionary *dict = [LLTool dictWithJsonString:result] ;NSNumber *ret = [dict objectForKey:@"success"] ;[self performBoolComplete:complete ret:ret filePath:furl.path] ;if(isMock){[[LLMockHelper sharedHelper] startMock] ;}}];}}
4、参考文章
1、/m0_37989980/article/details/78859046
2、//01/28/iOS-%E4%BD%BF%E7%94%A8NSURLConnection%E8%BF%9B%E8%A1%8CHttp-Get%E5%92%8CPost%E8%AF%B7%E6%B1%82%E7%BD%91%E7%BB%9C%E6%95%B0%E6%8D%AE/
3、/p/db0e1843c425
4、/p/44629e5bf986
5、/wudj810818/article/details/50903416
6、/article/p-gbonskld-yz.html