2016-11-30 27 views
0

我有以下實體和關係如何通過關係設置實體屬性?

enter image description here

我希望能夠設置一個運動有它的例程名關係的零結果,如果是有道理的?以便在日常實體形成時可以將其設置爲例程名稱。

我的問題是,你如何設置這種屬性?我想下面的代碼,但它會導致嚴重的崩潰:

userExercise.usersroutine?.name = nil 

我的邏輯是,我走鍛鍊,並按照名稱屬性之間的關係,並將其設置爲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

這是因爲你的usersroutine值本身是零和你正在試圖建立在它之上的名字。說得通?首先嚐試爲例程賦值,然後如果需要將名稱設置爲零。 –

+0

我明白,那麼正確的方法是什麼?簡單地使用userExercise.usersroutine = nil直到我有要設置的名稱? – infernouk

+0

你能否解釋一下你想在Routine和Exercise之間建立什麼樣的關係,以便我更好地理解你的問題並給出一個可行的解決方案。 –

回答

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 
} 

下面,首先我創建一些與例程無關的練習

「例行犯規存在創建練習的時候,它之後創建的,其名稱設置爲」

,然後通過一些練習(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 
    } 
創建例程

更新創建例程查詢UserExercise的用戶程序結果爲零的功能

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)") 
     } 
    } 
+0

即時通訊,直到迭代練習來添加它們/將它們的無例程更改爲例程保存,我無法弄清楚如何要實現該部分,即時通訊使用NSFetchedResultsControllerDelegate我假設使用它來查詢零練習是正確的方法,但不知道如何做到這一點。在覈心數據實體中還需要哪種類型的屬性來存儲練習數組? – infernouk

+0

此外,getUnmappedExercise在我的VC中導致如此多的錯誤,因爲它現在是一個函數,而不是OP中的代碼,是不是可以簡單地編輯該代碼來執行任務? – infernouk

+0

我加了這個函數讓你理解實現部分。查看編輯,我已經刪除了func,嘗試使用這段代碼並告訴我是否看到任何結果(Print語句)。 –

0

似乎並不需要完全使用name屬性。該屬性應該用於存儲UserRoutine的實際名稱,而不是基於任何關係。

Core Data中實體之間的關係不依賴於實體的特定屬性,而是依賴於實體本身之間的關係。

「我想常規建設者看看練習並導入所有零練習的關係到它」

所以......

創建一個讀取請求取所有UserExercise的實體沒有相關的UserRoutine(即userroutine爲零)。

let orphanedExerciseFetchRequest = NSFetchRequest(entityName: "UserExercises") 
orphanedExerciseFetchRequest.predicate = NSPredicate(format: "userroutine == nil) 

執行該讀取請求獲得UserExercises數組(沒有相關的例程)

let orphanedExercises = managedObjectContext.executeFetchRequest(orphanedExerciseFetchRequest()) 

將獲取UserExercise 「與歸屬演習創造一個例行」 entitiy的財產userRoutine到您的日常(並且不要忘記將更改保存在您的託管對象上下文中)。

myRoutine.userexercises = orphanedExercises 

以後,如果你想獲得一個特定的例行演習:

let fetchRequest = NSFetchRequest(entityName: "UserExercises") 
fetchRequest.predicate = NSPredicate(format: "userroutine == %@", someUserRoutine) 
+0

注意:不是用Xcode編寫的,所以可能會有一些拼寫錯誤等,但希望這可以幫助您朝正確的方向發展。 – Simo

+0

謝謝,我用我當前的獲取請求更新了OP,可以修改這個代碼,還是需要一個單獨的方法? – infernouk

+0

試過以下,但即時獲取致命錯誤? fileprivate懶惰VAR fetchedResultsController:NSFetchedResultsController = { 讓orphanedExerciseFetchRequest:NSFetchRequest = UserExercise.fetchRequest() orphanedExerciseFetchRequest.predicate = NSPredicate(格式爲: 「userroutine ==無」) 讓fetchedResultsController = NSFetchedResultsController(fetchRequest:orphanedExerciseFetchRequest ,managedObjectContext:self.persistentContainer.viewContext,sectionNameKeyPath:nil,cacheName:nil) fetchedResultsController.delegate = self return fetchedResultsController}() – infernouk

相關問題