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)?
Related
I'm trying to enable Sync with MongoDB Realm on my iOS app. The app already uses Realm DB, but I'm having trouble creating the schemas for my classes due to some less primitive variables. How would you write the following classes as schema (I'm mostly having trouble with List<Assignment> and the LinkingObjects variables)?
class Course: Object{
#objc dynamic var _id: ObjectId = ObjectId.generate()
#objc dynamic var _partitionKey: String = ""
#objc dynamic var name: String = ""
var days = List<String>()
let assignments = List<Assignment>()
}
class Assignment: Object{
#objc dynamic var _id: ObjectId = ObjectId.generate()
#objc dynamic var _partitionKey: String = ""
#objc dynamic var name: String = ""
var parentCourse = LinkingObjects(fromType: Course.self, property: "assignments")
}
With Realm, you don't need to 'write schemas' - it's done for you based on the properties of your classes.
For example, when an Realm object is defined in your app, when the app first Sync's to MongoDB Realm Cloud the objects schema is auto-generated. So for example let say I have an app that tracks people and their dogs. If I create the following Object in my app
class Person: Object {
#objc dynamic var _id = ObjectId.generate()
#objc dynamic var _partitionKey = ""
#objc dynamic var name = ""
}
and run the app, as soon as the app 'speaks' to MongoDB Realm, an object will be created on the server and in your local file with schema based on those Person properties. Nothing more is required or even needed
On the topic of primitives, Realm Collections do not support primitives (very well).
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 they should be avoided. If you want to store objects in Lists, create a Realm object with the primitive as the property.
In your question you have
var days = List<String>()
this should be changed to
class DayClass: Object {
#objc dynamic var date = ""
}
let days = List<DayClass>()
Realm does not support queries on a List of primitives and also doesn't support aggregative function on primitives (yet)
What that means is by storing another object within the List, you can use functions like .sum, .min, .max, .count etc. on those objects.
You code is very close and LinkingObjects are perfect. So just a slight change for the List and everything should work as is.
I have an object as below
#objcMembers class MyObject: Object {
dynamic var name: String = ""
dynamic var myArray = List<MyArray>()
}
class MyArray: Object {
#objc dynamic var number = 0
#objc dynamic var text = ""
}
How can I get number of occurrences of a keyword in text.
Suppose text contain sentences like
This world is very beautiful. This is correct
This is a beautiful car
So if I search for This, I should get 3.
If I search for beautiful, I should get 2
The first thing to do it to modify the code to make it more readable.
List properties are defined like this and I also changed the property name to better match what it is (not an array)
class MyObject: Object {
#objc dynamic var name: String = ""
let textList = List<TextClass>() //fixed definition
}
while we're at it, lets update the object stored in that list with a better fitting class name
class TextClass: Object {
#objc dynamic var number = 0
#objc dynamic var text = ""
}
And then here's the code to read in all of the MyObject objects, iterate over the textList property and count the total amount of occurrences of a given word.
let myObjectResults = realm.objects(MyObject.self)
let wordToFind = "This" //the word to find
for obj in myObjectResults {
var count = 0
let theList = obj.textList
for textObj in theList {
let wordCount = textObj.text.lowercased().components(separatedBy: wordToFind.lowercased()).count - 1
count += wordCount
}
print("object: \(obj.name) had: \(count) occuranced of string: \(wordToFind)")
}
and the results when searching for the word 'This'
object: some object had: 3 occurrences of string: This
When searching for the word Beautiful here's the output
object: some object had: 2 occurrences of string: Beautiful
The reason we're using iteration in the case is because we're actually performing a substring search of the realm property text. While Realm filtering is great at returning Results objects where objects property(s) match a particular query, it's not great at internal string manipulation.
There may be an NSPredicate solution as well.
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.
I have Realm data model
import RealmSwift
class Priority: Object {
dynamic var id = ""
dynamic var text = ""
dynamic var time = ""
}
And I can get all the stored objects
let realm = try! Realm()
let objects = realm.objects(Priority)
How to move an object from the index 7 in the index 3 and save the table?
Objects stored in a Realm are unordered. If you want to store an ordered list of objects you can do so using a List<T> property on a model class. List provides mutation methods that can be used to change the order of objects within the list.
You can put the Objects in Realm List, then you can use both move and swap methods to reorder.
Here is the List API: https://realm.io/docs/swift/latest/api/Classes/List.html
I want to use Realm to my iOS app but I have a problem with the relationship. What I want to achieve is a relationship between the following two RLMobjects :
class Catalogue: RLMObject {
dynamic var ID = ""
dynamic var greekName = ""
dynamic var deutschName = ""
dynamic var createdAt = NSDate()
dynamic var updatedAt = NSDate()
override class func primaryKey() -> String? {
return "ID"
}
}
class Products: RLMObject {
dynamic var foodName = ""
dynamic var foodDescription = ""
dynamic var foodPrice = ""
dynamic var createdAt = NSDate()
dynamic var updatedAt = NSDate()
dynamic var category: Catalogue?
}
I am retrieving all my data from a server in JSON format and the problem is that
I can not set the category as relationship to Catalogue ID.
In my database the category field is a foreign key to the Catalogue ID.
Does anyone knows how can I do that in Realm?
Thank you in advance.
Rather than storing the Catalogue ID in the dynamic var category: Catalogue? relationship field you will need to find the Catalogue object and just store that directly. This is how you link objects and is an important and powerful part of using NoSQL type DB's like Realm.
I would also add an array of products relationship on Catalogue so that you can link all the products to the Catalogue itself.
You can see more discussion about this here if that wasn't fully clear. Hope this helps