query Object from Realm List - swift

enter image description herei'm trying to query object from realm
class MessageRealm: Object {
dynamic var fromId = String()
dynamic var messageID = String()
dynamic var textDownloadded = String()
override class func primaryKey() -> String? {
return "messageID"
}
}
class UsersRealm: Object {
dynamic var sender = String()
let msgs = List<MessageRealm>()
override class func primaryKey() -> String? {
return "sender"
}
}
i have two class one for messages and the other for users, every users have a list of messages and i need to query thats message based on (UserRealm.sender)
This is the realm DB

I solve the issue by this way if anyone face the same
var messageIndex: Results<MessageRealm>!
let realm = try! Realm()
let mssagesRealm = realm.objects(UsersRealm.self).filter("sender = %#", userTitleName)
for sub in mssagesRealm {
messageIndex = sub.msgs.sorted(byKeyPath: "timeStamp")
}

Related

I want to sort the List of RealmSwift

I am using RealmSwift.
Data is a one-to-many relationship.
I'm having trouble because I don't know how to sort the list in RealmSwift.
I want to sort the tasks linked to the TaskList.
Thank you.
class TaskList: Object, Identifiable {
#objc dynamic var id = NSUUID().uuidString
#objc dynamic var title = ""
#objc dynamic var createdAt = NSDate()
var tasks: List<Task> = List<Task>()
override static func primaryKey() -> String? {
return "id"
} }
class Task: Object, Identifiable {
#objc dynamic var id = NSUUID().uuidString
#objc dynamic var title = ""
#objc dynamic var createdAt = NSDate()
private let lists = LinkingObjects(fromType: TaskList.self, property: "tasks")
var list: TaskList { return list.first! }
override static func primaryKey() -> String? {
return "id"
} }
If you want your tasks stored in an ordered fashion you'll have to manually do an ordered insert.
extension List {
func insert<V: Comparable>(_ object: Element, orderedBy keyPath: KeyPath<Element, V>) {
var index = 0
for i in 0..<count {
if self[i][keyPath: keyPath] >= object[keyPath: keyPath] {
break
}
index = i + 1
}
insert(object, at: index)
}
}
let list = TaskList()
let tasks = [
Task(title: "J"),
Task(title: "Z"),
Task(title: "T"),
Task(title: "J"),
Task(title: "Z"),
]
tasks.forEach {
list.tasks.insert($0, orderedBy: \.title)
}
However, I find it much easier to keep Lists unsorted and retrieve sorted Results whenever I need to display the data. To sort by a single property just call sorted(byKeyPath:):
let sortedTasks = taskList.tasks.sorted(byKeyPath: "title")
To sort by multiple fields call sorted(by:):
let sortedTasks = taskList.tasks.sorted(by: [
SortDescriptor(keyPath: "title"),
SortDescriptor(keyPath: "createdAt")
])
Alternatively, you can add a sorted property to your Model:
class TaskList: Object, Identifiable {
#objc dynamic var id = UUID().uuidString
#objc dynamic var title = ""
#objc dynamic var createdAt = Date()
var tasks = List<Task>()
lazy var sortedTasks: Results<Task> = tasks.sorted(byKeyPath: "title")
override class func ignoredProperties() -> [String] {
return ["sortedTasks"]
}
override static func primaryKey() -> String? {
return "id"
}
}
You cannot get a LinkingObjects itself to be sorted, but you can call LinkingObjects.sorted(byKeyPath:), which returns a Results instance containing all elements of the LinkingObjects, just sorted.
class Task: Object, Identifiable {
#objc dynamic var id = NSUUID().uuidString
#objc dynamic var title = ""
#objc dynamic var createdAt = NSDate()
private let lists = LinkingObjects(fromType: TaskList.self, property: "tasks")
lazy var sortedLists = lists.sorted(byKeyPath: "createdAt")
var list: TaskList { return list.first! }
override static func primaryKey() -> String? {
return "id"
}
}
I think this is a one line answer. If you know which TaskList object you want to get the tasks for, and you want them ordered by say, creation date. This will do it
let taskResults = realm.objects(Task.self)
.filter("ANY lists == %#", taskList)
.sorted(byKeyPath: "createdAt")

create Realm DB for each user in Chat App

this one for sending message and save it to realm db
var messageIndex = try! Realm().objects(MessageRealm.self).sorted(byKeyPath: "timeStamp")
func didPressSend(text: String) {
if self.inputContinerView.inputTextField.text! != "" {
let messageDB = MessageRealm()
let realm = try! Realm()
let userRealm = UsersRealm()
messageDB.textDownloadded = text
messageDB.fromId = user!.fromId
messageDB.timeStamp = Date()
print(messageDB)
try! realm.write ({
print(realm.configuration.fileURL)
userRealm.msgs.append(messageDB)
//realm.create(MessageRealm.self, value: ["textDownloadded": text, "fromId": user!.fromId, "timeStamp": Date()])
})
if let userTitleName = user?.toId {
print(userTitleName)
OneMessage.sendMessage(text, thread: "AAAWatree", to: userTitleName, isPhoto: false, isVideo: false, isVoice: false, isLocation: false, timeStamp: date, completionHandler: { (stream, message) in
DispatchQueue.main.async {
OneMessage.sharedInstance.deleteCoreDataMessage()
}
self.inputContinerView.inputTextField.text! = ""
})
}
}
}
This for when recieving message im trying to save user (send id )
let realm = try! Realm()
userData.sender = sender
userData.toId = toUser
print(userData.sender)
print(userData.toId)
try! realm.write ({
realm.add(userData, update: true)
})
this my Realm Object Class
class MessageRealm: Object {
dynamic var textDownloadded = String()
dynamic var imageDownloadded = NSData()
dynamic var videoDownloadded = String()
dynamic var voiceDownloadded = String()
dynamic var fromId = String()
dynamic var timeStamp = Date()
dynamic var messageId = NSUUID().uuidString
let userSelect = List<UsersRealm>()
override class func primaryKey() -> String? {
return "messageId"
}
}
class UsersRealm: Object {
dynamic var sender = String()
dynamic var fromId = String()
dynamic var toId = String()
dynamic var lastMessage = String()
dynamic var timeStamp = Date()
dynamic var profileImage = NSData()
let msgs = List<MessageRealm>()
override class func primaryKey() -> String {
return "sender"
}
}
sending and reciving is ok and its save to realm db but all any user send message i recived in one user i want to seprate for every user have his sending and recive database i miss something here but i dont know i try to search nothing its long question but i cant figure out the soluation
and sorry for my week english
Thank you
If I understood your case correctly you're using a single realm url for all users that's why all your clients have the same data. You should probably create a separate realm for the conversation and share it between the users who participate in that chat. Please learn more about sharing realms in our docs at https://realm.io/docs/swift/latest/#access-control.

Using Realm with MPMediaQuery

I want to build an Audiobookplayer which can set Bookmarks. Loading the Audiobooks from my Library with MPMediaQuery works fine, but when I take an audiobook off through iTunes, it stays in my realmfile.
I would like realm to delete the entry automatically when the playlist is updated through iTunes, but I can't seem to figure out how.
Here is my code.
class Books: Object {
dynamic var artistName: String?
dynamic var albumTitle: String?
dynamic var artwork: NSData?
dynamic var albumUrl: String?
dynamic var persistentID: String?
let parts = List<BookParts>()
override static func primaryKey() -> String? {
return "persistentID"
}
override class func indexedProperties() -> [String] {
return ["albumTitle"]
}
convenience init(artistName: String, albumTitle: String, albumUrl: String) {
self.init()
self.artistName = artistName
self.albumTitle = albumTitle
self.albumUrl = albumUrl
}
class BookQuery {
let realm = try! Realm()
var bookItems = Array<Books>()
var partItems = Array<BookParts>()
func getBooks() {
let query: MPMediaQuery = MPMediaQuery.audiobooks()
query.groupingType = .album
let collection: [MPMediaItemCollection] = query.collections!
try! realm.write {
for allbooks in collection {
let item = allbooks.representativeItem
let book = Books()
let id = item?.value(forProperty: MPMediaItemPropertyAlbumPersistentID) as! Int
book.artistName = item?.artist
book.albumTitle = item?.albumTitle
book.albumUrl = item?.assetURL?.absoluteString
book.artwork = Helper.getArtwork(item?.artwork) as NSData?
book.persistentID = id.stringValue
realm.add(book, update: true)
guard realm.object(ofType: Books.self, forPrimaryKey: "persistentID") != nil else {
continue
}
bookItems.append(book)
}
}
}
}
I calling the MediaQuery in "viewDidLoad" in my LibraryViewController.
I am pretty new to coding and are trying to solve this for a while.
Thanks for any help.
The high level thing you'll need to do is to have a way to detect when the iTunes playlist is updated and then delete the removed items' corresponding objects from the Realm.
A general approach to this is to get all the "persistent ID"s currently in the Realm at the start of the for loop, put those in an array, remove each ID it sees from the array, then delete objects with the persistent ID in the array that's left, since those weren't in the collection.

Realm Adding Object with Compound primaryKey Error

I have a simple class
class FarmRecord: Object {
dynamic var year = ""
dynamic var month = ""
dynamic var day = ""
func setYearID(inYear: String) {
self.year = inYear
compoundKey = compoundKeyValue()
}
func setMonthID(inMonth: String) {
self.month = inMonth
compoundKey = compoundKeyValue()
}
func setDayID(inDay: String) {
self.day = inDay
compoundKey = compoundKeyValue()
}
dynamic lazy var compoundKey: String = self.compoundKeyValue()
private func compoundKeyValue() -> String {
return "\(year)\(month)\(day)"
}
override static func primaryKey() -> String? {
return "compoundKey"
}
}
I tried to add object as follow:
let storeRealm = try! Realm()
let farm = FarmRecord()
farm.setYearID("2016")
farm.setMonthID("3")
farm.setDayID("1")
do {
try storeRealm.write {
storeRealm.add(farm)
}
} catch {
}
And I see a crash with EXEC_BAD_ACCESS (code = 1). I even tried storeRealm.add(farm, update: true) with no difference.
Realm appears to be mishandling your compoundKey property due to it being marked as lazy. I've written up a bug report about the issue on GitHub. As a workaround I'd suggest removing the lazy modifier and initializing compoundKey to an empty string.

Variable not being saved outside closure

I am using Parse for a database.
Problem: I am querying the database and saving an object, but it does not seem to be saving outside the query function. I think it is because I need to refresh a variable or something but I have no idea how to do that.
Relevant code:
class AddClassViewController: UIViewController {
var classroom = Classroom()
var checkClassList: [Classroom] = []
#IBAction func enrollClassButton(sender: AnyObject) {
self.classroom.classCode = classCodeText.text.uppercaseString
self.classroom.year = yearText.text
self.classroom.professor = professorNameText.text
ClassListParseQueryHelper.checkClass({ (result: [AnyObject]?,error: NSError?) -> Void in
self.checkClassList = result as? [Classroom] ?? []
//count is 1 inside here
println(self.checkClassList.count)
}, classCode: self.classroom.classCode!)
//count is 0 out here
println(self.checkClassList.count)
}
//this gets class with matching classcode
static func checkClass(completionBlock: PFArrayResultBlock, classCode: String){
let query = PFQuery(className: "Classroom")
query.whereKey("ClassCode", equalTo: classCode)
query.findObjectsInBackgroundWithBlock(completionBlock)
}
This is how I solved this:
class ClassListParseQueryHelper{
//this gets class with matching classcode
static func checkClass(classCode: String) -> [PFObject]{
let query = PFQuery(className: "Classroom")
query.whereKey("ClassCode", equalTo: classCode)
var test = query.findObjects() as! [PFObject]
return test
}
self.checkClassList = ClassListParseQueryHelper.checkClass(self.classroom.classCode!) as! [Classroom]