美文网首页
系统相册的数据获取

系统相册的数据获取

作者: 微凉初夏 | 来源:发表于2018-04-25 16:42 被阅读0次

    前言:

    前段时间项目需要做一个自定义的相册,分别显示图片和视频,并且可以局域网传输,由此我做了这么一个相册,这是纯UI部分,配合一个本地的FTP服务器进行传输。

    代码列表:

    屏幕快照 2018-04-11 14.25.08.png

    ~首先~获取数据~Source~

    Part 1、导入需要的库
    import Photos
    
    Part 2、建立数据类
    enum SourceType: String {//文件类型
        case image = "image"
        case video = "video"
    }
    //这里许多是没有用的,我这里是都列出来了,自行取舍
    class AlbumInfo {//文件类
    var id: Int?    //文件的id,唯一标识
    var name: String?    //文件名称
    var imageData: Data?
    var thumbnail: UIImage?    //缩略图
    var info: [AnyHashable : Any]?    //这里面获取的value都只能做字符串使用
    var video: AVAsset?
    var url: URL?    //只有video的URL是可以用的
    var path: String?    //只能做字符串使用
    var mix: AVAudioMix?
    var sourceType: SourceType?
    var isSelect: Bool?    //是否被选中
    
    init(_ id: Int?,
         _ name: String?,
         _ imageData: Data?,
         _ thumbnail: UIImage?,
         _ info: [AnyHashable : Any]?,
         _ video: AVAsset?,
         _ url: URL?,
         _ path: String?,
         _ mix: AVAudioMix?,
         _ sourceType: SourceType?) {
        self.id = id
        self.name = name
        self.imageData = imageData
        self.thumbnail = thumbnail
        self.info = info
        self.video = video
        self.url = url
        self.path = path
        self.mix = mix
        self.sourceType = sourceType
        self.isSelect = false
    }
    
    func isEqual(_ other: AlbumInfo) -> Bool {//比较是否一样
        return self.id == other.id && self.thumbnail == other.thumbnail
    }
    //info里包含的key值,
    static let key_id = "PHImageResultRequestIDKey"
    static let key_url = "PHImageFileURLKey"
    static let key_path = "PHImageFileSandboxExtensionTokenKey"
    }
    
    Part 3、相册资源
    final class AlbumSource {
    static let share = AlbumSource()
    
    init() {
        self.step()
    }
    
    //资源结果
    var imagesSource: [AlbumInfo]?
    var videosSource: [AlbumInfo]?
    
    func getAlbumSource() {
        self.getImageSet()
        self.getVideoSet()
    }
    
    //缩略图大小
    private var thumbnail: CGSize = CGSize(width: 50, height: 50)
    //图片管理(带缓存)
    private let manager = PHCachingImageManager()
    //所有系统的智能相册
    private var sys_Options: PHFetchOptions!
    //所有用户创建的相册
    private var user_Options: PHFetchResult<PHCollection>!
    
    private func step() {
        self.sys_Options = PHFetchOptions()
        self.sys_Options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
        //user_Options没有用到
        self.user_Options = PHCollectionList.fetchTopLevelUserCollections(with: nil)
    }
    
    private func getImageSet() {
        //        guard !AlbumSource.isAuthorized() else {
        //            print("没有权限")
        //            return
        //        }
        //获取图片
        self.sys_Options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue)
        
        let result: PHFetchResult = PHAsset.fetchAssets(with: .image, options: PHFetchOptions())
        guard result.count > 0 else {return}
        var images: [AlbumInfo] = []
        
        for i in 0..<result.count {
            self.manager.requestImageData(for: result[i], options: nil, resultHandler: {[weak self] (data, text, orientation, info) in
                guard let sself = self else {return}
                //                print("================", data, text, orientation, info)
                let id = sself.analysisInfoId(with: info)
                let thum = UIImage(data: data!)?.resize(toSize: sself.thumbnail)
                let url = sself.getImageUrl(with: info)
                let path = sself.getSourcePath(info)
                let name = sself.getName(path)
                images.append(AlbumInfo(id, name, data, thum, info, nil, url, path, nil, .image))
                sself.imagesSource = images
            })
        }
        self.manager.stopCachingImagesForAllAssets()
    }
    
    private func getVideoSet() {
        //获取视频
        self.sys_Options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.video.rawValue)
        let result: PHFetchResult = PHAsset.fetchAssets(with: .video, options: PHFetchOptions())
        guard result.count > 0 else {return}
        var videos: [AlbumInfo] = []
        
        for i in 0..<result.count {
            self.manager.requestAVAsset(forVideo: result[i], options: nil) {[weak self] (asset, mix, info) in
                guard let sself = self else {return}
    //                print("asset:", asset, "mix:", mix, "info:", info)
                let id = sself.analysisInfoId(with: info)
                let image = AlbumSource.getAVAssetImage(asset)
                let url = sself.getVideoUrl(asset)
                let path = sself.getSourcePath(info)
                let name = sself.getName(path)
                videos.append(AlbumInfo(id, name, nil, image, info, asset, url, path, mix, .video))
                sself.videosSource = videos
            }
        }
        self.manager.stopCachingImagesForAllAssets()
    }
    //获取path和url
    private func getVideoUrl(_ asset: AVAsset?) -> URL? {
        guard let urlAsset = asset as? AVURLAsset else {return nil}
        return urlAsset.url
    }
    
    private func getImageUrl(with sourceInfo: [AnyHashable : Any]?) -> URL? {
        guard let info = sourceInfo as? [String : Any] else {return nil}
        if let url = info[AlbumInfo.key_url] as? URL {
            return url
        }
        return nil
    }
    
    private func getSourcePath(_ info: [AnyHashable : Any]?) -> String? {
        guard let info = info as? [String : Any] else {return nil}
        if let value = info[AlbumInfo.key_path] as? String {
            let array = value.components(separatedBy: ";")
            if array.count > 0 {
                for string in array {
                    if string.first == "/" {
                        return "file://" + string
                    }
                }
            }
        }
        return nil
    }
    
    //PHImageResultRequestIDKey ==== id 图片标识
    private func analysisInfoId(with sourceInfo: [AnyHashable : Any]?) -> Int? {
        guard let info = sourceInfo as? [String : Any] else {return nil}
        if let id = info[AlbumInfo.key_id] as? Int {
            return id
        }
        return nil
    }
    
    //判断是否授权
    class func isAuthorized() -> Bool {
        return PHPhotoLibrary.authorizationStatus() == .authorized ||
            PHPhotoLibrary.authorizationStatus() == .notDetermined
    }
    
    //获取视频截图(默认:开始)
    class func getAVAssetImage(_ video: AVAsset?,
                               _ time: CMTime? = CMTimeMakeWithSeconds(0.0,600)) -> UIImage? {
        guard let asset = video else {return nil}
        let generator = AVAssetImageGenerator(asset: asset)
        var actualTime:CMTime = CMTimeMake(0,0)
        do{
            let cgimage: CGImage = try generator.copyCGImage(at: time!, actualTime: &actualTime)
            
            return UIImage(cgImage: cgimage)
        }catch {
            print(error)
        }
        return nil
    }
    
    //获取文件名称
    func getName(_ path: String?) -> String? {
        if let p = path {
            return p.components(separatedBy: "/").last
        }
        return nil
    }
    }
    

    其中,user_Options没有用到,如果有需要的,可以自行解决。

    相关文章

      网友评论

          本文标题:系统相册的数据获取

          本文链接:https://www.haomeiwen.com/subject/nfnahftx.html