Filter in realm list swift
This was a very challenging query but I think I have a solution.
First however; Primitives in Realm Lists are not well supported and are not yet queryable. See here and this for more reading.
EDIT: Release 10.7 added support for filters/queries as well as aggregate functions on primitives so the below info is no longer completely valid. However, it's still something to be aware of.
So we will need to add another class to hold the string data
class StringClass: Object {
@objc dynamic var myString = ""
}
so the following class will be updated to match
class ParamsModel: BaseResponse {
var options = List<StringClass>()
}
Then to peform the query we need to leverage a Subquery due to the depth of the objects.
let predicate = NSPredicate(format: "SUBQUERY(customFields, $customField, ANY $customField.params.options.myString == 'custom').@count > 0")
let results = realm.objects(RetailerModel.self).filter(predicate)
This will return all Retailer Models whose CustomFieldsModel has a ParamsModel options List property StringClass myString property equal to 'custom'
Realm List Filter Swift
This error occurs if you try and perform a query on a Realm Swift List
object (Which are actually Objective-C RLMArray
objects under the hood) before its parent object has been added to a Realm
.
class Person: Object {
dynamic var name = ""
dynamic var picture: NSData? = nil // optionals supported
let dogs = List<Dog>()
}
let dog = Dog()
dog.name = "Rex"
let person = Person()
person.dogs.append(dog)
let rex = person.dogs.filter("name == 'Rex'") // QUERY WILL TRIGGER EXCEPTION AT THIS POINT
let realm = try! Realm()
try! realm.write {
realm.add(person)
}
let rex = person.dogs.filter("name == 'Rex'") // Query will now work as expected
In a nutshell, you need to make sure that numbersDetail
belongs to a Realm
before you perform that query. You can easily test this by checking numbersDetail.realm != nil
.
iOS Realm Filter objects in a list of a relationship
Realm doesn't have any sort of concept of a deep-filtered view, so you can't have a Results<Canteen>
which restricts the List
s contained in related objects to vegan meals.
There are several similar things which you can do. You could add inverse relationship properties, and then query Meal
objects instead:
class Canteen: Object {
dynamic var name: String?
let lines = List<Line>()
}
class Line: Object {
dynamic var name: String?
let meals = List<Meal>()
let canteens = LinkingObjects(fromType: Canteen.self, property: "lines")
}
class Meal: Object {
dynamic var name: String?
dynamic var vegan: Bool = false
let lines = LinkingObjects(fromType: Line.self, property: "meals")
}
let meals = realm.objects(Meal).filter("vegan = true AND ANY lines.canteens.name = %@", selectedCanteenType.rawValue)
(Or rather, you will be able to once Realm 0.102.1 is out; currently this crashes).
If you just need to iterate over the meals but need to do so from the Canteen down, you could do:
let canteens = realm.objects(Canteen).filter("name = %@ AND ANY lines.meals.vegan = true", selectedCanteenType.rawValue)
for canteen in canteens {
for line in canteen.lines.filter("ANY meals.vegan = true") {
for meal in line.meals.filter("vegan = true") {
// do something with your vegan meal
}
}
}
This unfortunately has some duplication due to needing to repeat the filter for each level of the references.
How to filter Realm objects by list
try this solution
If you use a to-many relationship, You use an ANY
operator
Please read this well so you understand what to use because there is another operator ex ALL,ANY,NONE
Predicate Programming Guide
private func getDeviceContacts(_ phoneNumbers: [Int64]) -> [DeviceContactModel] {
do {
let realm = try Realm()
let deviceContacts = Array(realm.objects(DeviceContactModel.self).filter("ANY phones.fullNumber IN %@", phoneNumbers))
return deviceContacts
} catch {
debugPrint(error.localizedDescription)
return []
}
}
Realm Swift Filter Query Based On List Property
Let me restate the question;
You want an artist to be able to query for all new shows in cities
they are interested in where they have not yet responded.
If that's the question, let me start with some simple sample data
Two artists that have each have two cities if interest
let a0 = Artist()
a0.name = "Jim"
a0.citiesOfInterest.append(objectsIn: ["Austin", "Memphis"])
let a1 = Artist()
a1.name = "Henry"
a1.citiesOfInterest.append(objectsIn: ["Austin", "Memphis"])
and then two shows, one in each city
let s0 = Show()
s0.name = "Austin Show"
s0.city = "Austin"
let s1 = Show()
s1.name = "Memphis Show"
s1.city = "Memphis"
but artist a0 (Jim) has responded to the s0 (Austin) show
let r0 = ArtistResponse()
r0.show = s0
r0.artist = a0
r0.available = true
s0.artistResponses.append(r0) //jim responded to the Austin show
The result we want is that when Jim the artist logs on, he will see the Memphis show because he already responded to the Austin show.
let realm = try! Realm()
if let jim = realm.objects(Artist.self).filter("name == 'Jim'").first {
let myCities = jim.citiesOfInterest
let showResults = realm.objects(Show.self)
.filter("city IN %@ AND !(ANY artistResponses.artist.name == 'Jim')", myCities)
for show in showResults {
print(show.name)
}
}
And the output is
Memphis Show
We first get the Jim's cities of interest as an array, then we filter the shows that match those cities of interest but where there are no artist responses associated with Jim. This filter was based on the name but you could use the Artist id or even the Artist object itself as the comparator.
How can I filter a Realm List by Date Swift NSPredicates
You would need to use a date range filter. You would need to start the range at a specific date and end it at a certain date. For example,
let predicate = NSPredicate(format: "artSoldDate >= %@ AND artSoldDate <= %@", startDate, endDate)
let result = realm.objects(Art.self).filter(predicate)
Your example seems to try and check when the artSoldDate is exactly some date.
Filter querying multiple objects from Realm using List of Primary Keys
I think you are asking how to query Realm for items that have keys that match a set of keys in an array.
So given a DogClass Realm Object
class DogClass: Object {
@objc dynamic var dog_id = NSUUID().uuidString
@objc dynamic var dog_name = ""
override static func primaryKey() -> String? {
return "dog_id"
}
}
and suppose we know we want to retrieve three dogs that match some given primary keys
let keysToMatch = ["302AC133-3980-41F3-95E8-D3E7F639B769", "54ECC485-4910-44E5-98B9-0712BB99783E", "71FE403B-30CD-4E6C-B88A-D6FDBB08C509"]
let dogResults = realm.objects(DogClass.self).filter("dog_id IN %@", keysToMatch)
for dog in dogResults {
print(dog.dog_id, dog.dog_name)
}
Note the use of IN in the filter, which will match any dogs with id's in the given array.
You can also pass in a Realm List Object instead of a Swift array and get the same result.
let listOfKeysToMatch = List<String>()
listOfKeysToMatch.append("302AC133-3980-41F3-95E8-D3E7F639B769")
listOfKeysToMatch.append("54ECC485-4910-44E5-98B9-0712BB99783E")
listOfKeysToMatch.append("71FE403B-30CD-4E6C-B88A-D6FDBB08C509")
let dogResults2 = realm.objects(DogClass.self).filter("dog_id in %@", listOfKeysToMatch)
for dog in dogResults2 {
print(dog.dog_id, dog.dog_name)
}
How to access the realm model list in filter in swift 4?
Realm
support .filter()
function based on NSPredicate
. So, first you should get ibp_service_filter == true
values:
let filteredServices = chapter.service.filter("ibp_service_filter == true")
and then save only uniq ids (basic idea):
for service in filteredServices where !history_ibp.contains(where: { $0. service_id == service.service_id }) {
history_ibp.append(service)
}
Swift Realm filter List property using an Array
You can't achieve your goals using predicate with Realm because Realm have a lot of limitations using Predicates
and the missing ability to handle computed properties but you can use this way as a workarround
let filterList = ["A","B"]
let realmList = realmInstance?.objects(MyDTO.self)
let filteredArray = Array(realmList!).filter({Array($0.tags).map({$0.tagName}).sorted().joined().contains(filterList.sorted().joined())})
here Array($0.tags).map({$0.tagName}).sorted().joined()
we get the tags array and convert it with map to an array of Strings then we sort that array of Strings (this will ensure that only matters the TAGS in the array not the order) and after that we convert that sorted array in a String by example your array of tags.tagName is ["B","A","C"] and after this you will get "ABC" as STRING
after that we check if that STRING contains your filterList.sorted().joined() the same procedure that was explained before
so if your filterList have ["B","C","A"] you will get "ABC"
and the we check if "ABC" contains "ABC" if so then is included in final result
Related Topics
Cgaffinetransform -How to Align Video in Screen Center
Custom Table View Row Action (Image)
How to Rotate Custom Userlocationannotationview Image Using Mapkit in Swift
Pass Data from Tableview to Tab Bar View Controller in Swift
How to Send a Request with Alamofire with Xml Body
Swift 3:Url Image Makes Uitableview Scroll Slow Issue
Ksecattrkeytypeec Causing Encryptmessagewithpublickey() to Fail
Creating an Irregular Uibutton in Swift Where Transparent Parts Are Not Tappable
Swift:Background Color Fading Animation (Spritekit)
Delegates: Pass Data Without Segue
Facebook Sdk Login Throws Error in Swift 2 iOS 9
How to Get Only Keys from Firebase
Uitableviewcell Shows Incorrect Results from Document Folder
Random Number from an Array Without Repeating the Same Number Twice in a Row
Alamofire Multipart Upload Post Error in Swift
Error in Facebook Login, iOS 9, Swift
How to Transfer Data Between Parent and Child View Controllers
Keep a View Always on Top (Don't Scroll with Keyboard) in Iqkeyboardmanager