How do I save an audio file to iCloud using Swift?

Viewed 1432

I have created an app using Swift 3 and Xcode 8.3.3 that records audio files and saves them to the app's Document directory. I would now like to save these files to iCloud to have them backed up. I have been able to save a simple record to iCloud using this code:

let database = CKContainer.default().publicCloudDatabase

func saveToCloud(myContent: String){
    let myRecord = CKRecord(recordType: "AudioRecording")
    myRecord.setValue(myContent, forKey: "content")
    database.save(myRecord) { (record, error) in
        print(error ??  "No error")
        guard record != nil else {return}
        print("Saved record to iCloud")
    }
}

It seems like I should just need to add a line of code that would look something like this:

newNote.setValue(audioObject, forKey: "Audio")

But I'm not sure what object I need to pass it for audioObject and if iCloud will be able to handle the object. Any suggestions?

2 Answers

This is the same exact process if you wanted to save/read a video file

Here is how to write an audio file. Save it as a CKAsset:

func save(audioURL: URL) {

    let record = CKRecord(recordType: "YourType")

    let fileURL = URL(fileURLWithPath: audioURL.path)

    let asset = CKAsset(fileURL: fileURL)

    record["audioAsset"] = asset

    CKContainer.default().publicCloudDatabase.save(record) { (record, err) in
        if let err = err {
            print(err.localizedDescription)
            return 
        }
        if let record = record { return }
        print("saved: ", record.recordID)
    }
}

Here is how to read the audio file from a CKAsset:

func fetchAudioAsset(with recordID: CKRecord.ID) {

    CKContainer.default().publicCloudDatabase.fetch(withRecordID: recordID) { 
        [weak self](record, err) in

        DispatchQueue.main.async {

            if let err = err {
                print(err.localizedDescription)
                return 
            }

            if let record = record { return }

            guard let audioAsset = record["audioAsset"] as? CKAsset else { return }

            guard let audioURL = audioAsset.fileURL else { return }

            do {
        
                self?.audioPlayer = try AVAudioPlayer(contentsOf: audioURL)

            } catch {
                print(error.localizedDescription)
            }
        }
    }
}
Related