随笔-512  评论-3694  文章-0 

【Swift 2.1】共享文件操作小结(iOS 8 +)

 

前言

  适用于 iOS 8 + 本地共享文件列表

 

声明
  欢迎转载,但请保留文章原始出处:)
  博客园:http://www.cnblogs.com
  农民伯伯: http://over140.cnblogs.com

 

正文 

  一、准备

    1.1  默认 App 的文件共享是关闭的,需要在 plist 中设置启用:

    Application supports iTunes file sharing  设置为  YES

      启用后把设备连接到 iTunes 上,在 iTunes 应用里的文件共享就能看到你的 App 了(如果看不见需要断开重新拔插一下数据线),可以拷贝一些视频进去,便于测试。

    1.2  导入库

      Photos.framework

      AVKit.framework  用于播放视频    

 

  二、获取视频列表

    private let VIDEO_EXTENSIONS = [
        ".MOV", ".MP4"
    ]

    private var fileManager = NSFileManager.defaultManager()
    
    func loadVideos() {
        var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
        if paths.count > 0 {
            let documentsDirectory = paths[0] as String
            let documentUrl = NSURL(fileURLWithPath: documentsDirectory, isDirectory: true)
            do {
                documentUrl.path
                let files = try fileManager.contentsOfDirectoryAtPath(documentsDirectory)
                for file in files {
                    fetchVideos(documentUrl.URLByAppendingPathComponent(file).path ?? "")
                }
            }   catch {
                
            }
            
            self.tableView.reloadData()
        }
    }
    
    func fetchVideos(path: String) {
        var isDir: ObjCBool = false
        if !path.isEmpty && fileManager.fileExistsAtPath(path, isDirectory: &isDir) {
            if isDir {
                do {
                    let files = try fileManager.contentsOfDirectoryAtPath(path)
                    for file in files {
                        fetchVideos(file)
                    }
                } catch {
                }
            } else {
                var file = File(path: path)
                if file.isValid() && isVideoFileExtension(file.fileExtension.uppercaseString) {
                    do {
                        if let attr: NSDictionary = try fileManager.attributesOfItemAtPath(path) {
                            file.fileSize = attr.fileSize()
                        }
                    } catch {
                    }
                    videos.append(file)
                }
            }
        }
    }
    
    func isVideoFileExtension(ext: String) -> Bool {
        for videoExtension in VIDEO_EXTENSIONS {
            if ext == videoExtension {
                return true
            }
        }
        return false
    }
    
    struct File {
        var fileExtension = ""
        var fileName = ""
        var path = ""
        var assert: AVURLAsset?
        var url: NSURL!
        var fileSize: UInt64 = 0
        
        init(path: String) {
            self.path = path
            self.url = NSURL(fileURLWithPath: path)
            self.fileName = url.lastPathComponent ?? ""
            self.fileExtension = "." + (url.pathExtension ?? "")
        }
        
        func isValid() -> Bool {
            return !(fileName.isEmpty || fileExtension.isEmpty)
        }
    }

    代码说明:

      a)需要注意一些 swift 的用法,例如 fileExistsAtPath 的用法

      b)还有 String 的 pathExtension 和 lastPathComponent 都没了,都改到了 NSURL 下面去了,网上很多资料都还是从 NSString 或者 String 取这些属性

      c)AVURLAsset 可以取到视频的时长

        CMTimeGetSeconds(AVURLAsset(URL: file.url, options: nil).duration)

 

  三、播放视频

    func play(file: File) {
        let player = AVPlayer(URL: file.url)
        let playerViewController = AVPlayerViewController()
        playerViewController.player = player
        self.presentViewController(playerViewController, animated: true) {
            playerViewController.player?.play()
        }
    }

 

  四、用 ... 打开

    func openIn(file: File, indexPath: NSIndexPath) {
        let document = UIDocumentInteractionController(URL: file.url)
        let rect = self.tableView.rectForRowAtIndexPath(indexPath)
        document.presentOpenInMenuFromRect(rect, inView: self.tableView, animated: true)
    }

 

  五、删除视频

    func delete(file: File, indexPath: NSIndexPath) {
        do {
            try fileManager.removeItemAtPath(file.path)
            videos.removeAtIndex(indexPath.row)
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
        } catch {
            
        }
    }

 

  六、保存到相册

    func saveToCameraRoll(file: File, indexPath: NSIndexPath) {
        if UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(file.path) {
            UISaveVideoAtPathToSavedPhotosAlbum(file.path, self, "image:didFinishSavingWithError:contextInfo:", nil)
        } else {
            // save faild
        }
    }
    
    func image(image: UIImage, didFinishSavingWithError error: NSErrorPointer, contextInfo:UnsafePointer<Void>) {
        if error == nil {
            // save success
        } else {
            // save faild
        }
    }

    代码说明:

      注意 UISaveVideoAtPathToSavedPhotosAlbum 的用法,后面 Selector 写得不对就会报错。

 

结束

  一口气写完一个功能好爽

 

posted on 2015-12-02 18:24 农民伯伯 阅读(...) 评论(...) 编辑 收藏