Swift 3 - 从核心数据中获取价值

Posted

技术标签:

【中文标题】Swift 3 - 从核心数据中获取价值【英文标题】:Swift 3 - Get value from core data 【发布时间】:2018-02-20 22:57:02 【问题描述】:

我有一个需要 2 个输入的类,Sets 和 Reps

使用 prepare(for segue: UIStoryboardSegue, sender: Any?) 我将值传递回 WorkoutViewController.Swift

数据保存成功,因为在 SetRepsViewController.Swift 中按下保存栏按钮后弹出窗口

但是标签不显示值 我在这里做错了什么 我相信 targetLog?.setAndrep?.sets 没有正确获得价值

有人可以帮我解决我应该怎么做吗?

viewController的屏幕截图

WorkoutViewController.swift

import UIKit
import CoreData


class WorkoutViewController: UIViewController

var muscleLog: MuscleList?
var targetLog: Log?


@IBOutlet weak var LogTableView: UITableView!

@IBOutlet weak var input: UITextField!
@IBOutlet weak var weightInput: UITextField!
@IBOutlet weak var repsInput: UITextField!
@IBOutlet weak var dateView: UILabel!
@IBOutlet weak var setsLabel: UILabel!
@IBOutlet weak var repsLabel: UILabel!


let dateFormatter = DateFormatter()

func workoutTitle(title: String)
    self.title = title





override func viewDidLoad() 
    super.viewDidLoad()

    dateFormatter.calendar = Calendar(identifier: .persian)
    dateFormatter.dateFormat = "dd/MM/yyyy"
    let date = Date()
    let dateInPersian = dateFormatter.string(from: date)

    dateView.text = dateInPersian





override func viewWillAppear(_ animated: Bool) 



    setsLabel.text = targetLog?.repLog?.sets
    repsLabel.text = targetLog?.setAndrep?.reps



override func prepare(for segue: UIStoryboardSegue, sender: Any?) 

    if segue.identifier == "addTarget"
        guard let destination = segue.destination as? SetRepsViewController else 
            return
        
        destination.destLog = targetLog
    




override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.


//hide keybaord method
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
    self.view.endEditing(true)




@IBAction func addLog(_ sender: Any) 

    let weight = Double(weightInput.text ?? "") ?? 0.0
    let reps = Int16(repsInput.text ?? "") ?? 0
    let todayDate = dateView.text ?? ""
    let notes = input.text ?? ""

    if let log = Log(weight: weight, reps: reps, currentday: todayDate, notes: notes)
        muscleLog?.addToDailyLogs(log)

        do
            try log.managedObjectContext?.save()
        catch 
            print("Could not Log")
        
    
    LogTableView.reloadData()




func deleteMuscle(at indexPath: IndexPath)
    guard let logs = muscleLog?.logList?[indexPath.row],
        let managedContext = logs.managedObjectContext else
            return
    
    managedContext.delete(logs)

    do
        try managedContext.save()

        LogTableView.deleteRows(at: [indexPath], with: .automatic)

    catch
        print("Could not save")
        LogTableView.reloadRows(at: [indexPath], with: .automatic)
    


 


 extension WorkoutViewController: UITableViewDelegate,UITableViewDataSource 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return muscleLog?.logList?.count ?? 0


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let WorkCell = LogTableView.dequeueReusableCell(withIdentifier: "WorkCell", for: indexPath)

    if let logs = muscleLog?.logList?[indexPath.row] 
        WorkCell.textLabel?.text = logs.currentday

        let weight = String(logs.weight)
        let reps = String(logs.reps)
        let note = logs.notes

        WorkCell.detailTextLabel?.text = weight + " kg x " + reps + " reps  Notes: "+note!
    

    return WorkCell


func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 
    if editingStyle == .delete
        deleteMuscle(at: indexPath)
    



SetRepsViewController.swift

import UIKit

class SetRepsViewController: UIViewController 

var destLog: Log?

@IBOutlet weak var setText: UITextField!
@IBOutlet weak var repText: UITextField!



@IBAction func saveTarget(_ sender: UIBarButtonItem) 


    let sets = setText.text ?? ""
    let reps = repText.text ?? ""

    if let target = SetRep(sets: sets, reps: reps)
        destLog?.addsetAndrep(target)
        do
            try target.managedObjectContext?.save()

            self.navigationController?.popViewController(animated: true)
        catch
            print("Could not save workout")
        
    






override func viewDidLoad() 
    super.viewDidLoad()

    // Do any additional setup after loading the view.


override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.





【问题讨论】:

你应该在viewWillAppear而不是viewDidLoad中设置标签。 @pbasdf 我也把它放在 viewWillApear 中,但没有用 destLogtargetLog 是如何声明和填充的? @pbasdf 使用 prepare for segue 函数覆盖 func prepare(for segue: UIStoryboardSegue, sender: Any?) if segue.identifier == "addTarget" guard let destination = segue.destination as? SetRepsViewController else return destination.destLog = targetLog targetLog == nil 吗?你是怎么设置的? 【参考方案1】:

@IMan 将数据保存到核心数据后,您必须从 CoreData 获取数据,然后才能显示您的数据。

【讨论】:

你知道我如何获取数据吗,我尝试了很多方法,我不确定如何获取一对一关系的数据【参考方案2】:

您需要在您的prepareForSegue 中设置destLog 的值,方法是确定在tableView 中选择了哪一行:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    if segue.identifier == "addTarget"
        guard let destination = segue.destination as? SetRepsViewController else 
            return
        
        let indexPath = LogTableView.indexPathForSelectedRow
        targetLog = muscleLog?.logList?[indexPath.row]
        destination.destLog = targetLog
    

这将确保与表视图中选定行对应的 Log 传递给 SetRepsViewController。当您关闭 SetRepsViewController 时,viewWillAppear 代码将正确更新标签,因为 targetLogdestLog 都引用同一个 Log 对象。

【讨论】:

它给出了线程 1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) segue 连接到场景中的哪个元素?我以为它是原型细胞?【参考方案3】:

@IMan 试试这个

func fetchList()

 let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    let fetchRequest: NSFetchRequest<"YOUR ENTITY NAME"> = ("YOUR ENTITY NAME").fetchRequest()

    do 
        let fetchResults = try self.moc.fetch(fetchRequest)

        for Entity in fetchResults as [NSManagedObject] 

            let entity1 = Entity.value(forKey: "YOUR ENTITY KEY VALUE") 
            let entity12 = Entity.value(forKey: "YOUR ENTITY KEY VALUE") 


   print(entity1, entity2)



     catch 

        print(error.localizedDescription)
    

【讨论】:

以上是关于Swift 3 - 从核心数据中获取价值的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Firebase 数据库中的 autoID 获取价值 - Swift

一对多关系核心数据获取数据

NSSortDescriptor 从 Swift 4 的核心数据中获取密钥

swift 3 - 核心数据关系 - 获取数据

如何在核心数据swift 3中同时保存和获取

Swift 从实体(核心数据)获取特定的 NSManagedObject