'The video from the core data is not displayed
in swift UIKit
Via PHPickerViewController
Choose the video and store it in the core data successfully
result.itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier) { url, err in
do {
if let urls = url {
let localURL = FileManager.default.temporaryDirectory.appendingPathComponent(urls.lastPathComponent)
try? FileManager.default.removeItem(at: localURL)
try FileManager.default.copyItem(at: urls, to: localURL)
DispatchQueue.main.sync {
coreDateHelperMedia().storeMedia(urlImg: UIImage.init(), videoURL: urls, types: "video")
self.collection.reloadData()
}
}
} catch let error {
print("Error",error)
}
}
This is the url
- _url : file:///Users/badrshammry/Library/Developer/CoreSimulator/Devices/7986A27F-7026-45E1-9073-78CCD6A9B90A/data/Containers/Data/Application/E0C76BFB-16C0-4C65-A80C-9D931FFC1EB9/tmp/8bbab7eb-1530-46b2-8bfa-6e9d9262354e.mp4
And when you press it in cell in didSelectItemAt This url comes from the core data
- _url : file:///Users/badrshammry/Library/Developer/CoreSimulator/Devices/7986A27F-7026-45E1-9073-78CCD6A9B90A/data/Containers/Data/Application/E0C76BFB-16C0-4C65-A80C-9D931FFC1EB9/tmp/.com.apple.Foundation.NSItemProvider.ZUVWZt/8bbab7eb-1530-46b2-8bfa-6e9d9262354e.mp4
Here I am playing the video
let dataUrl = arrS1[indexPath.row]
let urlvideo = dataUrl.videoSection?.absoluteString
guard let url = URL(string: urlvideo!) else {return}
let player = AVPlayer(url: URL(fileURLWithPath:url.path))
playerController = AVPlayerViewController()
playerController.player = player
playerController.allowsPictureInPicturePlayback = true
playerController.delegate = self
present(playerController, animated: true) {
player.play()
}
The problem is that it is stuck in the process of running
the coreDateHelperMedia()
//MARK: - Store
func storeMedia (urlImg : UIImage , videoURL : URL , types : String){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context: NSManagedObjectContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "MediaEntity", in: context)
let coreDataObject = NoteEntity(entity: entity!, insertInto: context)
coreDataObject.setValue(urlImg, forKey: "img")
coreDataObject.setValue(videoURL, forKey: "video")
coreDataObject.setValue(types, forKey: "typeString")
coreDataObject.setValue(UUID(), forKey: "id")
do {
try context.save()
} catch let error {
print(error.localizedDescription)
}
}
//MARK: - Fetch
func fetchMedia ()->[MediaModel]{
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return []
}
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "MediaEntity")
var items : [MediaModel] = []
do {
items.removeAll()
let coreDataObjects = try managedContext.fetch(fetchRequest)
for item in coreDataObjects {
var textItem = MediaModel.init()
let image = item.value(forKey: "img")
let video = item.value(forKey: "video")
let type = item.value(forKey: "typeString")
let uid = item.value(forKey: "id")
if let vid = video ,let img = image , let udidd = uid {
textItem.img = img as! UIImage
textItem.video = vid as! URL
textItem.typeString = type as! String
textItem.id = udidd as! UUID
items.append(textItem)
}
}
return items
} catch let error as NSError {
print(error)
}
return []
}
Solution 1:[1]
A video is a bunch of Data or in practise a file in the file system. You aren't storing any video to your database. You are storing a URL that references a file in a temporary directory which you actively did by choosing FileManager.default.temporaryDirectory. That directory is temporary and doesn't survive long.
What you need to do is:
- Copy the video to your apps document directory where it will remain persistent over multiple app launches.
- Store a reference to the video as a relative URL. Store the name of the video in core data and rebuild the entire URL each time you want it.
You can always locate the app document directory via NSSearchPathForDirectoriesInDomains e.g:
enum AppURLS {
static func documentsDirectory() -> URL {
guard let docspath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last else {
fatalError("unable to get system docs directory - serious problems")
}
return URL(fileURLWithPath: docspath)
}
}
And your storage function will look like this:
func storeMedia (videoURL : URL) {
let name = videoURL.lastPathComponent
let note = NoteEntity(etc)
note.video = name //only store name
let target = AppURLS.documentsDirectory().appendingPathComponent(name)
try FileManager.default.copyItem(at: videoURL, to: target)
}
When you want the video back again use the name stored in the video property to rebuild the source URL and give that to your video player.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |


