I have wishlistVC that has collection view like the picture below:
I have product realm model like this:
class Product : Object {
@objc dynamic var productID : String = ""
@objc dynamic var name : String = ""
@objc dynamic var unitPrice: Double = 0.0
@objc dynamic var quantity = 0
@objc dynamic var descriptionProduct : String = ""
@objc dynamic var hasBeenAddedToWishList : Bool = false
@objc dynamic var hasBeenAddedToCart : Bool = false
@objc dynamic var isNewProduct : Bool = false
var imagePaths = List<String>()
}
and WishList realm model like this:
class WishList : Object {
@objc dynamic var userID: String = ""
var products = List<Product>() // many to many relationship
static func getWishListFromRealmDatabase() -> WishList {
let userID = "1"
let allWishList = RealmService.shared.realm.objects(WishList.self)
let theWishList = allWishList.filter("userID CONTAINS[cd] %@", userID).first
if let userWishList = theWishList {
return userWishList
} else {
// WishList never setted up before in Realm database container
// then create WishList in realm database
let newWishList = WishList()
newWishList.userID = userID
newWishList.products = List<Product>()
RealmService.shared.save(object: newWishList)
return newWishList
}
}
static func addProductToWishListRealmDatabase(userWishList: WishList, selectedProduct: Product) {
// to check wheter the selected product from user is already in WishList or not
if userWishList.products.filter("productID == %@", selectedProduct.productID).first == nil {
RealmService.shared.save(expression: {
selectedProduct.hasBeenAddedToWishList = true
userWishList.products.append(selectedProduct)
})
}
}
}
when the user tap that love button, here is the code used to add product to WishList:
func addProductToWishListRealmDatabase(userWishList: WishList, selectedProduct: Product) {
// to check wheter the selected product from user is already in WishList.products or not
if userWishList.products.filter("productID == %@", selectedProduct.productID).first == nil {
// write in realm database
RealmService.shared.save(expression: { // <-- this is just a wrapper to avoid write do try catch block all over the place
selectedProduct.hasBeenAddedToWishList = true
userWishList.products.append(selectedProduct)
})
}
}
and here is the full simplified code of my WishListVC:
class WishListVC : UIViewController {
@IBOutlet weak var wishListCollectionView: UICollectionView!
private var userWishList : WishList?
private var products = List<Product>()
private var selectedProduct : Product?
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
userWishList = WishList.getWishListFromRealmDatabase() // the definition is in the code above
guard let userWishList = userWishList else {return}
products = userWishList.products
}
}
extension WishListVC : ListProductCellDelegate {
func likeButtonDidTapped(at selectedIndexPath: IndexPath, productHasBeenLiked: Bool, collectionView: UICollectionView) {
guard let userWishList = userWishList else {return}
let selectedProduct = products[selectedIndexPath.item]
if productHasBeenLiked {
WishList.removeProductFromWishListRealmDatabase(userWishList: userWishList, selectedProduct: selectedProduct)
} else {
WishList.addProductToWishListRealmDatabase(userWishList: userWishList, selectedProduct: selectedProduct)
}
wishListCollectionView.reloadData()
self.wishListCollectionView.isHidden = userWishList.products.isEmpty
}
}
if I append a product to the wishlist model
like the code above, it will affect to the Product.self in realm database, it will keep adding the product in 'Product Realm Database', as you can see in the image below, there are 9 data in Product, but as you can see some of the product have the same productID, there are 3 products that have 'a' as the productID .
so how to avoid adding the product that has the same productID in 'Product Realm Database' (Product.self) when I modify the WishList
by appending the product to wishlist.products ?
I have also tried to add primary key using:
override static func primaryKey() -> String? {
return "productID"
}
but It makes crash with message:
*** Terminating app due to uncaught exception 'RLMException', reason: 'Attempting to create an object of type 'Product' with an existing primary key value 'a'.'
it will throw error because I add productID = 'a'
what should I do ? how to append product to the WishList model but I also can avoid adding the same product that has the same productID to the Product Realm database model (Product.self) ?
do I use the wrong approach to add the product to the wishlist?