How to insert items at 0 index to the Realm container

随声附和 提交于 2020-01-01 14:25:53

问题


Is there a way to insert new items at the 0 index to the Realm container? I don't see an insert method in the Realm class.

Do I need to use Lists? If the answer is yes, how can I restructure the following code to be able to use Lists and keep the List in constant sync with the Realm container. In other words I'm having a hard time coming up with a good way to keep the Realm container and the List with the same items when adding and removing.

In the following code new items are entered at the last index. How can I restructure it to be able to insert items at the 0 index?

Model class

import RealmSwift

class Item:Object {
    dynamic var productName = ""
}

Main ViewController

let realm = try! Realm()
var items : Results<Item>?

var item:Item?

override func viewDidLoad() {
    super.viewDidLoad()

    self.items = realm.objects(Item.self)
}

func addNewItem(){
        item = Item(value: ["productName": productNameField.text!])
        try! realm.write {
            realm.add(item!)
        }
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.items!.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "reusableCell", for: indexPath)
    let data = self.items![indexPath.row]
    cell.textLabel?.text = data.productName
    return cell
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == UITableViewCellEditingStyle.delete{
        if let item = items?[indexPath.row] {
            try! realm.write {
                realm.delete(item)
            }
            tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
        }
    }
}

Ideally this is what I would like to be able to do when inserting new items in the addNewItem() method...

    item = Item(value: ["productName": inputItem.text!])

    try! realm.write {
        realm.insert(item!, at:0) 
    }

回答1:


Adding a sortedIndex integer property that lets you manually control the ordering of objects is definitely one of the more popular ways to order objects in Realm, however it's quite inefficient. In order to insert an object at 0, you'll then need to loop through every other object and increment its ordering number by 1, meaning you'll end up needing to touch every object of that type in your database in order to do it.

The best practice for this sort of implementation is to create another Object model subclass that contains a List property, keep one instance of it in Realm, and to then add every object to that. List properties behave like normal arrays, so it's possible to very quick and efficient to arrange objects that way:

import RealmSwift

class ItemList: Object {
   let items = List<Item>()
}

class Item: Object {
    dynamic var productName = ""
}

let realm = try! Realm()

// Get the list object
let itemList = realm.objects(ItemList.self).first!

// Add a new item to it
let newItem = Item()
newItem.productName = "Item Name"

try! realm.write {
   itemList.items.insert(newItem, at: 0)
}

You can then use the ItemList.items object directly as the data source for your table view.




回答2:


They're at least two ways to do this:

you can manually add priority as number in your class for.ex:

class Task: Item {
    dynamic var something = ""
    dynamic var priority = 0
}

add to realm:

//you can make priority 2,3,4 etc - 0 will be at the top
let task = Task(something: "Something", priority: 0)

and after retrieve objects:

var tasks: Results<Task>!
viewdidLoad(){
    let realm = try! Realm()
    tasks = realm.objects(Task.self).sorted(byKeyPath: "priority")
}

or you can make date like this:

class Task: Item {
    dynamic var something = ""
    dynamic var created = Date()

    override class func indexedPriority() -> [String]{
        return ["created"]
    }
}

add to realm:

let task = Task(something: "Something")

and after retrieve objects:

var tasks: Results<Task>!
viewdidLoad(){
    let realm = try! Realm()
    tasks = realm.objects(Task.self).sorted(byKeyPath: "created")
}

first one you must update yourself to assign priority, second one will be automatically updated



来源:https://stackoverflow.com/questions/43471106/how-to-insert-items-at-0-index-to-the-realm-container

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!