Storing media to CloudKit as CKAsset works for images only, no longer for videos

921 Views Asked by At

I am having an issue with saving videos to CloudKit as CKAsset. While the example code below works for saving images only (set videoSelection to false), I was able to use it in the past also for storing videos to CloudKit. I am currently using XCode 11.3 with the Swift programming language and simulators and physical devices with iOS 13.2 installed. The debugger indicates that the Asset data is retrieved correctly in func imagePickerController after selecting the video with complete URL. When trying to write video CKAsset data to iCloud, an error message is generated, including "connection to service on pid 0 named com.apple.cloudd".

import UIKit
import CloudKit
import AVKit
import AVFoundation

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
 let videoSelection: Bool =  false //if true, then select video, if false select image
 var SelectedAsset: CKAsset? = nil
 var imagePicker = UIImagePickerController()

    func iCloud_WriteRecord()
       {
        let newCloudRecord = CKRecord (recordType: "TestRecordType", recordID: CKRecord.ID (recordName: "myRecordID0001"))
        newCloudRecord.setValue (SelectedAsset, forKey: "CKAssetField")
        CKContainer(identifier: "iCloud.CLCO.INT45.Activity01").privateCloudDatabase.save (newCloudRecord) { (record, error) in

            if record != nil {
                   if (error != nil) {
                       print("error 1")
                       return;
                   }

                   print("success")
               }
               else
               {
                   print("error 2")
                   return;
               }

           }
       }

    @IBAction func SelectImageOrMedia(_ sender: UIButton) {

        if videoSelection {imagePicker.mediaTypes = ["public.movie"]} else {imagePicker.mediaTypes = ["public.image"]}

        imagePicker.sourceType =  .photoLibrary
        imagePicker.delegate = self
        imagePicker.allowsEditing = true
        present (imagePicker, animated: true, completion: nil)

    }

          func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
           {

               if let image = info[UIImagePickerController.InfoKey.editedImage]
                   as? UIImage //image
               {
                let mediaAsset = CKAsset(fileURL: info[UIImagePickerController.InfoKey.imageURL] as! URL)
                SelectedAsset = mediaAsset
                imagePicker.dismiss(animated: true, completion: nil)
                return;

               }
               else //video
               {

                let mediaAsset = CKAsset(fileURL: info[UIImagePickerController.InfoKey.mediaURL] as! URL)
                let tmpVideoURL: String = mediaAsset.fileURL!.absoluteString
                SelectedAsset = mediaAsset
                imagePicker.dismiss(animated: true, completion: nil)

                return;
               }


           } //func

    @IBAction func SaveTestRecord(_ sender: UIButton) {

               iCloud_WriteRecord()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
}

I am able to check that it works for images by verifying on CloudKit dashboard that a new record with an Asset field of a certain size (e.g. 47kB) has been properly added after executing the code in SelectImageOrMedia(), imagePickerController() and iCloud_WriteRecord() in that order. When trying the same thing for videos (with videoSelection=true), the debugger indeed indicates that mediaAsset (CKAsset) has been initialized correctly with a complete url-path. However, any attempt to write the video asset using iCloud_WriteRecord() in the code generates the following error message without storing the record:

Got a connection error for operation 2676FFA25279B538: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service on pid 0 named com.apple.cloudd" UserInfo={NSDebugDescription=connection to service on pid 0 named com.apple.cloudd}

The technique described above used to work before, not only for images but also for videos.

Any assistance with solving this issue will be much appreciated!

1

There are 1 best solutions below

0
Carl On

I was able to figure out by myself how to solve the problem. It turned out that the asset file was deleted automatically before the asset could be dispatched. Copying the video file (through code) to a non-temporary location before initializing the asset did the trick. The solution seemingly works on both simulators and physical devices.