2015-11-23 46 views
0

我有以下方法,如果SessionStatus完成,我想返回movieDestinationUrl,但我不断收到此错误Unexpected non-void return value in void function。我究竟做错了什么?异步completionHandler内的返回值

func createVideo() -> NSURL { 

    // create new file to receive data 
    let docsDir: AnyObject = documentsPath 
    let movieFilePath = docsDir.stringByAppendingPathComponent("result.mov") 
    let movieDestinationUrl = NSURL(fileURLWithPath: movieFilePath) 
    _ = try? NSFileManager().removeItemAtURL(movieDestinationUrl) 

    // use AVAssetExportSession to export video 
    let assetExport = AVAssetExportSession(asset: composition, presetName:AVAssetExportPresetHighestQuality) 
    assetExport!.outputFileType = AVFileTypeQuickTimeMovie 
    assetExport!.outputURL = movieDestinationUrl 
    assetExport?.videoComposition = layercomposition 
    assetExport!.exportAsynchronouslyWithCompletionHandler({ 
     switch assetExport!.status{ 
     case AVAssetExportSessionStatus.Failed: 
      print("failed \(assetExport!.error)") 
     case AVAssetExportSessionStatus.Cancelled: 
      print("cancelled \(assetExport!.error)") 
     default: 
      print("Movie complete") 


      // save to photoalbum 
      return movieDestinationUrl 

     } 
    }) 

} 

回答

0

您可以设置一个观察者变量,并在它的didSet中保存到相册中。在完成处理程序中,派发到主队列并设置观察者以开始保存。

var movieDestinationUrlGetter: NSURL? { 
    didSet { 
     //save to photoalbum 
    } 
} 

func createVideo() -> NSURL { 
. 
. 

assetExport!.exportAsynchronouslyWithCompletionHandler({ 
    switch assetExport!.status{ 
    case AVAssetExportSessionStatus.Failed: 
     print("failed \(assetExport!.error)") 
    case AVAssetExportSessionStatus.Cancelled: 
     print("cancelled \(assetExport!.error)") 
    default: 
     dispatch_async(dispatch_get_main_queue()) { 
      print("Movie complete") 
      movieDestinationUrlSGetter = movieDestinationUrl 
     } 
    } 
}) 
0

它看起来像返回值取决于异步代码,你应该尝试使用其他方法,如委托出口后的反应是在完成处理程序块完整的成功:

func createVideo() { 

    // create new file to receive data 
    let docsDir: AnyObject = documentsPath 
    let movieFilePath = docsDir.stringByAppendingPathComponent("result.mov") 
    let movieDestinationUrl = NSURL(fileURLWithPath: movieFilePath) 
    _ = try? NSFileManager().removeItemAtURL(movieDestinationUrl) 

    // use AVAssetExportSession to export video 
    let assetExport = AVAssetExportSession(asset: composition, presetName:AVAssetExportPresetHighestQuality) 
    assetExport!.outputFileType = AVFileTypeQuickTimeMovie 
    assetExport!.outputURL = movieDestinationUrl 
    assetExport?.videoComposition = layercomposition 
    assetExport!.exportAsynchronouslyWithCompletionHandler({ 
     switch assetExport!.status{ 
     case AVAssetExportSessionStatus.Failed: 
      print("failed \(assetExport!.error)") 
     case AVAssetExportSessionStatus.Cancelled: 
      print("cancelled \(assetExport!.error)") 
     case AVAssetExportSessionStatus.Completed: { 
      print("Movie complete") 

      self.onExportComplete(movieDestinationUrl) // a method where you notify self that the export is successfully complete 
     } 

     default: { 
      print("Export did not complete") 
     } 
    }) 
} 

请注意,现在此方法返回void,因为在导出完成之前没有任何内容可以返回

另请注意,您没有覆盖所有可能的状态代码,因此默认情况下可能也意味着完成并未成功结束原因。使用“已完成”状态以确保它已完成。

0

你不能返回它,因为它是异步的,没有什么东西在等待接收值。

一种方法是改用通知,并将URL包含为附加到通知的数据的一部分。

+0

这看起来怎么样? –

+0

查看'NSNotificationCenter'的文档。如果使用它后不清楚,让我知道什么部分混淆你。 –

1

同步:您需要一把锤子。你派人从你的工具箱拿起锤子,拿回来,然后把锤子递给你。同时你正在等待那个人回来。非常简单,效率很低,因为你花时间等待其他人。

异步:你需要一把锤子。你派人从你的工具箱拿起锤子。但你不要等到锤子回来,因为你还有其他的事情要做。当这个人拿着锤子回来时,他们把它放到了一个标有“把锤子放在这里!”的地方。并在笔记上放置一个“锤子已准备就绪”的音符。一旦你完成了你正在做的事情,你就会看到笔记,将它移开,然后拿起锤子。

这就是异步调用的工作方式。他们跑到最后,他们把结果存放在你可以找到它们的地方,通常通过调用你给他们的一段代码来通知你。 (这是“完成处理程序”)。