PHImageManager. requestExportSessionForVideoでiCloud動画のダウンロードに失敗する問題

PHImageManager. requestExportSessionForVideoでiCloud動画のダウンロードに失敗する問題

`PHImageManager-requestExportSessionForVideo:options:exportPreset:resultHandler:` でiCloudにある動画のExportに失敗することがあったのでメモ


## 確認環境
* iPhone6s(ストレージ使用率 98%くらい)
* 4G回線
* iCloudフォトライブラリ：ON
    * ストレージ最適化：ON

# 問題のコード

```swift:

let opt = PHVideoRequestOptions()
opt.networkAccessAllowed = true
opt.deliveryMode = .MediumQualityFormat

let exportPreset = AVAssetExportPreset960x540

PHImageManager.defaultManager().requestExportSessionForVideo(strongSelf, options: opt, exportPreset: exportPreset) { (session: AVAssetExportSession?, info: [NSObject : AnyObject]?) in
    if let error = info?[PHImageErrorKey] as? NSError {
        log.error(error.debugDescription)
        return
    }

    guard let session = session else { return }
        
    session.outputURL = outputURL
    session.outputFileType = AVFileTypeQuickTimeMovie
    session.shouldOptimizeForNetworkUse = true

    session.exportAsynchronouslyWithCompletionHandler({
        switch session.status {
        case .Completed:
            // 完了時の処理
        case .Failed:
            if let err = session.error {
                log.error("Failed to export video. cause=\(err.description)")
            }
            session.outputURL?.fileRemove()
        default:
            log.error("Unexpected export status found. status=\(session.status)")
        }
    })
}

```

iCloudにあると思われる動画(`PHImageResultIsInCloudKey: 1`となる)の場合、以下のようなエラーがでて `AVAssetExportSession`が`nil`になる

```swift:
PHImageErrorKey: Error Domain=CloudPhotoLibraryErrorDomain Code=81 "Error fetching asset with identifier: XXXXXXXXXXXXXXXXXX (nonpartial failure)"
UserInfo={NSLocalizedDescription=Error fetching asset with identifier: XXXXXXXXXXXXXX (nonpartial failure), NSUnderlyingError=0x17004e2e0 {Error Domain=CKErrorDomain Code=3 "インターネット接続がオフラインのようです。"
```

そのほかの通信は問題なくできてるので、ネットワークにはつながっているはずなのに :cry: 

`PHVideoRequestOptions.deliveryMode = .Automatic` にしても状況変わらず。
Wi-Fiに接続すると問題なくExportできる。

# 回避策： `requestAVAssetForVideo:options:resultHandler:` を使う 

`requestAVAssetForVideo:options:resultHandler:` を使い、自前でExportSessionを生成することで、無事Exportできるようになった。

```swift:
let opt = PHVideoRequestOptions()
opt.networkAccessAllowed = true
opt.deliveryMode = .MediumQualityFormat

PHImageManager.defaultManager().requestAVAssetForVideo(strongSelf, options: opt, resultHandler: { (avasset, avaudioMix, info) in
    if let error = info?[PHImageErrorKey] as? NSError {
        log.error(error.debugDescription)
        return
    }
    
    guard let avasset = avasset else {
        return
    }
    
    guard let session = AVAssetExportSession(asset: avasset, presetName: AVAssetExportPreset960x540) else {
        return
    }
    
    session.outputURL = outputURL
    session.outputFileType = AVFileTypeQuickTimeMovie
    session.shouldOptimizeForNetworkUse = true

    session.exportAsynchronouslyWithCompletionHandler({
        switch session.status {
        case .Completed:
            // 完了時の処理
        case .Failed:
            if let err = session.error {
                log.error("Failed to export video. cause=\(err.description)")
            }
            session.outputURL?.fileRemove()
        default:
            log.error("Unexpected export status found. status=\(session.status)")
        }
    })
}
```

# 所感
* iCloudにある動画のダウンロードは写真.appでも不安定なのでなんかおかしいのかなー。

# 参考
* [requestExportSessionForVideo:options:exportPreset:resultHandler: - PHImageManager | Apple Developer Documentation](https://developer.apple.com/reference/photos/phimagemanager/1616981-requestexportsessionforvideo)