Izzuddin Cheras Izzuddin Cheras - 6 months ago 71
Swift Question

ios swift play video uploaded from cloudkit

I am trying to play a video downloaded from cloudkit. I use the same query method that I use for downloading image:

publicData.performQuery(query, inZoneWithID: nil) { results, error in
if error == nil { // There is no error
for cafe in results! {
let newCafe = Cafe()
newCafe.address = cafe["address"] as? String
newCafe.name = cafe["name"] as? String
newCafe.email = cafe["email"] as? String
newCafe.description = cafe["description"] as? String
newCafe.location = cafe["location"] as? CLLocation
newCafe.cafeImage = cafe["cafeImage"] as? CKAsset
newCafe.offer_wifi = cafe["offer_wifi"] as? Bool
newCafe.smoking_area = cafe["smoking_area"] as? Bool
newCafe.cafeVideo = cafe["video"] as? CKAsset // <== I want to use this
self.cafes.append(newCafe)
let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()

defaults.setInteger(self.cafes.count, forKey: "PreviousCafeCount")


dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
Spinner.sharedLoader.hideLoading()
})


inside the cafeDetailViewController, I create a button that trigger playing a video using AVPlayer. AVKit and AVFoundation are already imported.

@IBAction func playVideo(sender: AnyObject) {
if let file = cafeDetail.cafeVideo {
let player = AVPlayer(URL: file.fileURL)
let playerController = AVPlayerViewController()

playerController.player = player
self.addChildViewController(playerController)
self.view.addSubview(playerController.view)
playerController.view.frame = self.view.frame

player.play()
}
}


However the result is this:enter image description here

follow up question: how can I implement model association in swift? Similar to has_many and belongs_to association in rails. I don't think downloading the whole video beforehand is a good solution.

Answer

From what I can see, you need to save the video to a local file and then play that file. This is modified from something I wrote to mess around with CloudKit.

    import UIKit
    import CloudKit
    import AVKit
    import AVFoundation

    class CloudKitTestViewController: UIViewController {

    let publicDatabase = CKContainer.defaultContainer().publicCloudDatabase

    var videoURL: NSURL!

    @IBAction func load(sender: AnyObject) {

        let predicate = NSPredicate(format: "videoName = %@", "nameOfVideoGoesHere")

        activityIndicator.startAnimating()

        let query = CKQuery(recordType: "Videos", predicate: predicate)

        publicDatabase.performQuery(query, inZoneWithID: nil) { (results, error) in
            if error != nil {
                dispatch_async(dispatch_get_main_queue()) {
                    self.notifyUser("Cloud Access Error",
                                    message: error!.localizedDescription)
                }
            } else {
                if results!.count > 0 {
                    let record = results![0]

                    dispatch_async(dispatch_get_main_queue()) {
                        !)

                        let video = record.objectForKey("videoVideo") as! CKAsset

                        self.videoURL = video.fileURL 

                        let videoData = NSData(contentsOfURL: self.videoURL!)

                        let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
                        let destinationPath = NSURL(fileURLWithPath: documentsPath).URLByAppendingPathComponent("filename.mov", isDirectory: false)

                        NSFileManager.defaultManager().createFileAtPath(destinationPath.path!, contents:videoData, attributes:nil)

                        self.videoURL = destinationPath

                        print(self.videoURL)

                    }
                } else {
                    dispatch_async(dispatch_get_main_queue()) {
                        self.notifyUser("No Match Found",
                                        message: "No record matching the address was found")
                    }
                }
            }

            dispatch_async(dispatch_get_main_queue(), {
                self.activityIndicator.stopAnimating()
            })
        }


    }

    override func prepareForSegue(segue: UIStoryboardSegue,
                                  sender: AnyObject?) {
        let destination = segue.destinationViewController as!
        AVPlayerViewController
        let url = videoURL
        print(videoURL)
        destination.player = AVPlayer(URL: url!)
    }

}
Comments