Eco Apps
Eco Apps

Reputation: 53

Unable to save, access and modify a 'List' in Realm database in Swift code

I am trying to build an app where the user can add notes to any item in a collection view. I want to update the list in Realm database as user adds a note.

I am using Realm database version "realm-swift-0.98.4" which is the latest version which can be used with Swift 2.1.1 Using such an old version of Realm as I didn't want to update to Xcode 8 and Swift 3 after reading many negative reviews about them. I have some experience with Swift and totally new to Realm..

Here is the model of my data:

import Foundation
import RealmSwift
import Realm

class ItemEntry: Object {
    dynamic var title = ""
    dynamic var counts = 0
    let noteAndTimeEntryList = List<noteAndTimeEntryObj>()

    convenience init(title: String) {
        self.init()
        self.title = title
    }
}

class noteAndTimeEntryObj: Object {
    dynamic var timeStampOfNote: NSDate?
    dynamic var note: String? = ""
}

Here is the code for displaying Items and adding notes to it:

import UIKit
import RealmSwift
import Realm

var ItemsList = [ItemEntry(title: "A"),ItemEntry(title: "B"),ItemEntry(title: "C"),ItemEntry(title: "D")]

override func viewDidLoad() {
    super.viewDidLoad()
    let realm = try! Realm()
    try! realm.write {
        realm.add(ItemsList)
    }
    saveButton.addTarget(self, action: "saveNoteButtonTapped:", forControlEvents: UIControlEvents.TouchUpInside)

    …
    …
}

Displaying the Items:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath      indexPath:NSIndexPath)->UICollectionViewCell {
    var  cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! ItemCollectionViewCell
    cell.titleLabel.text = ItemsList[indexPath.row].title
    return cell
}

Saving note:

func saveNoteButtonTapped(sender: UIButton) {
    guard let selectedCellRow = rowOfLongPressedItem else {
        return // rowOfLongPressedItem was nil
    }

    let realm2 = try! Realm()
    let ItemsListTemp = realm2.objects(ItemsList)

    var selectedItem = ItemsList[selectedCellRow]
    selectedItem.counts += 1
    var latest = selectedItem.counts - 1

    let noteTimePair = noteAndTimeEntryObj()

    noteTimePair.timeStampOfNote = NSDate()
    noteTimePair.note = noteTextField.text

    selectedItem.noteAndTimeEntryList.append(noteTimePair)

    ItemsList[selectedCellRow] = selectedItem

    let realm3 = try! Realm()

    realm3.beginWrite()
    ItemsList.append(selectedItem)
    do {
        try realm3.commitWrite()
    } catch let error {
        // Handling write error,
        // e.g. Delete the Realm file, etc.
        print("UNABLE to append 'selectedItem' to Itemslist")
    }

    notePopup.hidden = true
    notePopup.endEditing(true)
    noteTextField.text = ""
}

At the lines below, I am getting an error "Cannot convert value of type '[ItemEntry]' to expected argument type 'Object.Type'"

let realm2 = try! Realm()
let ItemsListTemp = realm2.objects(ItemsList)

I didn't have these 2 lines of code before. I added them because I was getting this error on executing code and trying to Save a note: "Terminating app due to uncaught exception 'RLMException', reason: 'Attempting to modify object outside of a write transaction - call beginWriteTransaction on an RLMRealm instance first.'"

Can someone please help me... Please post the correct code to

Upvotes: 0

Views: 639

Answers (1)

Nate Mann
Nate Mann

Reputation: 673

Not really sure what you are trying to do.

First, add an ItemsList Object to noteAndTimeEntryObj

class noteAndTimeEntryObj: Object {
   dynamic var timeStampOfNote: NSDate?
   dynamic var note: String? = ""
   dynamic var itemsList = ItemsList()
}

Then, change your noteAndTimeEntryList to

let noteAndTimeEntryList = LinkingObjects(fromType: noteAndTimeEntryObj.self, property: "itemsList")

This will make it an auto-updating.

Then, in add the ItemsList object when you create an new notAndTimeEntry

let noteTimePair = noteAndTimeEntryObj()

noteTimePair.timeStampOfNote = NSDate()
noteTimePair.note = noteTextField.text
notTimePare.itemsList = ItemsListTemp

Get rid of selectedItem.noteAndTimeEntryList.append(noteTimePair)

Then save your noteTimePair. I think your function should look like this:

func saveNoteButtonTapped(sender: UIButton) {
   guard let selectedCellRow = rowOfLongPressedItem else {
       return // rowOfLongPressedItem was nil
   }

   let realm = try! Realm()
   let itemsList = realm2.objects(ItemsList)

   var selectedItem = ItemsList[selectedCellRow]

   try! realm.write {
      selectedItem.counts += 1

      let noteTimePair = noteAndTimeEntryObj()

      noteTimePair.timeStampOfNote = NSDate()
      noteTimePair.note = noteTextField.text
      noteTimePair.itemsList = selectedItem
      realm.add(noteTimePair)
   }

   notePopup.hidden = true
   notePopup.endEditing(true)
   noteTextField.text = ""
}

Upvotes: 1

Related Questions