如何在 Swift 中将可转换属性保存到 Core Data

Posted

技术标签:

【中文标题】如何在 Swift 中将可转换属性保存到 Core Data【英文标题】:How to save transformable attribute to Core Data in Swift 【发布时间】:2020-08-13 21:08:04 【问题描述】:

我正在构建一个从 TMDB 获取电影数据的 SwiftUI 应用。当用户将电影添加到他们的观看列表时,我试图将数据保存为 Core Data 中的可转换属性。

问题是我无法保存数据。

这是我的核心数据模型

我已经为 TransformableMovie 实体创建了 NSManagedObject NSManagedObject 子类:

TransformableMovie+CoreDataClass.swift

import Foundation
import CoreData

@objc(TransformableMovie)
public class TransformableMovie: NSManagedObject 


TransformableMovie+CoreDataProperties.swift

import Foundation
import CoreData


extension TransformableMovie 

    @nonobjc public class func fetchRequest() -> NSFetchRequest<TransformableMovie> 
        return NSFetchRequest<TransformableMovie>(entityName: "TransformableMovie")
    

    @NSManaged public var movie: MovieClass?


这是我创建的类:

MovieClass.swift

import Foundation

public class MovieClass: NSObject, NSCoding 
    
    var movie: Movie
    
    init(movie: Movie) 
        self.movie = movie
        
    
    required public init?(coder aDecoder: NSCoder) 
        self.movie = aDecoder.decodeObject(forKey: "movie") as! Movie

    
    
    public func encode(with aCoder: NSCoder) 
        aCoder.encode(movie, forKey: "movie")
        
    

这是我试图保存数据的视图(在 navigationBarItems 按钮中)

MovieDetailView.swift

import SwiftUI
import CoreData

struct MovieDetailView: View 
    
    @ObservedObject private var detailVM = MovieDetailViewModel()
    
    // Core data
    @Environment(\.managedObjectContext) var managedObjectContext
    
    var movie: Movie
    
    @State private var showingAlert = false
    
    init(movie: Movie) 
        self.movie = movie
        detailVM.getMovieDetails(id: movie.id)
        
        // Stop Scrollview bounce
        UIScrollView.appearance().bounces = false
    
    
    var body: some View 
        
        VStack 
            
            ...

        .navigationBarTitle(movie.title)
        
        .navigationBarItems(trailing:
                                Button(action: 
                                    
                                    // Save to core data
                                    let movieToBeSaved = TransformableMovie(context: self.managedObjectContext)
                                    
                                    movieToBeSaved.movie?.movie = detailVM.fetchedMovie!
     
                                    self.showingAlert = true
                                    
                                    do 
                                        try self.managedObjectContext.save()
                                     catch 
                                        // handle the Core Data error
                                    
                                ) 
                                    Image(systemName: "plus")
                                        .renderingMode(.original)
                                .alert(isPresented: $showingAlert) 
                                    Alert(title: Text("Saved"), message: Text("Movie added to your watch list"), dismissButton: .default(Text("Ok")))
                                )
        
    

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

我认为问题在于这一行:

movieToBeSaved.movie?.movie = detailVM.fetchedMovie!

movie? 属性为 nil,因此赋值永远不会起作用。从您提供的代码中很难看出,但我认为您需要先创建一个 ModelClass 对象,然后分配它:

let movieModel = ModelClass(movie: detailVM.fetchedMovie)
movieToBeSaved.movie = movieModel

【讨论】:

以上是关于如何在 Swift 中将可转换属性保存到 Core Data的主要内容,如果未能解决你的问题,请参考以下文章

如何使用带有 Swift 的 Core Data 获取非标准(可转换)属性来更新/保存和持久化?

如何将日期类型保存到 Swift Core Data 中实体的属性?

如何在 Swift 中将计算的闭包属性转换为闭包?

如何在 Swift 3 中将自定义类保存为 CoreData 实体的属性?

在 Swift 中将实例变量的属性保存到 Struct 的静态变量数组中

如何在 Swift 3 中将 HTML 文本转换为属性字符串而不丢失换行符 [重复]