ios - 封装核心数据对象

标签 ios swift core-data persistence encapsulation

我有一个json数据保存在core data中,保存在一个数组中,我想封装我在core data中保存的数组。问题是当我想在应用程序中显示它时,它只检索数组中的 1 个数据。假设我有一个 5。这里我显示我的代码

这是我的函数获取请求我的 json 数据

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()
            }
        }

这是我封装在我的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)
        }
    }
}

在我获取核心数据并尝试在 videos.forEach 中打印视频后,该值不只有一个值。但是当我尝试加载 youtube 播放器时,它只显示一个值。

only one object return

最佳答案

对于您的解决方案,

在您的 UICollectionViewCell 类中创建一个 videoModel 变量,并删除 UICollectionViewCell 类中的 fetchRequest 调用导致问题,

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 文件应该是这样的,

import Foundation

struct VideoModel {
    var videoTitle: String?
    var videoId: String?

    init(title: String, id: String) {
        videoTitle = title
        videoId = id
    }
}

然后在 SearchViewController 中,创建一个 viewModels 数组并将 videoModel 分配给您在 cellForItemAt 数据源方法中的单元格,

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
    }

最后在 fetchVideosWith 中将 viewModel 附加到您的 viewModels 数组,

//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()
                }
            }
    }

希望对您有所帮助。

关于ios - 封装核心数据对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53975439/

相关文章:

iphone - 使用 RestKit 发布导致发布 nil 对象

ios - 核心数据 : How to get data of entity in relationship?

ios - UILabel 换行后不显示文字

swift - 从 ViewController 传递数据

ios - 午睡 JSON 响应

swift - Core Data 中的哪些查询可以从属性的 R-Tree 索引中受益?

ios - Xcode 5 Assets 目录 : How to automatically pick LaunchImage at correct size

objective-c - 防止在 TableView 处于编辑模式时更新 NSFetchedResultsController

ios - 视频媒体类型不工作的 MPMediaPickerController

ios - 子上下文未保存在核心数据中