我有以下实体和关系
我希望能够将练习设置为常规名称关系的nil结果,如果这有意义的话?以便以后可以在形成例程实体时将其设置为例程名称。
我的问题是,你如何设置这种属性?我正在尝试以下代码,但它会导致致命的崩溃:
userExercise.usersroutine?.name = nil
我的逻辑是我参加练习并遵循与name属性的关系并将其设置为nil?
感谢您对我的逻辑进行任何更正和澄清
编辑:添加了我现有的练习和例行保存功能
func createExercise() {
guard let managedObjectContext = managedObjectContext else { return }
if let userExercise = userExercise {
userExercise.name = userExerciseName.text
userExercise.sets = Int64(userSetsCount)
userExercise.reps = Int64(userRepsCount)
userExercise.weight = Double(self.userExerciseWeight.text!)!
userExercise.id = UUID().uuidString
userExercise.routine = nil
}
do {
try managedObjectContext.save()
} catch {
fatalError("Failure to save context: \(error)")
}
}
常规创作:
func createRoutine() {
guard let managedObjectContext = managedObjectContext else { return }
let userRoutine = UserRoutine(context: managedObjectContext)
userRoutine.name = workoutNameTextfield.text
do {
try managedObjectContext.save()
} catch {
fatalError("Failure to save context: \(error)")
}
}
当前获取请求:
fileprivate lazy var fetchedResultsController: NSFetchedResultsController<UserExercise> = {
let fetchRequest: NSFetchRequest<UserExercise> = UserExercise.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "id", ascending: true)]
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.persistentContainer.viewContext, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self
return fetchedResultsController
答案 0 :(得分:1)
请检查下面的实施我已经创建了一些练习和例程。同时阅读代码中的注释,这将有助于您弄清楚如何去做。
添加新练习的功能
func createExercise(weight: Int16, respetitions: Int16, name: String, routine: Routine?)->Exercise? {
let context = getMainContext()
let exercise = NSEntityDescription.insertNewObject(forEntityName: "Exercise", into: context) as! Exercise
exercise.setValue(weight, forKey: "weight")
exercise.setValue(name, forKey: "name")
exercise.setValue(respetitions, forKey: "rep")
do {
try context.save()
return exercise
}
catch
{
fatalError("unable to Ssavve")
}
}
添加新例程的功能
func createRoutine(name: String, exercises:[Exercise]) {
let context = getMainContext()
let routine = NSEntityDescription.insertNewObject(forEntityName: "Routine", into: context) as! Routine
routine.name = name
//Iterate over Exercise objects & check if routine is nil.
//Here if routine is not nil it menas your exercise is already assigned to a routine.
//If routine is nil assign routine.addToRelationship(<#T##value: Exercise##Exercise#>) and Also assign routine to the execise.
do {
try context.save()
}
catch
{
fatalError("unable to Ssavve")
}
}
获取主NSManagedObjectContext的函数,我们可以在其上执行核心数据操作
func getMainContext() -> NSManagedObjectContext {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
return appDelegate.persistentContainer.viewContext
}
下面,首先我创建一些与例程没有任何关系的练习
&#34;创建练习时,例程不存在,之后创建练习并设置其名称&#34;
然后通过传递一些练习(You can refer to other answer on how to fetch exercises with routine as nil values)
来创建例程func initializer() {
//I'm adding exercises first without routines
let ex1 = self.createExercise(weight: 10, respetitions: 4, name: "Exercise1", routine: nil)
let ex2 = self.createExercise(weight: 5, respetitions: 10, name: "Exercise2", routine: nil)
let ex3 = self.createExercise(weight: 20, respetitions: 2, name: "Exercise3", routine: nil)
let ex4 = self.createExercise(weight: 5, respetitions: 10, name: "Exercise2", routine: nil)
self.createRoutine(name: "Routine 1", exercises: [ex1!, ex2!]) //You can pass all the exercises or use fetch request to query exercises with routine as nil
self.createRoutine(name: "Routine 2", exercises: [ex3!, ex4!])
self.createRoutine(name: "Routine 3", exercises: [ex1!, ex2!]) //This routine shall not be adding any execises as they are already added to othe routines
}
更新create routine函数以查询UserExercise的结果,其中usersroutine为nil
func createRoutine() {
guard let managedObjectContext = managedObjectContext else { return }
let userRoutine = UserRoutine(context: managedObjectContext)
userRoutine.name = workoutNameTextfield.text
//Getting nil value User Exercises
let request: NSFetchRequest<UserExercise> = UserExercise.fetchRequest()
request.predicate = NSPredicate(format: "usersroutine == nil")
do {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let queryResults = try context.fetch(request)
//I like to check the size of the returned results!
print ("num of results = \(queryResults.count)")
//You need to convert to NSManagedObject to use 'for' loops
for exercise in queryResults as [NSManagedObject] {
//get the Key Value pairs (although there may be a better way to do that...
print("Exercise NAME: \(exercise.value(forKey: "name"))")
}
} catch {
print("Error with request: \(error)")
}
do {
try managedObjectContext.save()
} catch {
fatalError("Failure to save context: \(error)")
}
}
答案 1 :(得分:0)
您似乎根本不需要使用name
属性。此属性应用于存储UserRoutine
的实际名称,而不是基于任何关系。
核心数据中的实体之间的关系不依赖于实体的特定属性,而是依赖于实体本身。
&#34;我希望例程构建器查看练习并将关系中的所有练习导入nil&#34;
因此...
创建获取请求以获取UserExercise
的所有不具有相关UserRoutine
的实体(即userroutine
为零)。
let orphanedExerciseFetchRequest = NSFetchRequest(entityName: "UserExercises")
orphanedExerciseFetchRequest.predicate = NSPredicate(format: "userroutine == nil)
执行此获取请求以获取UserExercises数组(没有相关例程)
let orphanedExercises = managedObjectContext.executeFetchRequest(orphanedExerciseFetchRequest())
&#34;使用归因练习创建例程&#34;
将提取的UserExercise
权限属性userRoutine
设置为您的例程(并且不要忘记在管理对象上下文中保存更改)。
myRoutine.userexercises = orphanedExercises
稍后,如果您想要针对特定例程进行练习:
let fetchRequest = NSFetchRequest(entityName: "UserExercises")
fetchRequest.predicate = NSPredicate(format: "userroutine == %@", someUserRoutine)