2015-10-17 117 views
3

我只是没有“信息”在Swift imagePickerController,所以我不知道如何获取网址并将其转换为数据发送到Web服务。如何将视频(在图库中)转换为NSData?在Swift

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) { 

    var videoDataURL = info[UIImagePickerControllerMediaURL] as! NSURL! 
    var videoFileURL = videoDataURL.filePathURL 
    var video = NSData.dataWithContentsOfMappedFile("\(videoDataURL)") 
} 
+0

请说明你的问题。发布的代码中的“info”参数有什么问题? – rmaddy

+0

酷发表的代码在Swift中工作不swift2我问它如何在swift中工作2这是我的函数参数no info in it“func imagePickerController(picker:UIImagePickerController,didFinishPickingImage image:UIImage,editingInfo:[String:AnyObject]?)” – MOMMH

+0

发布的代码在Swift 2中的工作方式不是什么?您的评论中的委托方法已被弃用。在你的问题中使用一个。只需将'info'参数修改为'[String:AnyObject]'。 – rmaddy

回答

6

的Xcode 8.3•斯威夫特3.1

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any]) { 
    let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! 
    if let fileURL = info[UIImagePickerControllerMediaURL] as? URL { 
     do { 
      try FileManager.default.moveItem(at: fileURL, to: documentsDirectoryURL.appendingPathComponent("videoName.mov") 
      print("movie saved") 
     } catch { 
      print(error) 
     } 
    } 
} 

斯威夫特2

如果让解开你的自选您应该使用。另外NSData.dataWithContentsOfMappedFile已被弃用iOS8。尝试使用NSData的方法初始化contentsOfURL:

注意:您也需要从[NSObject : AnyObject]的didFinishPickingMediaWithInfo声明更改为[String : AnyObject]

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { 
    if let fileURL = info[UIImagePickerControllerMediaURL] as? NSURL { 
     if let videoData = NSData(contentsOfURL: fileURL) { 
      print(videoData.length) 
     } 
    } 
} 

由罗布提到的数据可真大,但不是复制文件,应将文件移动到文件夹如下:

let documentsDirectoryURL = try! NSFileManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true) 
if let fileURL = info[UIImagePickerControllerMediaURL] as? NSURL { 
    do { 
     try NSFileManagerdefaultManager().moveItemAtURL(fileURL, toURL: documentsDirectoryURL.URLByAppendingPathComponent("videoName").URLByAppendingPathExtension("mov")) 
     print("movie saved") 
    } catch { 
     print(error) 
    } 
} 
+0

谢谢,它适用于我 –

3

有几个问题:

  1. 考虑这条线:

    var videoDataURL = info[UIImagePickerControllerMediaURL] as! NSURL! 
    

    这并不强制的info[UIImagePickerControllerMediaURL]展开(这是不好的,因为如果它是nil,应用程序会崩溃)和蒙上它作为一个隐含展开可选NSURL!。这没有意义。只是做一个有条件的解包(和解开到NSURL,而不是一个NSURL!):

    if let videoDataURL = info[UIImagePickerControllerMediaURL] as? NSURL { ... } 
    
  2. 下一行调用filePathURL

    var videoFileURL = videoDataURL.filePathURL 
    

    如果你想要一个文件URL,你已经有一个,所以不需要转换,而只需使用videoDataURL。如果你真的想要的路径,你会使用path方法:

    let videoPath = videoDataURL.path 
    

    坦率地说,苹果竟将我们使用字符串的路径走,所以只使用原videoDataURL,避免同时使用pathfilePathURL的。

  3. 您正在使用dataWithContentsOfMappedFile

    var video = NSData.dataWithContentsOfMappedFile("\(videoDataURL)") 
    

    如果你真的想用dataWithContentsOfMappedFile,正确的雨燕语法是:

    let video = NSData(contentsOfMappedFile: videoPath!) 
    

    dataWithContentsOfMappedFile弃用,因此,你应该使用:

    let video = try NSData(contentsOfFile: videoPath!, options: .DataReadingMappedIfSafe) 
    

    或者,绕过这videoPath完全,你可以:

    let video3 = try NSData(contentsOfURL: videoDataURL, options: .DataReadingMappedIfSafe) 
    

    显然,这些try引渡应该是一个do块与块catch内完成。顺便说一下,正如你在上面的所有例子中看到的那样,在可能的情况下应该使用let

-

坦率地说,我建议不要装成一个NSData可言。只需复制它NSFileManager,这是一个更有效的内存使用。如果视频很长,可能会很大,并且您应该避免在任何时间将整个内容加载到内存中。

所以,你可以:

if let videoDataURL = info[UIImagePickerControllerMediaURL] as? NSURL { 
    do { 
     // build your destination URL however you want 
     // 
     // let tempFolder = NSURL(fileURLWithPath: NSTemporaryDirectory()) 
     // let destinationURL = tempFolder.URLByAppendingPathComponent("test.mov") 

     // or 

     let documents = try NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false) 
     let destinationURL = documents.URLByAppendingPathComponent("test.mov") 

     // but just copy from the video URL to the destination URL 

     try NSFileManager.defaultManager().copyItemAtURL(videoDataURL, toURL: destinationURL) 
    } catch { 
     print(error) 
    } 
} 

如果您要上传这个到Web服务,你再使用NSURLSessionUploadTask,使用文件或流的选项。这个请求的构建是一个单独的问题,但希望你有这样的想法:对于像照片或者特别是视频这样的大型资产,如果可以避免的话,不要使用资产实例化NSData

+0

你还应该解释这个答案如何解决问题中的问题。 – rmaddy

+0

@rmaddy - 我正在削减Gordian结,但我修改了回答来描述问题。 – Rob