2016-08-26 18 views
0

私のiosアプリケーションの共有拡張を作成しました。写真アプリで共有オプションをクリックすると共有拡張が表示され、それをクリックするとコントローラが表示されます。これまですべてがうまくいっています。私はyoutubeのAPIを使用してYouTubeにビデオをアップロードしています。私は、ビデオが小さい場合iosの共有拡張でNSDataにビデオを変換する

GTLUploadParameters *uploadParameters = [GTLUploadParameters uploadParametersWithData:fileData MIMEType:@"video/*"]; 

は今、それは簡単にこのコードを

NSData *fileData = [NSData dataWithContentsOfURL:[NSURL URLWithString:videoURL]]; 

を使用したNSDataに変換され、すべてが動作していると、映像がアップロードされたパラメータを作成するには、このメソッドを使用しています。

しかし、ビデオが大きい場合は、クラッシュして共有拡張を終了します(私はブレークポイントを設定してこの問題を発見しました。ファイルデータ変換を削除するとクラッシュしません)。だから私が何をしたか、私はアプリがクラッシュされていませんが、私はネットワークエラーを取得しています今、このユーチューブAPIメソッド

GTLUploadParameters *uploadParameters = [GTLUploadParameters uploadParametersWithFileURL:[NSURL URLWithString:videoURL] MIMEType:@"video/*"]; 

を使用したNSDataに変換するのではなくでした。エラーが

エラードメイン= NSURLErrorDomainコード= -995 "(ヌル)" である

少し検索は、それが原因NSURLSessionであることを発見し、この

sessionConfiguration.sharedContainerIdentifier = @“com.me.myapp.containerIdentifier”; 
のようなものを使用するように指示しました

私はyoutube apiを使用しています。私はどこでそれを使用するかわからない、または大規模なビデオファイルと共有の拡張子でYouTubeのAPIを使用する他の方法があります。

注::私は自分のアプリでyoutube apiを使用していて、NSDataで正常に動作しています。

希望の質問は明らかです。私は今一日それに固執しています。助けてください。

ありがとうございます。

EDIT 1:

Iは

NSData *fileData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:videoURL] options:0 error:&error]; 

FILEDATAがnilこのコードを使用します。私は取得していますエラーが

エラードメイン= NSCocoaErrorDomainコード= 260 IMG_2187.MOV「ファイル 『』そのようなファイルが存在しないため を開くことができませんでした。」です のUserInfo = {NSFilePath = /ファイル:/var/mobile/Media/DCIM/102APPLE/IMG_2187.MOV、

+0

'NSURLErrorBackgroundSessionRequiresSharedContainer'(これは' -995'エラーです)は、バックグラウンドサービスがあなたのコンテナの外のものを参照するのが好きではないと思わせるものです。おそらくあなたのドキュメントや一時フォルダにコピーして、そこからfileURLを使って 'uploadParametersWithFileURL'でアップロードしてみてください。 – Rob

+0

FWIW、これはSergeyが彼の答えで行っていた場所のようです... – Rob

答えて

1

あなたのファイルがお使いの携帯電話の代わりに、[:videoURL NSURL URLWithString]に存在する場合は、これを試してみてください。

NSData * fileData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:videoURL]];

+0

fileDataはnilを返しました – George

+0

あなたはvideoURLを記録できますか? –

+0

これはvideoURLファイルです:///var/mobile/Media/DCIM/102APPLE/IMG_2187.MOV – George

2
  1. この行を考えてみましょう:

    var videoDataURL = info[UIImagePickerControllerMediaURL] as! NSURL! 
    

    これは(それがnilだった場合、アプリがクラッシュするので、悪いです)info[UIImagePickerControllerMediaURL]の強制アンラップを行い、それはオプションの暗黙的に開封されたとして、それをキャストNSURL!。それは意味をなさない。ただ、条件付きのアンラップ(およびNSURL、ないNSURL!にアンラップ)の操作を行います。

    if let videoDataURL = info[UIImagePickerControllerMediaURL] as? NSURL { ... } 
    
  2. を次の行にはfilePathURLを呼び出します。

    var videoFileURL = videoDataURL.filePathURL 
    

    ファイルのURLを望んでいた場合、あなたが既に持っています、変換は必要ありませんが、代わりにvideoDataURLを使用してください。これだけのオリジナルvideoDataURLを使用し、

    let videoPath = videoDataURL.path 
    

    率直に言って、Appleは離れて、文字列のパスを使用してから私たちをシフトしようとしていると、パスとfilePathURLの両方の使用を避ける:あなたは本当にパスを望んでいた場合、あなたはpathメソッドを使用したいです。あなたはdataWithContentsOfMappedFileを使用している

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

    あなたが本当にdataWithContentsOfMappedFileを使用したい場合は、適切なスウィフト構文は次のとおりです。

    let video = NSData(contentsOfMappedFile: videoPath!) 
    

    しかしdataWithContentsOfMappedFileは非推奨、あなたの代わりに使用する必要がありますので:

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

    または、bypas videoPathは完全に、あなたができると歌う:

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

    、それらはレンディションは、catchブロックで何ブロック内で行う必要がありますしてみてください。

  4. ちなみに、上のすべての例でわかるように、できる限りletを使用する必要があります。

率直に言えば、私はNSDataにロードすることをお勧めします。 NSFileManagerでコピーすると、メモリをより効率的に使用できます。ビデオが長い場合、それはかなり大きくなる可能性があります。また、特定の時点でメモリにすべてのものを読み込まないようにする必要があります。

だから、可能性:Webサービスにこれをアップロードする場合は

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) 
    } 
} 

、あなたは、ファイルやストリームのオプションを使用して、NSURLSessionUploadTaskを使用すると思います。このリクエストの作成は別の質問ですが、写真や動画などの大きなアセットの場合は、できるだけ避けたい場合はNSDataをアセットにインスタンス化しないでください。

関連する問題