Reputation: 649
I have a json data save in core data and save it in an array, and I want to encapsulated the array I have save in core data. the problem is when I want to display it in app it only retrieve 1 data in array. which is suppose I have a 5. here I show my code
this is a my function fetch request my json data
APIServices.shared.fetchData(url: APIServices.youtubeBaseURL, params: params, of: Item.self) { (items) in
let privateContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
privateContext.parent = CoreDataManager.shared.persistenceContainer.viewContext
var newVideos = [Video]()
items.forEach({ (item) in
let video = Video(context: privateContext)
video.title = item.snippet.title
video.videoId = item.id.videoId
newVideos.append(video)
do {
try privateContext.save()
try privateContext.parent?.save()
} catch let saveErr {
print("Failed to save json data:", saveErr)
}
})
DispatchQueue.main.async {
self.videos = newVideos
self.collectionView.reloadData()
self.showLoadingHUD()
}
}
this is a code in my encapsulated in my collectionViewCell
var video: Video? {
didSet{
let context = CoreDataManager.shared.persistenceContainer.viewContext
let fetchRequest = NSFetchRequest<Video>(entityName: "Video")
do {
let videos = try context.fetch(fetchRequest)
videos.forEach { (video) in
titleLabel.text = video.title
guard let videoId = video.videoId else { return }
DispatchQueue.main.async {
let playerVars: [String : Any] = [
"playsinline" : 0,
"enablejsapi": 1,
"wmode": "transparent",
"controls": 1,
"showinfo": 0,
"rel": 0,
"modestbranding": 1,
"iv_load_policy": 3 //annotations
]
self.player.load(withVideoId: videoId, playerVars: playerVars)
}
}
} catch let fetchErr {
print("Failed to fetch video:", fetchErr)
}
}
}
after I fetch the core data and try to print video inside videos.forEach the value is there not only one value. but when I try to load with youtube player, it only display one value.
Upvotes: 0
Views: 155
Reputation: 9652
For your solution,
Create a videoModel
variable in your UICollectionViewCell
class like, and remove fetchRequest
call in UICollectionViewCell
class which is causing the issue,
var videoModel: VideoModel? {
didSet {
titleLabel.text = videoModel?.videoTitle
let playerVars: [String : Any] = [
"playsinline" : 0,
"enablejsapi": 1,
"wmode": "transparent",
"controls": 1,
"showinfo": 0,
"rel": 0,
"modestbranding": 1,
"iv_load_policy": 3 //annotations
]
self.player.load(withVideoId: videoModel?.videoId ?? "", playerVars: playerVars)
}
}
ViewModel
file should look like,
import Foundation
struct VideoModel {
var videoTitle: String?
var videoId: String?
init(title: String, id: String) {
videoTitle = title
videoId = id
}
}
Then in SearchViewController
, create a viewModels
array and assign the videoModel
your your cell in cellForItemAt
datasource method,
var videoModels = [VideoModel]()
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: videoId, for: indexPath) as! SearchVideoCell
let video = videos[indexPath.row]
cell.delegate = self
cell.video = video
cell.videoModel = videoModels[indexPath.row]
return cell
}
Finally in fetchVideosWith
append viewModel
to your viewModels
array,
//MARK:- Fetch Data
fileprivate func fetchVideosWith(title name: String) {
let params = ["part": "snippet", "q": "tausiyah \(name)", "key": "AIzaSyC2mn0PTL8JmSWEthvksdJLvsnwo5Tu9BA"]
APIServices.shared.fetchData(url: APIServices.youtubeBaseURL, params: params, of: Item.self) { (items) in
let privateContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
privateContext.parent = CoreDataManager.shared.persistenceContainer.viewContext
var newVideos = [Video]()
items.forEach({ (item) in
let video = Video(context: privateContext)
video.title = item.snippet.title
video.videoId = item.id.videoId
newVideos.append(video)
do {
try privateContext.save()
try privateContext.parent?.save()
} catch let saveErr {
print("Failed to save json data:", saveErr)
}
let videoModel = VideoModel(title: item.snippet.title, id: item.id.videoId)
self.videoModels.append(videoModel)
})
DispatchQueue.main.async {
self.videos = newVideos
self.collectionView.reloadData()
self.showLoadingHUD()
}
}
}
Hope it helps.
Upvotes: 1