简体   繁体   中英

How to insert items at 0 index to the Realm container

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 List s? If the answer is yes, how can I restructure the following code to be able to use List s 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) 
    }

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM