iOS 开发之--使用AFNetWorking3.1.0上传单张/多张图片

在调试接口的时候,遇到一个问题,就是多张图片上传的时候,无论我上传多少张,只会上传成功最后一张,也就是说只有一张图片上传成功了,针对这个问题,经过查找资料,找到了缘由,首先,在上传的过程当中,咱们获取到本地的image,会放到一个数组里面,在请求方法内进行上传,也就是说接口只调用一次,可是图片是在遍历完成后,一次性上传成功,如今的话,php后台的循环逻辑出现问题,走的仍是单张上传逻辑,只是在外层添加了一个循环,这就直接致使了问题的存在,固然安卓那边是正常的,针对这种状况,有两种解决方法:php

1,在php端,优化多张图片上传逻辑,而后兼容下单张上传的接口,html

2,就是在ios端的上传多张图片的接口,进行代码的优化,把请求提内的遍历,放到外层,而后每上传一张图片就调用一次接口,固然这是种笨办法,由于php后台没法及时处理,只能在前台作优化了,ios

找后台调试后发现,经过上面的方法上传多张图片,实际上只有一张被传到后台,可能的缘由是:git

上传多张图片时,因为url的参数没有变化,iOS默认是同一个请求,只发送了一次请求给后台,故后台只收到一张图片。github

废话不说了,直接上代码:json

正常的上传图片的方法:数组

        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        manager.requestSerializer.timeoutInterval = 20;
        manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain", @"multipart/form-data", @"application/json", @"text/html", @"image/jpeg", @"image/png", @"application/octet-stream", @"text/json", nil];

        [manager POST:[NSString stringWithFormat:@"%@%@",HostUrl,getInfoPhoto] parameters:parameterDict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
            
            // formData: 专门用于拼接须要上传的数据,在此位置生成一个要上传的数据体
            // 这里的_photoArr是你存放图片的数组
            for (int i = 0; i < headImage.count; i++) {
                
                UIImage *image = headImage[i];
                NSData *imageData = UIImageJPEGRepresentation(image, 0.5);
                
                // 在网络开发中,上传文件时,是文件不容许被覆盖,文件重名
                // 要解决此问题,
                // 能够在上传时使用当前的系统事件做为文件名
                NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
                // 设置时间格式
                [formatter setDateFormat:@"yyyyMMddHHmmss"];
                NSString *dateString = [formatter stringFromDate:[NSDate date]];
                NSString *fileName = [NSString  stringWithFormat:@"%@.jpg", dateString];
                /*
                 *该方法的参数
                 1. appendPartWithFileData:要上传的照片[二进制流]
                 2. name:对应网站上[upload.php中]处理文件的字段(好比upload)
                 3. fileName:要保存在服务器上的文件名
                 4. mimeType:上传的文件的类型
                 */
                [formData appendPartWithFileData:imageData name:@"upload" fileName:fileName mimeType:@"image/jpeg"]; //
            }

            
        } progress:^(NSProgress * _Nonnull uploadProgress) {
            
            //上传进度
            dispatch_sync(dispatch_get_main_queue(), ^{
                NSLog(@"progress is %@",uploadProgress);
            });
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            success(responseObject);
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            failure(error);
            
        }];

 

而后处理事后的代码:缓存

 // 上传多张图片
        for(NSInteger i = 0; i < headImage.count; i++)
        {
            AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
            manager.requestSerializer.timeoutInterval = 20;
            manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain", @"multipart/form-data", @"application/json", @"text/html", @"image/jpeg", @"image/png", @"application/octet-stream", @"text/json", nil];

            __block NSInteger blockI = i;
            [manager POST:[NSString stringWithFormat:@"%@%@",HostUrl,getInfoPhoto] parameters:parameterDict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
                //取出单张图片二进制数据
                id obj = headImage[blockI];
                UIImage *image = nil;
                if ([obj isKindOfClass:[UIImage class]]) {
                    image = (UIImage *)obj;
                }else{
                    image = [UIImage imageWithContentsOfFile:obj];
                }
                if (image) {

                    UIImage *image = headImage[i];
                    NSData *imageData = UIImageJPEGRepresentation(image, 0.5);
                    
                    // 在网络开发中,上传文件时,是文件不容许被覆盖,文件重名
                    // 要解决此问题,
                    // 能够在上传时使用当前的系统事件做为文件名
                    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
                    // 设置时间格式
                    [formatter setDateFormat:@"yyyyMMddHHmmss"];
                    NSString *dateString = [formatter stringFromDate:[NSDate date]];
                    NSString *fileName = [NSString  stringWithFormat:@"%@.jpg", dateString];
                    /*
                     *该方法的参数
                     1. appendPartWithFileData:要上传的照片[二进制流]
                     2. name:对应网站上[upload.php中]处理文件的字段(好比upload)
                     3. fileName:要保存在服务器上的文件名
                     4. mimeType:上传的文件的类型
                     */
                    [formData appendPartWithFileData:imageData name:@"upload" fileName:fileName mimeType:@"image/jpeg"]; //

                    
                }
            } progress:^(NSProgress * _Nonnull uploadProgress) {
                
                NSLog(@"progress is %@",uploadProgress);
                
            } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                
                success(responseObject);
                
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                failure(error);
            }];  
        }

循环调用接口,必然是不合理,不过在这里只谈问题的解决!服务器

 

补:另外若是使用AFN,我推荐一个很是牛的封装类,里面把处理缓存的机制加上了,连接以下:网络

简书地址:http://www.jianshu.com/p/c695d20d95cb

GitHub地址:https://github.com/jkpang/PPNetworkHelper

相关文章
相关标签/搜索