通过UIImagePickerController(),打开相册并选取相册内的资源,其实没什么难度。之前项目中需要将相册内的视频拿到本地APP中,并进行播放。具体思路为本地某个控制器准守UIImagePickerControllerDelegate代理方法,通过一下两个方法即可拿到当前视频的路径,尽管中间有通过264压缩,但是整体功能不受影响。

    func initImagePickController(){if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {let picker = UIImagePickerController()picker.delegate = selfpicker.sourceType = UIImagePickerControllerSourceType.photoLibrarypicker.videoExportPreset = AVAssetExportPresetHighestQualitypicker.mediaTypes = [kUTTypeMovie as String]picker.allowsEditing = falseself.present(picker, animated: true, completion: {()-> Void in})}else{print("读取相册错误")} }// 代理方法,点击哪个视频,就会调用该方法。func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {let mediaType = info[UIImagePickerControllerMediaType] as! Stringif mediaType == (kUTTypeMovie as String){let videoURL =  info[UIImagePickerControllerMediaURL] as! NSURLlet startTime : Int  = 0let urlStr = videoURL.absoluteStringself.dismiss(animated: true, completion: nil)print(urlStr)//拿到urlStr后,即可设置播放器的url。}}

上面的代码,在获取通过相机拍照或者其他APP保存的视频都没有问题。直到有一次,通过苹果家的“隔空投送”功能将Mac上的视频投送到iPhone相册里面,在提取该视频的时候程序崩溃了。

通过对比正确提取视频和错误提取后的info中的信息发现,能够正确提取的info[UIImagePickerControllerMediaURL]不为空,而引起崩溃的info[UIImagePickerControllerMediaURL]为nil。打断点后,在xcode的输出栏中,通过po info 命令,打印info的详细内容后发现:

正确:
▿ 3 elements▿ 0 : 2 elements- key : "UIImagePickerControllerReferenceURL"- value : assets-library://asset/asset.MP4?id=CCCE2E1E-15F3-4416-8E73-B6102ACDEC15&ext=MP4▿ 1 : 2 elements- key : "UIImagePickerControllerMediaType"- value : public.movie▿ 2 : 2 elements- key : "UIImagePickerControllerMediaURL"- value : file:///private/var/mobile/Containers/Data/Application/ED79D02E-3516-4B82-B0F7-EA79BCF48903/tmp/7B922446-27CB-46F9-BB7E-0C3273CE45D8.MOV错误:
▿ 2 elements▿ 0 : 2 elements- key : "UIImagePickerControllerReferenceURL"- value : assets-library://asset/asset.MOV?id=7CE3AC64-2EF7-4915-B257-3D140B9F3919&ext=MOV▿ 1 : 2 elements- key : "UIImagePickerControllerMediaType"- value : public.movie

通过正常提取视频路径的后发现,通过UIImagePickerControllerMediaURL这个key,指向的是通过压缩后放入的视频路径。而UIImagePickerControllerReferenceURL是指向源视频资源的一个ID。通过某些方法,就可以将源视频提取出来。

那么我们可以通过UIImagePickerControllerReferenceURL这个信息把视频源提取出来,复制到本地app的一个专属临时文件夹内,然后播放该视频就可以了吧。这样还可以避免了从相册里面取视频时必须压缩的尴尬局面。

那么修改后成了一下代码:

        if let referenceURL = info[UIImagePickerControllerReferenceURL] as? NSURL {let fetchResult = PHAsset.fetchAssets(withALAssetURLs: [referenceURL as URL], options: nil)if let phAsset = fetchResult.firstObject {PHImageManager.default().requestAVAsset(forVideo: phAsset, options: PHVideoRequestOptions(), resultHandler: { (asset, audioMix, info) -> Void inDispatchQueue.main.async {if let asset = asset as? AVURLAsset {let videoData = NSData(contentsOf: asset.url)// optionally, write the video to the temp directorylet videoPath = NSTemporaryDirectory() + "tmpMovie.MOV"let videoURL = NSURL(fileURLWithPath: videoPath)let writeResult = videoData?.write(to: videoURL as URL, atomically: true)if writeResult == true{                               print(videoURL)// 利用该videoURL获取复制到本地APP的视频资源路径,上传、下载作为播放器的视频源}else{print("失败")}}}})}}

这样做其实基本实现了之前设想的功能,但是xcode却报出了警告,大体意思就是UIImagePickerControllerReferenceURL方法已经过时,请利用UIImagePickerControllerPHAsset。但是通过对比上面的正确和错误的info信息知道,根本没有这个key键啊?怎么取出。

原来在iOS11后,苹果对于用户隐私做出了某些改变,既能保护了用户的隐私,又能方便app开发者方便调用相册资源。

iOS11之前,利用UIImagePickerController后会弹出授权窗口,意思是要访问你的相册,需要经过你的同意。反正就是只要是你想要访问相册,无论该访问有多么的微不足道,都会弹出窗口。但是在iOS11后,创建UIImagePickerController,并且present后,不在弹出,即本博客的func initImagePickController()方法执行过程不在弹出弹窗。

而之前之所以无法通过info[UIImagePickerControllerPHAsset]获取的资源就是因为这方面的原因。通过断点发现,执行上面的代码段:PHAsset.fetchAssets()该方法时(xcode此时也提示该方法已经过时),会弹出授权窗口。利用到了PHAsset类。经过授权以后,info[UIImagePickerControllerPHAsset]不在为nil,此时打印info这个字典的信息为:

▿ 3 elements▿ 0 : 2 elements- key : "UIImagePickerControllerReferenceURL"- value : assets-library://asset/asset.MP4?id=9ABEAACE-54DD-4C2F-BCEE-DEDFA12B2BDC&ext=MP4▿ 1 : 2 elements- key : "UIImagePickerControllerPHAsset"- value : <PHAsset: 0x103d823e0> 9ABEAACE-54DD-4C2F-BCEE-DEDFA12B2BDC/L0/001 mediaType=2/0, sourceType=1, (528x960), creationDate=2019-05-05 09:31:04 +0000, location=0, hidden=0, favorite=0 ▿ 2 : 2 elements- key : "UIImagePickerControllerMediaType"- value : public.movie

此时发现,没有了UIImagePickerControllerMediaURL该key键。有了UIImagePickerControllerPHAsset该key键,获取对应的PHAsset类就可以提取对应的资源了。

经过上面的分析可知,我们在正确的提取相册内的资源并复制到本地APP内,在点击选中视频后,在执行UIImagePickerControllerDelegate的imagePickerController()代理方法之前,必须获取访问相册的权限后才能通过info[UIImagePickerControllerPHAsset]得到PHAsset。由此整理出一下代码:

func jumpToViewController() {
//        主动获取打开系统相册权限if PHPhotoLibrary.authorizationStatus() == .notDetermined{PHPhotoLibrary.requestAuthorization { (state) inif state == .authorized{    self.initImagePickController()  } else if state == .denied || state == .restricted{self.dismiss(animated: true, completion: {print("拒绝访问相册")})}}}else{          self.initImagePickController()}}
// 也可以主动调用UIImageWriteToSavedPhotosAlbum()该方法,即向相册内写东西,但是我们内部可以什么都不写,只是为了获取权限。func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {if let asset = info[UIImagePickerControllerPHAsset] as? PHAsset {PHImageManager.default().requestAVAsset(forVideo: asset, options: PHVideoRequestOptions(), resultHandler: { (asset, audioMix, info) -> Void in    DispatchQueue.main.async {if let asset = asset as? AVURLAsset {                        let videoData = NSData(contentsOf: asset.url)                        // optionally, write the video to the temp directorylet videoPath = NSTemporaryDirectory() + "tmpMovie.MOV"let videoURL = NSURL(fileURLWithPath: videoPath)let writeResult = videoData?.write(to: videoURL as URL, atomically: true)if writeResult == true{                            print(videoURL)// 利用该videoURL获取复制到本地APP的视频资源路径,上传、下载作为播放器的视频源                            }else{                         print("失败")}}}})}

复制文件的时候,必须在主线程中进行,否则会报错:DispatchQueue : Cannot be called with asCopy = NO on non-main thread。

iOS(swift):将相册里的资源复制到本地APP相关推荐

  1. iOS——调用系统相册和相机

    iOS--调用系统相册和相机 背景 我们在许多app里可以发现在换头像的时候一般有两个选择,一个是选择本地照片,一个选择是相机也就是直接拍一张照片当头像,另外还有就是可以去修改照片尺寸,所以我们就要知 ...

  2. iOS/swift之获取系统所有相册和照片录像、封装相册多选

    参考:http://www.hangge.com/blog/cache/detail_1512.html ios14 使用PHPicker获取相册(需要 import PhotosUI) 支持多选 支 ...

  3. 用Swift实现iOS相机及相册图片上传

    最近要做一个iOS相机及相册图片上传,其中遇到了这些问题:1.图片增删在UICollectionView里的变化:2.获取相机拍摄的照片和相册的照片:3.将PHAsset对象转为UIImage对象: ...

  4. iOS 程序员必须收藏的资源大全

    这个列表分为以下几个部分:框架( Frameworks ).组件( Components ).测试( Testing )和其他的开源项目,免费的和付费的服务.每个部分中的项目没有先后顺序,均是按照提交 ...

  5. BundleLoader:帮你无缝加载自定义Bundle里的资源文件

    引子 iOS开发中,我们封装SDK给第三方使用通常采用.a或.framework + .bundle的形式.相信封装过这种带bundle资源文件的SDK的同学们一定都会遇到这样一个小麻烦.那就是加载自 ...

  6. 学习苹果Swift语言的一些在线资源

    Swift 是苹果为 OS X 和 iOS 平台引入的一种新的程序设计语言,这种程序设计语言已经激发了开发者社区的大量关注.仅仅几天之内,在 Stack Overflow 网站上提出的关于 Swift ...

  7. 怎么把备忘录中的视频导到手机相册里

    备忘录是手机上常见的工具.有一些好用的手机备忘录,不仅可以记录文字备忘,还能设置时间提醒,并在备忘录中添加视频文件,让备忘录的形式更丰富.那怎么把备忘录中的视频导到手机相册里呢? 想要将备忘录中的视频 ...

  8. 怎样获取苹果APP里的资源图片

    今天,朋友想从我这里要一份"慕课"app里的资源图片素材,让我帮忙从mac机上的AppStore上下一下这个应用,关键是AppStore上没有这个应用啊!小编当时就晕了☁️小编理解 ...

  9. iOS 获取系统相册

    在iOS开发中经常会用到相册的图片,但是原生的UIImagePikerViewDelegate只能选取一张照片进行处理,这样管理起来比较麻烦,所以本次带来获取系统所有相册. 首先建一个继承NSObje ...

最新文章

  1. 佩恩:京奥了不起 10年后“水落石出”
  2. 9、Power Map—应用拾取坐标系统确定经纬度
  3. 反思对新项目如何快速上手
  4. SpringAop对struts2的Action设置切面织入时报错java.lang.NoSuchMethodException
  5. Taro+react开发(73):Taro.createSelectorQuery
  6. Elasticsearch单机安装Version7.10.1
  7. python学习手记 pt1
  8. NSLog 输出格式集合
  9. arcgis中img 批量转换tif_在ArcGIS中Python使用及批量裁剪示技巧讲解 !
  10. Chrome历史版本查看
  11. 如何合并pdf文件,pdf合并方法
  12. 2013 B 碎纸片拼接与复原
  13. 北斗导航:太空中最亮的“中国星”
  14. POJ 3689 Equations 题解 《挑战程序设计竞赛》
  15. MATLAB的矩阵输入
  16. 【示波器】基于FPGA的数字示波器设计实现
  17. 本题要求递归实现一个计算非负整数阶乘的简单函数。
  18. php工具箱在win10自动退出,win10游戏闪退修复办法
  19. vue中安装和使用Dplayer视频播放器
  20. 4.2.3 编程题《将一笔钱换算成1分、2分和5分的硬币组合》

热门文章

  1. 安装.NET Framework 4.6.1
  2. C++ 求Fibonacci(斐波那契)数
  3. 生成文件md5校验码可满足大于2G情况
  4. jqm视频播放器,html5视频播放器,html5音乐播放器,html5播放器,video开发demo,html5视频播放示例,html5手机视频播放器
  5. jEdit打字区域背景颜色个性化设置
  6. CTC(Connectionist Temporal Classification)介绍
  7. java byte转16进制_Java 十六进制(Hex)与byte数组之间的转换
  8. 在Sublime中输入中文都成了繁体字的解决办法
  9. 这一次AI应该是真正的已经到来
  10. 几何体抽象画创作和多边花绘制程序python