How to get all the objects in which an object is a property of them?


#1

class House: Object {
@objc dynamic var address: Address?
}

class Shop: Object {
@objc dynamic var address: Address?
}

class Address: Object {}

if I have an Address object, how can I get all the objects (Shop and House) which associate with it, or at least get the objects count.


#2

Just make 2 inverse relationship, and you are good to go.


#3

Lets use a concrete example using a direct approach:

Suppose you have three objects as outlined in your question

class Address: Object {
    @objc dynamic var street: String?
}

class House: Object {
    @objc dynamic var address: Address?
}

class Shop: Object {
    @objc dynamic var address: Address?
}

Let’s create some objects and store in Realm. Define two addresses a0, a1 and three houses h0, h1, h2 ensuring that house 0 and 2 have address a0. And lets create a shop as well (s0) and give it address 0.

let a0 = Address()
a0.street = "123 Here Road"

let a1 = Address()
a1.street = "456 There Road"

let h0 = House()
h0.address = a0

let h1 = House()
h1.address = a1

let h2 = House()
h2.address = a0

let s0 = Shop()
s0.address = a0

and write it to realm

try! realm.write {
    realm.add(h0)
    realm.add(h1)
    realm.add(h2)
    realm.add(s0)
}

Now let’s suppose we want to get the object with address which starts with 123 and then get a count of houses and shops that are associated with that address. I am not including any real error checking for brevity

let addressResults = realm.objects(Address.self).filter("street BEGINSWITH[cd] '123'")
let myAddressObject = addressResults.first!

let houseResults = realm.objects(House.self).filter("address == %@", myAddressObject)
print("house count: \(houseResults.count)")

let shopResults = realm.objects(Shop.self).filter("address == %@", myAddressObject)
print("shop count: \(shopResults.count)")

and the results

house count: 2
shop count: 1

As an alternate solution, you can define a relationship between the address, houses and shops. Keeping the house and shop object as above, change the address object like so

class Address: Object {
    @objc dynamic var street: String?
    
    let houses = List<House>()
    let shops = List<Shop>()
}

then create some objects and write to realm.

let h0 = House()
let h1 = House()
let h2 = House()

let s0 = Shop()

let a0 = Address()
a0.street = "123 Here Road"
a0.houses.append(h0)
a0.houses.append(h1)
a0.shops.append(s0)

let a1 = Address()
a1.street = "456 There Road"
a1.houses.append(h2)

then to get the count of houses and shops for each address:

let addressResults = realm.objects(Address.self)

for address in addressResults {
    let street = address.street!
    let houseCount = address.houses.count
    let shopCount = address.shops.count
    print("street: \(street) has \(houseCount) houses and \(shopCount) shops")
}

and the output

street: 123 Here Road has 2 houses and 1 shops
street: 456 There Road has 1 houses and 0 shops