Reputation: 673
I don't understand why I am failing to print out the properties of my realm result. when I print existingCart[i].${property}, it always give me a default value for all iteration i.
the statement print(existingCart)
has no problem. It contains non default values in the properties. It returns:
Results<Product> <0x7fe5d8f3a770> (
[0] Product {
itemImage = <ffd8ffe0 00104a46 49460001 01000048 00480000 ffe10058 — 232200 total bytes>;
itemName = Ground Beef;
price = 6.53;
unit = 450 g;
quantity = 1;
isInCart = 0;
},
[1] Product {
itemImage = <ffd8ffe0 00104a46 49460001 01000048 00480000 ffe1004c — 153015 total bytes>;
itemName = Chicken Drumsticks;
price = 9.06;
unit = 1.25 kg;
quantity = 1;
isInCart = 0;
},
[2] Product {
itemImage = <ffd8ffe0 00104a46 49460001 01000048 00480000 ffe10058 — 242980 total bytes>;
itemName = Ground Turkey;
price = 6.91;
unit = 450 g;
quantity = 2;
isInCart = 0;
},
[3] Product {
itemImage = <ffd8ffe0 00104a46 49460001 01000048 00480000 ffe10058 — 224128 total bytes>;
itemName = Canned Beans;
price = 1.79;
unit = 398 mL;
quantity = 1;
isInCart = 0;
},
[4] Product {
itemImage = <ffd8ffe0 00104a46 49460001 01000048 00480000 ffe10058 — 252231 total bytes>;
itemName = Frosted Flakes;
price = 9.49;
unit = 1.06 kg;
quantity = 1;
isInCart = 0;
},
[5] Product {
itemImage = <ffd8ffe0 00104a46 49460001 01000048 00480000 ffe1004c — 165948 total bytes>;
itemName = Gouda Cheese;
price = 4.99;
unit = 300 g;
quantity = 1;
isInCart = 0;
}
)
This is how I try to load the data from Realm:
private func loadExistingCart() {
let realm = try! Realm()
let existingCart = realm.objects(Product.self)
print(existingCart) // see above
for i in 0..<existingCart.count {
print(existingCart[i].itemName) // empty string
print(existingCart[i].price) // 0.0
print(existingCart[i].quantity) // 0
print(existingCart[i].unit) // empty string
cart.addItem(existingCart[i]) // adds
}
}
Here is the product class:
import UIKit
import Foundation
import Realm
import RealmSwift
class Product : Object {
// MARK: Properties
@objc var itemImage = Data()
@objc var itemName: String = ""
@objc var price: Float = 0.0
@objc var unit: String = ""
@objc var quantity: Int = 0
@objc var isInCart: Bool = false
convenience init?(itemImage: UIImage?, itemName: String, price: Float, unit: String, quantity: Int, isInCart: Bool = false) {
self.init()
// itemName, unit, category should not be empty
guard (!itemName.isEmpty && !unit.isEmpty) else {
return nil
}
// price should not be a negative number
guard (price >= 0) else {
return nil
}
// Initialize stored properties
self.itemImage = UIImageJPEGRepresentation(itemImage!, 0.9)!
self.itemName = itemName
self.price = price
self.unit = unit
self.quantity = quantity
self.isInCart = isInCart
}
override class func primaryKey() -> String? {
return "itemName"
}
}
This is how products are being saved
private func saveToCart(product: Product, update: Bool) {
let realm = try! Realm()
print(product)
try! realm.write {
realm.add(product, update: true)
}
}
Upvotes: 2
Views: 801
Reputation: 1610
You've made a tiny error in the declaration of the Product class there, and it's just a common gotcha with using Realm.
If you look back over all the Realm examples in their documentation, you'll see that each member field should be declared such as this corrected one:
@objc dynamic var itemImage = Data()
Yep, you've missed out the dynamic
modifier on each of your properties. Go back and add that to each property and it should just start working. For completeness, this should be the properties declaration:_
// MARK: Properties
@objc dynamic var itemImage = Data()
@objc dynamic var itemName: String = ""
@objc dynamic var price: Float = 0.0
@objc dynamic var unit: String = ""
@objc dynamic var quantity: Int = 0
@objc dynamic var isInCart: Bool = false
You can google the dynamic
keyword for an explanation. It's based on the fact that the object you have is just a proxy to a database object, and Realm needs to intercept the property access to actually interrogate the database and retrieve the value of the property. You can see the same effect as your problem if you ever try to look at an object in the debugger - it's just full of the default values.
Upvotes: 2
Reputation: 5584
I'm not familiar enough with how Realm works to say why you can't seem to access the objects by index, but perhaps you could try accessing them as part of a Sequence instead?
let existingCart = realm.objects(Product.self)
for item in existingCart {
print(item.itemName)
print(item.price)
print(item.quantity)
print(item.unit)
}
Upvotes: 0