• iOS实现视频和图片的上传


    关于iOS如何实现视频和图片的上传, 我们先理清下思路

    思路:

    #1. 如何获取图片?

    #2. 如何获取视频?

    #3. 如何把图片存到缓存路径中?

    #4. 如何把视频存到缓存路径中?

    #5. 如何上传?

    接下来, 我们按照上面的思路一步一步实现

    首先我们新建一个类, 用来储存每一个要上传的文件uploadModel.h

    #import <Foundation/Foundation.h>
    
    @interface uploadModel : NSObject
    
    @property (nonatomic, strong) NSString *path;
    @property (nonatomic, strong) NSString *type;
    @property (nonatomic, strong) NSString *name;
    @property (nonatomic, assign) BOOL      isUploaded;
    
    @end

    #1. 如何获取图片?

    从相册选择 或者 拍照, 

    这部分可以用UIImagePickerController来实现

    代码如下:

    - (void)actionPhoto {
        
        UIAlertController *alertController  = 
        [UIAlertController alertControllerWithTitle:@""
                                            message:@"上传照片"
                                     preferredStyle:UIAlertControllerStyleActionSheet];
        
        UIAlertAction *photoAction  = 
        [UIAlertAction actionWithTitle:@"从相册选择"
                                 style:UIAlertActionStyleDefault
                               handler:^(UIAlertAction * _Nonnull action) {
            
                                   NSLog(@"从相册选择");
                                   self.imagePicker.sourceType    = UIImagePickerControllerSourceTypePhotoLibrary;
                                   self.imagePicker.mediaTypes = @[(NSString *)kUTTypeImage];
                                   self.imagePicker.allowsEditing = YES;
                                   
                                   [self presentViewController:self.imagePicker
                                                      animated:YES
                                                    completion:nil];
                                   
                               }];
        
        UIAlertAction *cameraAction = 
        [UIAlertAction actionWithTitle:@"拍照"
                                 style:UIAlertActionStyleDefault
                               handler:^(UIAlertAction * _Nonnull action) {
            
                                   NSLog(@"拍照");
                                   if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
                                       
                                       self.imagePicker.sourceType        = UIImagePickerControllerSourceTypeCamera;
                                       self.imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
                                       self.imagePicker.cameraDevice      = UIImagePickerControllerCameraDeviceRear;
                                       self.imagePicker.allowsEditing     = YES;
                                       
                                       [self presentViewController:self.imagePicker
                                                          animated:YES
                                                        completion:nil];
                                   }
                               }];
        
        UIAlertAction *cancelAction = 
        [UIAlertAction actionWithTitle:@"取消"
                                 style:UIAlertActionStyleCancel
                               handler:^(UIAlertAction * _Nonnull action) {
            
                                   NSLog(@"取消");
                               }];
        
        [alertController addAction:photoAction];
        [alertController addAction:cameraAction];
        [alertController addAction:cancelAction];
        
        [self presentViewController:alertController animated:YES completion:nil];
    }

    #2. 如果获取视频?

    从相册选择 或者 拍摄

    这部分也可以用UIImagePickerController来实现

    代码:

    - (void)actionVideo {
        
        UIAlertController *alertController = 
        [UIAlertController alertControllerWithTitle:@""
                                            message:@"上传视频"
                                     preferredStyle:UIAlertControllerStyleActionSheet];
        
        UIAlertAction *photoAction = 
        [UIAlertAction actionWithTitle:@"从视频库选择"
                                 style:UIAlertActionStyleDefault
                               handler:^(UIAlertAction * _Nonnull action) {
            
                                   NSLog(@"从视频库选择");
                                   self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
                                   self.imagePicker.mediaTypes = @[(NSString *)kUTTypeMovie];
                                   self.imagePicker.allowsEditing = NO;
                                   
                                   [self presentViewController:self.imagePicker animated:YES completion:nil];
                               }];
        
        UIAlertAction *cameraAction = 
        [UIAlertAction actionWithTitle:@"录像"
                                 style:UIAlertActionStyleDefault
                               handler:^(UIAlertAction * _Nonnull action) {
            
                                   NSLog(@"录像");
                                   self.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
                                   self.imagePicker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
                                   self.imagePicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
                                   self.imagePicker.videoQuality = UIImagePickerControllerQualityType640x480;
                                   self.imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
                                   self.imagePicker.allowsEditing = YES;
                                   
                                   [self presentViewController:self.imagePicker animated:YES completion:nil];
                               }];
        
        UIAlertAction *cancelAction = 
        [UIAlertAction actionWithTitle:@"取消"
                                 style:UIAlertActionStyleCancel
                               handler:^(UIAlertAction * _Nonnull action) {
            
                                   NSLog(@"取消");
                               }];
        
        [alertController addAction:photoAction];
        [alertController addAction:cameraAction];
        [alertController addAction:cancelAction];
        
        [self presentViewController:alertController animated:YES completion:nil];
    }

    #3, 关于缓存, 如何把照片存入缓存目录?

    这部分我们先考虑缓存目录, 一般存在Document 或者 Temp里面

    我们给图片和视频各创建一个缓存目录:

    #define PHOTOCACHEPATH [NSTemporaryDirectory() stringByAppendingPathComponent:@"photoCache"]
    #define VIDEOCACHEPATH [NSTemporaryDirectory() stringByAppendingPathComponent:@"videoCache"]

    把UIImage存入缓存的方法:

    //将Image保存到缓存路径中
    - (void)saveImage:(UIImage *)image toCachePath:(NSString *)path {
        
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if (![fileManager fileExistsAtPath:PHOTOCACHEPATH]) {
            
            NSLog(@"路径不存在, 创建路径");
            [fileManager createDirectoryAtPath:PHOTOCACHEPATH
                   withIntermediateDirectories:YES
                                    attributes:nil
                                         error:nil];
        } else {
            
            NSLog(@"路径存在");
        }
        
        //[UIImagePNGRepresentation(image) writeToFile:path atomically:YES];
        [UIImageJPEGRepresentation(image, 1) writeToFile:path atomically:YES];
    }

    4. 如何把视频存入缓存?

    把视频存入缓存的方法:

    //将视频保存到缓存路径中
    - (void)saveVideoFromPath:(NSString *)videoPath toCachePath:(NSString *)path {
        
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if (![fileManager fileExistsAtPath:VIDEOCACHEPATH]) {
            
            NSLog(@"路径不存在, 创建路径");
            [fileManager createDirectoryAtPath:VIDEOCACHEPATH
                   withIntermediateDirectories:YES
                                    attributes:nil
                                         error:nil];
        } else {
            
            NSLog(@"路径存在");
        }
        
        NSError *error;
        [fileManager copyItemAtPath:videoPath toPath:path error:&error];
        if (error) {
            
            NSLog(@"文件保存到缓存失败");
        }
    }

    从缓存获取图片的方法:

    //从缓存路径获取照片
    - (UIImage *)getImageFromPath:(NSString *)path {
        
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if ([fileManager fileExistsAtPath:path]) {
            
            return [UIImage imageWithContentsOfFile:path];
        }
        
        return nil;
    }

    上传图片和视频的时候我们一般会利用当前时间给文件命名, 方法如下

    //以当前时间合成图片名称
    - (NSString *)getImageNameBaseCurrentTime {
        
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"yyyy-MM-dd HH-mm-ss"];
        
        return [[dateFormatter stringFromDate:[NSDate date]] stringByAppendingString:@".JPG"];
    }
    
    //以当前时间合成视频名称
    - (NSString *)getVideoNameBaseCurrentTime {
        
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"yyyy-MM-dd HH-mm-ss"];
        
        return [[dateFormatter stringFromDate:[NSDate date]] stringByAppendingString:@".MOV"];
    }

    有时候需要获取视频的第一帧作为显示, 方法如下:

    //获取视频的第一帧截图, 返回UIImage
    //需要导入AVFoundation.h
    - (UIImage*) getVideoPreViewImageWithPath:(NSURL *)videoPath
    {
        AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoPath options:nil];
        
        AVAssetImageGenerator *gen         = [[AVAssetImageGenerator alloc] initWithAsset:asset];
        gen.appliesPreferredTrackTransform = YES;
        
        CMTime time      = CMTimeMakeWithSeconds(0.0, 600);
        NSError *error   = nil;
        
        CMTime actualTime;
        CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error];
        UIImage *img     = [[UIImage alloc] initWithCGImage:image];
        
        return img;
    }

    5. 如何上传?

    下面就是上传方法:

    我把服务器地址xx掉了, 大家可以改为自己的

    //上传图片和视频
    - (void)uploadImageAndMovieBaseModel:(uploadModel *)model {
        
        //获取文件的后缀名
        NSString *extension = [model.name componentsSeparatedByString:@"."].lastObject;
        
        //设置mimeType
        NSString *mimeType;
        if ([model.type isEqualToString:@"image"]) {
            
            mimeType = [NSString stringWithFormat:@"image/%@", extension];
        } else {
            
            mimeType = [NSString stringWithFormat:@"video/%@", extension];
        }
        
        //创建AFHTTPSessionManager
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        
        //设置响应文件类型为JSON类型
        manager.responseSerializer    = [AFJSONResponseSerializer serializer];
        
        //初始化requestSerializer
        manager.requestSerializer     = [AFHTTPRequestSerializer serializer];
        
        manager.responseSerializer.acceptableContentTypes = nil;
        
        //设置timeout
        [manager.requestSerializer setTimeoutInterval:20.0];
        
        //设置请求头类型
        [manager.requestSerializer setValue:@"form/data" forHTTPHeaderField:@"Content-Type"];
        
        //设置请求头, 授权码
        [manager.requestSerializer setValue:@"YgAhCMxEehT4N/DmhKkA/M0npN3KO0X8PMrNl17+hogw944GDGpzvypteMemdWb9nlzz7mk1jBa/0fpOtxeZUA==" forHTTPHeaderField:@"Authentication"];
        
        //上传服务器接口
        NSString *url = [NSString stringWithFormat:@"http://xxxxx.xxxx.xxx.xx.x"];
    
        //开始上传
        [manager POST:url parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
            
            NSError *error;
            BOOL success = [formData appendPartWithFileURL:[NSURL fileURLWithPath:model.path] name:model.name fileName:model.name mimeType:mimeType error:&error];
            if (!success) {
                
                NSLog(@"appendPartWithFileURL error: %@", error);
            }
        } progress:^(NSProgress * _Nonnull uploadProgress) {
            
            NSLog(@"上传进度: %f", uploadProgress.fractionCompleted);
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            NSLog(@"成功返回: %@", responseObject);
            model.isUploaded = YES;
            [self.uploadedArray addObject:model];
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            NSLog(@"上传失败: %@", error);
            model.isUploaded = NO;
        }];
    }

    这里有事先创建两个可变数组uploadArray, uploadedArray, 一个存放准要上传的内容, 一个存放上传完的内容

    在准备上传后做什么操作, 可以检查两个数组的数量是否相等

    最后是UIImagePickerController的协议方法

    #pragma mark - UIImagePickerDelegate methods
    
    - (void)imagePickerController:(UIImagePickerController *)picker
    didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
        
        [picker dismissViewControllerAnimated:YES completion:nil];
        
        //获取用户选择或拍摄的是照片还是视频
        NSString *mediaType = info[UIImagePickerControllerMediaType];
        
        if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
            
            //获取编辑后的照片
            NSLog(@"获取编辑后的好片");
            UIImage *tempImage = info[UIImagePickerControllerEditedImage];
            
            //将照片存入相册
            if (tempImage) {
                
                if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
                    
                    //将照片存入相册
                    NSLog(@"将照片存入相册");
                    UIImageWriteToSavedPhotosAlbum(tempImage, self, nil, nil);
                }
                
                //获取图片名称
                NSLog(@"获取图片名称");
                NSString *imageName = [self getImageNameBaseCurrentTime];
                NSLog(@"图片名称: %@", imageName);
                
                //将图片存入缓存
                NSLog(@"将图片写入缓存");
                [self saveImage:tempImage
                    toCachePath:[PHOTOCACHEPATH stringByAppendingPathComponent:imageName]];
                
                //创建uploadModel
                NSLog(@"创建model");
                uploadModel *model = [[uploadModel alloc] init];
                
                model.path       = [PHOTOCACHEPATH stringByAppendingPathComponent:imageName];
                model.name       = imageName;
                model.type       = @"image";
                model.isUploaded = NO;
                
                //将模型存入待上传数组
                NSLog(@"将Model存入待上传数组");
                [self.uploadArray addObject:model];
                
            }
        }
        
        else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]) {
            
            if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
                
                //如果是拍摄的视频, 则把视频保存在系统多媒体库中
                NSLog(@"video path: %@", info[UIImagePickerControllerMediaURL]);
                
                ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
                [library writeVideoAtPathToSavedPhotosAlbum:info[UIImagePickerControllerMediaURL] completionBlock:^(NSURL *assetURL, NSError *error) {
                    
                    if (!error) {
                        
                        NSLog(@"视频保存成功");
                    } else {
                        
                        NSLog(@"视频保存失败");
                    }
                }];
            }
            
            //生成视频名称
            NSString *mediaName = [self getVideoNameBaseCurrentTime];
            NSLog(@"mediaName: %@", mediaName);
            
            //将视频存入缓存
            NSLog(@"将视频存入缓存");
            [self saveVideoFromPath:info[UIImagePickerControllerMediaURL] toCachePath:[VIDEOCACHEPATH stringByAppendingPathComponent:mediaName]];
            
            //创建uploadmodel
            uploadModel *model = [[uploadModel alloc] init];
            
            model.path       = [VIDEOCACHEPATH stringByAppendingPathComponent:mediaName];
            model.name       = mediaName;
            model.type       = @"moive";
            model.isUploaded = NO;
            
            //将model存入待上传数组
            [self.uploadArray addObject:model];
        }
        
        //[picker dismissViewControllerAnimated:YES completion:nil];
    
    }
    - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
     
        [picker dismissViewControllerAnimated:YES completion:nil];
    }
  • 相关阅读:
    .NET版UEditor报请求后台配置项http错误,上传功能无法使用的错误解决
    [Asp.net mvc]Asp.net mvc 中使用LocalStorage
    Asp.net mvc Kendo UI Grid的使用(三)
    [Asp.net mvc]Asp.net mvc 使用Json传递数据
    Asp.net mvc Kendo UI Grid的使用(二)
    接口
    结构
    多态
    继承
    方法
  • 原文地址:https://www.cnblogs.com/zhouxihi/p/6526304.html
Copyright © 2020-2023  润新知