当前位置: 移动技术网 > IT编程>移动开发>IOS > iOS实现视频和图片的上传思路

iOS实现视频和图片的上传思路

2019年07月24日  | 移动技术网IT编程  | 我要评论

qq个性 签名,幼儿园小制作,张贤亮作品下载

关于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];
}

以上所述是小编给大家介绍的ios实现视频和图片的上传思路,希望对大家有所帮助

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

  • ios uicollectionview实现横向滚动

    现在使用卡片效果的app很多,之前公司让实现一种卡片效果,就写了一篇关于实现卡片的文章。文章最后附有demo实现上我选择了使用uicollectionview ... [阅读全文]
  • iOS UICollectionView实现横向滑动

    本文实例为大家分享了ios uicollectionview实现横向滑动的具体代码,供大家参考,具体内容如下uicollectionview的横向滚动,目前我使... [阅读全文]
  • iOS13适配深色模式(Dark Mode)的实现

    iOS13适配深色模式(Dark Mode)的实现

    好像大概也许是一年前, mac os系统发布了深色模式外观, 看着挺刺激, 时至今日用着也还挺爽的终于, 随着iphone11等新手机的发售, ios 13系统... [阅读全文]
  • ios 使用xcode11 新建项目工程的步骤详解

    ios 使用xcode11 新建项目工程的步骤详解

    xcode11新建项目工程,新增了scenedelegate这个类,转而将原appdelegate负责的对ui生命周期的处理担子接了过来。故此可以理解为:ios... [阅读全文]
  • iOS实现转盘效果

    本文实例为大家分享了ios实现转盘效果的具体代码,供大家参考,具体内容如下demo下载地址: ios转盘效果功能:实现了常用的ios转盘效果,轮盘抽奖效果的实现... [阅读全文]
  • iOS开发实现转盘功能

    本文实例为大家分享了ios实现转盘功能的具体代码,供大家参考,具体内容如下今天给同学们讲解一下一个转盘选号的功能,直接上代码直接看viewcontroller#... [阅读全文]
  • iOS实现轮盘动态效果

    本文实例为大家分享了ios实现轮盘动态效果的具体代码,供大家参考,具体内容如下一个常用的绘图,主要用来打分之类的动画,效果如下。主要是ios的绘图和动画,本来想... [阅读全文]
  • iOS实现九宫格连线手势解锁

    本文实例为大家分享了ios实现九宫格连线手势解锁的具体代码,供大家参考,具体内容如下demo下载地址:效果图:核心代码://// clockview.m// 手... [阅读全文]
  • iOS实现卡片堆叠效果

    本文实例为大家分享了ios实现卡片堆叠效果的具体代码,供大家参考,具体内容如下如图,这就是最终效果。去年安卓5.0发布的时候,当我看到安卓全新的material... [阅读全文]
  • iOS利用余弦函数实现卡片浏览工具

    iOS利用余弦函数实现卡片浏览工具

    本文实例为大家分享了ios利用余弦函数实现卡片浏览工具的具体代码,供大家参考,具体内容如下一、实现效果通过拖拽屏幕实现卡片移动,左右两侧的卡片随着拖动变小,中间... [阅读全文]
验证码:
移动技术网