首页 > 解决方案 > 如何使用 tableView 和 Realm 创建和保存一对多关系(父子)

问题描述

我正在尝试在领域中创建一对多关系,也称为父子关系。我查看了领域提供的文档,但我仍然对如何实际保存到领域有些困惑。我有两个视图,主视图是一个视图控制器,它只有一个带有数字 1-7 的 tableview。在这个视图中,我可以批量选择编辑表格中的这些行并将它们保存到领域。那部分没什么大不了的。

在下一个视图中,我有一些非常相似的东西,其中有一个只有一些示例数据的表格视图。有一个批量选择行按钮,很好,这是我遇到问题的保存按钮。此 tableView 中的数据(仅出于测试目的而对所有这些数据都相同)是我希望与第一个视图上的数据建立子关系的数据。

例如,如果我有 4 个保存到领域,我单击上面有 4 个的行,它会将我带到我的下一个视图。这个表格视图有两行和其他数据,但我希望能够批量选择这些行并将它们作为一个孩子保存到 4。我对保存到领域功能的外观有点困惑。

这是我的第一个视图控制器

    import UIKit
import Realm
import RealmSwift

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!
    var realm: Realm!

    fileprivate var createSaves = SaveClass.createSaves()

    var testingBool = false
    var values: [String] = []
    var valuesTwo: [String] = []
    var valuesThree: [String] = []

    @IBOutlet weak var itemBtn: UIBarButtonItem!

    @IBOutlet weak var saveBtn: UIBarButtonItem!

    override func viewDidLoad() {
        super.viewDidLoad()
        print(Realm.Configuration.defaultConfiguration.fileURL!)
        realm = try! Realm()
        self.tableView.delegate = self
        self.tableView.dataSource = self
    }


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return createSaves.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
        cell.txtLbl?.text = "\(createSaves[indexPath.row].label)"
        return cell
    }


    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if testingBool == true {
            values.append(createSaves[indexPath.row].label)
            valuesTwo.append(createSaves[indexPath.row].romanNum)
            valuesThree.append(createSaves[indexPath.row].txt)
        } else if testingBool == false {
            performSegue(withIdentifier: "segue", sender: indexPath)
        }
    }

    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        if testingBool == true {
            if let index = values.index(of: createSaves[indexPath.row].label) {
                values.remove(at: index)
            }
            if let index = valuesTwo.index(of: createSaves[indexPath.row].romanNum) {
                valuesTwo.remove(at: index)
            }
            if let index = valuesThree.index(of: createSaves[indexPath.row].txt) {
                valuesThree.remove(at: index)
            }
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let nxtVC = segue.destination as? TestingViewController
        let myIndexPath = self.tableView.indexPathForSelectedRow!
        let row = myIndexPath.row
        nxtVC?.realmedData = createSaves[row].label
    }

    @IBAction func btnPressed(_ sender: Any) {
        testingBool = !testingBool
        if testingBool == true {
            tableView.allowsMultipleSelection = true
            tableView.allowsMultipleSelectionDuringEditing = true
            itemBtn.title = "cancel"
        } else if testingBool == false {
            tableView.allowsMultipleSelection = false
            tableView.allowsMultipleSelectionDuringEditing = false
            itemBtn.title = "item"
        }

    }

    @IBAction func saveBtnPressed(_ sender: Any) {
        if testingBool == true {
            //favorite(label: values)
            realmed(label: values, romanNum: valuesTwo, txt: valuesThree)
        }
    }

    func realmed(label: [String], romanNum: [String], txt: [String]) {
        try? realm!.write {
            for (stringOne, (stringTwo, stringThree)) in zip(label, zip(romanNum, txt)) {
                let realmed = Realmed(label: stringOne, romanNum: stringTwo, txt: stringThree)
                realm.add(realmed)
            }
        }
    }


}

这是我的第二个观点

    import UIKit
import Realm
import RealmSwift

class TestingViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {


    @IBOutlet weak var mainLbl: UILabel!

    var realm: Realm!
    var realmedData = ""
    var testingBool = false
    var values: [String] = []
    var valuesTwo: [String] = []

    @IBOutlet weak var testTable: UITableView!

    @IBOutlet weak var selectBtn: UIButton!

    @IBOutlet weak var saveBtn: UIButton!

    let firstSave = OtherSave.otherArrOne()

    override func viewDidLoad() {
        super.viewDidLoad()
        realm = try! Realm()
        self.testTable.delegate = self
        self.testTable.dataSource = self
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        if objectExists(label: realmedData) == true {
            self.mainLbl.text = "\(realmedData)"
        } else {
            self.mainLbl.text = "Don't Know"
        }
    }


    @IBAction func selectBtnPressed(_ sender: Any) {
        testingBool = !testingBool
        if testingBool == true {
            testTable.allowsMultipleSelection = true
            testTable.allowsMultipleSelectionDuringEditing = true
        } else if testingBool == false {
            testTable.allowsMultipleSelection = false
            testTable.allowsMultipleSelectionDuringEditing = false
        }
    }

    @IBAction func saveBtnPressed(_ sender: Any) {
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return firstSave.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell2", for: indexPath) as! TestingTableViewCell
        cell.nameLbl.text = "\(firstSave[indexPath.row].name)"


        return cell
    }
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if testingBool == true {
            values.append(firstSave[indexPath.row].info)
            valuesTwo.append(firstSave[indexPath.row].name)
        }
    }

    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        if testingBool == true {
            if let index = values.index(of: firstSave[indexPath.row].info) {
                values.remove(at: index)
            }
            if let index = valuesTwo.index(of: firstSave[indexPath.row].name) {
                valuesTwo.remove(at: index)
            }
        }
    }



    func fetchingLabel(label: String) -> Realmed? {
        let realm = try? Realm()
        return realm?.object(ofType: Realmed.self, forPrimaryKey: label)
    }


    func objectExists(label: String) -> Bool {
        return realm.object(ofType: Realmed.self, forPrimaryKey: label) != nil
    }

}

这是父级的领域对象:

    import Foundation
import Realm
import RealmSwift

class Realmed: Object {
    @objc dynamic var label = ""
    @objc dynamic var romanNum = ""
    @objc dynamic var txt = ""
    let realmTwo = List<RealmTwo>()

    override static func primaryKey() -> String {
        return "label"
    }


    convenience init(label: String, romanNum: String, txt: String) {
        self.init()
        self.label = label
        self.romanNum = romanNum
        self.txt = txt
    }

}

这是孩子的领域对象

    import Foundation
import UIKit
import Realm
import RealmSwift

class RealmTwo: Object {
    @objc dynamic var spanish = String()
    @objc dynamic var french = String()
    let realmed = LinkingObjects(fromType: Realmed.self, property: "realmTwo")
}

我试图做一个类似于第一个视图控制器的功能:

    func realmed(label: [String], romanNum: [String], txt: [String]) {
    try? realm!.write {
        for (stringOne, (stringTwo, stringThree)) in zip(label, zip(romanNum, txt)) {
            let realmed = Realmed(label: stringOne, romanNum: stringTwo, txt: stringThree)
            realm.add(realmed)
        }
    }
}

但我真的不明白如何创建要保存为数组的数据实例。

如果有什么我可以帮忙的,请询问 谢谢

标签: iosswiftuitableviewrealm

解决方案


我假设您想从“values”和“valuesTwo”创建“RealmTwo”对象并将它们添加到 Realmed 对象。

你想做的是

  1. 获取父对象(Realmed)
  2. 创建一个子对象(RealmTwo)
  3. 将子对象附加到父对象

你可以用这样的函数来做到这一点。

    func save() {

        let realmed = fetchingLabel(label: realmedData)! // fetch a parent
        do {
            try realm.write {
                for index in 0..<values.count {
                    let realmTwo = RealmTwo()            // create a child
                    realmTwo.french = values[index]
                    realmTwo.spanish = valuesTwo[index]
                    realmed.realmTwo.append(realmTwo)    // append
                }
            }
        } catch {
        }
    }

推荐阅读