I am new to realm and iOS development so I apologize in advance if something isn’t explained properly or is just incorrect.
I have 2 Realm Object classes:
class Category: Object {
#objc dynamic var name: String = ""
#objc dynamic var color: String = ""
let trackers = List<Tracker>()
}
and
class Tracker: Object {
#objc dynamic var timeSegment: Int = 0
var parentCategory = LinkingObjects(fromType: Category.self, property:
"trackers")
}
I’m able to store new timeSegment properties consistently; however, the issue is that I cannot retrieve & display a collection of timeSegment values relating to their parentCategory. setting
var entries : Results<Tracker>?
produces all results for every category, which is the only result i'm able to pull so far after testing.
Any help is appreciated, and can follow up with any additional details. Thanks
You need to call objects on your Realm object with a filter for fetching only results that match a predicate. The realm object in this code is an instance of the Realm class.
func getTrackersWithName(_ name: String) -> Results<Tracker> {
return realm.objects(Tracker.self).filter("name = \"\(name)\"")
}
This tells Realm to fetch all objects that match the filter predicate. In this case, the filter predicate matches any object where the value of the "name" property matches the string that is passed into the method.
Related
I'm using Realm Swift for the following code:
class Item: Object {
#Persisted(primaryKey: true) var name = ""
#Persisted(originProperty: "items") var collection: LinkingObjects<SomeCollection>
}
class SomeCollection: Object {
#Persisted(primaryKey: true) var name = ""
let items = List<Item>()
}
On app startup when I initialize the Realm instance I got:
Property 'SomeCollection.items' declared as origin of linking objects property 'Item.collection' does not exist" UserInfo={NSLocalizedDescription=Schema validation failed due to the following errors:
Interestingly, if I change the line for LinkingObjects to:
let collection = LinkingObjects(fromType: SomeCollection.self, property: "items")
it then works fine, however, after adding an Item instance to the items list of SomeCollection, the collection property of Item instance doesn't show any linked SomeCollection, which I thought should be linked automatically?
What am I doing wrong here?
Thanks for help!
This
let items = List<Item>()
Needs to be this
#Persisted var items = List<Item>()
or
#Persisted var items: List<Item>
depending on the use case.
The let syntax is how we used to do it.
That's called and Inverse Relationship and is covered in the documentation a bit further.
I have the following Realm data structure:
class Pair {
#objc dynamic var kanji: String? = nil
let kana = List<String>()
}
I need to look up an entry in the Realm the Pair.kana property of which has the same elements. How do I achieve that (preferably using NSPredicate)?
I'm experiencing slightly unusual behaviour when attempting to use computed properties to access linked Objects in a Realm Object subclass.
final class Patient: Object {
dynamic var name: String = ""
var parameters = List<Parameter>()
}
final class Parameter: Object {
dynamic var name: String = ""
dynamic var patient: Patient? {
return LinkingObjects(fromType: Patient.self, property: "parameters").first
}
}
The patient property on the Parameter class returns nil but, if you replace the code with the following, we get the expected behaviour:
var p = LinkingObjects(fromType: Patient.self, property: "parameters")
var q: Patient? {
return p.first
}
I suspect this is something to do with Realm's internal representation of LinkingObject. The code I used originally was referenced in a previous StackOverflow question and was accepted as a functional solution thus I guess it worked then so perhaps something has changed? Xcode 7, Swift 2.2
When Realm added the ability to query inverse relationships, that became the syntax to specify them. See https://realm.io/news/realm-objc-swift-0.100.0/ and https://realm.io/docs/swift/latest/#inverse-relationships for details.
I've got a number of user properties in a user viewcontroller class ie
//user vars
var email: String?
var givenName: String?
var familyName:String?
var phone: String?
var dob: NSDate?
In a method within that class i retrieve user data from coredata and set the user text fields with that data in a loop
for i in 0 ..< userTextFields.count {
let field = userTextFields[i]
let fieldName = userTextFieldKeyNames[i]
let fieldText = currentUser.valueForKey(fieldName) as? String
field.text = fieldText
}
the fieldName variable in the loop matches the class's ivars above. Is there a way i can reference the ivars within the loop by matching it with the fieldName string so I can set the values of the ivars with the fetched coredata values ie in a literal sense saying something like the following ...
if self.property.name.text == fieldName {
self.property.value == fieldText
}
ie somehow resolving the various property names withing the class ... or is this bad design? .... if so any suggestions on achieving the same result in a better way
Not Swift-ish, as it's bypassing compile time type checking. Best option is to keep them all in a dictionary, and use a protocol to define allowed data types in the dictionary, but even that is rather poor
I have a a class similar to this:
class Flight: Object {
dynamic var flightNumber = ""
dynamic var departureApt = ""
dynamic var arrivalApt = ""
dynamic var nextFlight : Flight?
dynamic var previousFlight : Flight?
}
A 'flight' may contain nextFlight and/or previousFlight, but it is not guaranteed. My goal is to query for a flight and check if it is a child of another flight (either next or previous of a parent flight).
Before Realm 0.100 i retrieved the parent by using this code:
if let parent = flight.linkingObjects(Flight.self, forProperty: "previousFlight").first {
print("This flight has a parent flight: \(parent.flightNumber)")
}
I am now unsure how to achieve the same with Realm 0.100 and would love some feedback!
EDIT
I have now been able to achieve the result I wanted, but I am not sure if it is the correct way to do it. I have added a variable that finds the parent this way:
let parentForNext = LinkingObjects(fromType: Flight.self, property: "nextFlight")
let parentForPrevious = LinkingObjects(fromType: Flight.self, property: "previousFlight")
var parent : Flight? {
get {
return parentForNext.first ?? parentForPrevious.first ?? nil
}
}
The Object.linkingObjects(_:property:) method was deprecated in Realm Swift 0.100 (see release post for more).
This is because there's a more powerful (though slightly more verbose) way to declare inverse relationships in Realm: through the LinkingObjects property type on models. This allows linking objects to behave like live, auto-updating List properties or Results queries. So you know the objects you get back will never be out of date, which is especially important given that all other Realm types auto-update. It also allows querying inverse relationships as if they were forward relationships (List properties).
So if you did this before 0.100:
let parent = flight.linkingObjects(Flight.self, forProperty: "previousFlight").first
The equivalent is this in 0.100 and later (on the model):
let parents = LinkingObjects(fromType: Flight.self, property: "previousFlight")
var parent: Flight? { return parents.first }
In your second code sample, you have multiple "parents", and yes you can have a computed property that combines them in whatever way you like:
let nextParent = LinkingObjects(fromType: Flight.self, property: "nextFlight")
let previousParent = LinkingObjects(fromType: Flight.self, property: "previousFlight")
var parent: Flight? { return nextParent.first ?? previousParent.first }
You can read more about inverse relationships in Realm's docs on the subject: https://realm.io/docs/swift/latest/#inverse-relationships