RealmSwift : All the realm rows are displayed twice - ios

I am learning to develop on Swift, so sorry if my questions seem stupid :D
On my app, I need 3 objects : Car, Station & Conso
A Car Object can have many Conso
A Station Object car have many Conso
A Conso Object can be linked to only one Car and one Station
Here are the codes for Realm objects
Conso.swift
import Foundation
import RealmSwift
final class Conso : Object {
//var id: Int
#objc dynamic var idConso = ""
//... Some fields
#objc dynamic var data: NSData?
#objc dynamic var idCar = ""
#objc dynamic var station: Station? // Link to a Station Object
#objc dynamic var car: Car? // Link to a car Object
Car.swift
import Foundation
import RealmSwift
final class Car : Object {
//#objc dynamic var ID = 0
#objc dynamic var idCar = ""
//...some fields
#objc dynamic var data: NSData?
// Link to Conso object (Many-to-One)
let consos = LinkingObjects(fromType: Conso.self, property: "car")
Station.swift
import Foundation
import RealmSwift
import MapKit
final class Station : Object {
//#objc dynamic var ID = 0
#objc dynamic var idStation = ""
//...some fields
#objc dynamic var data: NSData?
// Link to Conso object (Many-to-One)
let consos = LinkingObjects(fromType: Conso.self, property: "station")
I insert the objects on database using this snippet :
// Create a Conso Object
let conso:Conso = Conso()
conso.idConso = "Conso-123454344"
if let textStationService = self.TextFieldStationService.text{
conso.nomStation = textStationService
conso.station?.nomStation = textStationService
}
if let textCPStationService = self.TextFieldCodePostal.text{
conso.CPStation = textCPStationService
self.station!.codePostal = textCPStationService
}
if let textVilleStationService = self.TextFieldStationServiceCPVille.text{
conso.villeStation = textVilleStationService
self.station!.ville = textVilleStationService
}
// A car object is received from another viewController
conso.car = self.car
let realm = try! Realm()
try! realm.write {
realm.add(conso)
realm.add(station!)
}
From another ViewController, I get the results with this snippet
assumed that a car id (idCar) is received from another VC :
func listConso(){
let realm = try! Realm()
// Get the car from its id
self.car = realm.objects(Car.self).filter("idCar = %#",self.idCar).first
// Get Conso based on the searched car
self.consosData = realm.objects(Car.self).filter("idCar = %#",self.idCar).first?.consos.sorted(byKeyPath: "dateConso", ascending: false)
self.consos = Array((self.consosData)!)
self.tableViewConso.setEditing(false, animated: true)
self.tableViewConso.reloadData()
print("listConsop")
}
The result is that I have many lines twice
Thank you for your help.

Related

How to create model like firebase structure using RealmSwift in iOS swift?

I have been trying to create model like firebase database structure. I can able to create normal string, bool and int value but not able to do array and dictionary.
Here is my firebase structure screenshot:
Here i am trying to add groupMembers and to in model like firebase structure.
Here is my Model i tried to create with array and dictionary:
import Foundation
import RealmSwift
class RealmMessages: Object {
#objc dynamic var messageText : String?
#objc dynamic var sender: String?
let chatCreatedDateTimee = List<timeStampValue>()
#objc dynamic var chatId: String?
#objc dynamic var from: String?
#objc dynamic var groupMemberss : [String: String]!
let groupMemebersCount = RealmOptional<Int>()
#objc dynamic var task: Bool = false
#objc dynamic var to: Array = [String]()
}
class timeStampValue: Object {
let timestamp = RealmOptional<Int>()
}
Here is my contoller code: Trying to add value into realm database.
var dic : [String : String] = [:]
var cont = ["one", "two", "three"]
var oneVal = ["909090": "SELF", "808080": "Other"]
override func viewDidLoad() {
super.viewDidLoad()
let realm = try! Realm()
print("realm location:::\(String(describing: Realm.Configuration.defaultConfiguration.fileURL))")
let myMessage = RealmMessages()
myMessage.messageText = "Diva"
myMessage.sender = "yIvq1mQxjfZpjs1ybRTTlDOmUKV2"
let timevalue = timeStampValue()
timevalue.timestamp.value = 123123131
myMessage.chatId = "+918000080000"
myMessage.from = "+918000080000"
myMessage.groupMemberss = oneVal
myMessage.to = cont
try! realm.write {
realm.add(myMessage)
}
}
How to get groupMemberss and to structure in realm database like firebase. And how to create array and dictionary in realm
There are a number of solutions but here's two.
Assuming the data has been read in and the data from the groupMembers snapshot is sitting in a dictionary var that looks like this
let groupMembersDict = [
"919": "participant",
"111": "observer",
"222": "participant"
]
To store that in Realm, you can work with primitives and store each key and value in a separate List (think: Array) or you can leverage a managed Realm object and store those in a List.
If you want to keep the data within an object; here's what it would look like.
class GroupData: Object {
#objc dynamic var num = ""
#objc dynamic var type = ""
convenience init(withNum: String, andType: String) {
self.init()
self.num = withNum
self.type = andType
}
}
Here's the main object showing both options; either option 1: store the key value pairs in two arrays, or option 2: use the above GroupData object to store the key value pairs together
class Messages: Object {
#objc dynamic var messageText = ""
//option 1: two lists of primative strings that can be accessed like an array.
// downside is managing two lists
let groupNum = List<String>()
let groupType = List<String>()
//option 2: a list of members using another Realm object
let groupNumType = List<GroupData>()
}
And some code to create two messages, one of each type
let msg0 = Messages()
msg0.messageText = "My message"
for member in groupMembersDict {
msg0.groupNum.append( member.key )
msg0.groupType.append( member.value )
}
let msg1 = Messages()
msg1.messageText = "This message"
for member in groupMembersDict {
let aGroup = GroupData(withNum: member.key, andType: member.value)
msg1.groupNumType.append(aGroup)
}
store them in realm
realm.add(msg0)
realm.add(msg1)
read them both in an display the message from option 2. Option 1 would be just iterating over the arrays to print the group data
let messageResults = realm.objects(Messages.self)
for msg in messageResults {
print(msg.messageText)
for group in msg.groupNumType {
print(group.num, group.type)
}
}
Keep in mind that all managed properties must be primitives: NSString, NSDate, NSData, NSNumber or List, Results, RLMLinkingObjects, or subclasses of RLMObject like the GroupData shown above.

How to store Array of Dictionaries to Realm Database in Swift

I am getting JSON data from server by api call in swift application.
So, I want to store that into Realm data base and again need to fetch to show in tableview.
I have no idea about Realm database, After, checked few forums, I got basic idea for creating Object class.
So, I have installed Realm pod file and imported that library to my classes.
My JSON data is
[{
"type": "story",
"story": 
{
"author-name": "",
"headline": "Quotes ",
"summary": "Best quotes of Muhammad Ali",
"hero-image": "https://image”
}
},
{
"type": “Trending”,
"story": 
{
"author-name": "",
"headline": "Quotes ",
"summary": "Best quotes of Muhammad Ali",
"hero-image": "https://image”
}
},
{
"type": “Technology”,
"story": 
{
"author-name": "",
"headline": "Quotes ",
"summary": "Best quotes of Muhammad Ali",
"hero-image": "https://image”
}
},
{
"type": “Top”,
"story": 
{
"author-name": "",
"headline": "Quotes ",
"summary": "Best quotes of Muhammad Ali",
"hero-image": "https://image”
}
}
]
And I have each type keyword has different model class saved data from api data to show in Tableview
like
let storyObj = StoryModule()
let trending = StoryModule()
let technology = StoryModule()
let stotopryObj1 = StoryModule()
and I am saving each key value for every type
if abc.type == "story" {
let storyObj = abc.story
storyObj.authorname = storyObj?.authorname
storyObj.heroimage = storyObj?.heroimage
storyObj.headline = storyObj?.headline
storyObj.summary = storyObj?.summary
self.treningStoriesList.append(storyObj)
}
It is same for remaining Trending, Top and Technology objects.
and the Realm module is
import RealmSwift
class DemoInfo: Object {
#objc dynamic var category = ""
let items = List<DemoList>()
}
class DemoList : Object {
#objc dynamic var authorName = ""
#objc dynamic var imageUrl = ""
#objc dynamic var summary = ""
#objc dynamic var headLine = ""
}
And In MainViewController class,
let realmDB = try! Realm()
But, Here I got struck, How to save those storyObj,technology,top, etc module data and fetch.
Can anyone suggest me?
If you want to add a realm object in your db, you must define a primary key for each realm object classes. So, you need to change your JSON file, after you can create your realm objects like this;
DemoObject.swift
import RealmSwift
class DemoObject: Object {
#objc dynamic var id: String = ""
#objc dynamic var type: String = ""
#objc dynamic var subObject: SubObject?
override static func primaryKey() -> String? {
return "id"
}
}
SubObject.swift
import RealmSwift
class SubObject: Object {
#objc dynamic var id: String = ""
#objc dynamic var authorName: String = ""
#objc dynamic var imageUrl: String = ""
#objc dynamic var summary: String = ""
#objc dynamic var headLine: String = ""
override static func primaryKey() -> String? {
return "id"
}
}
Then, you can use these codes to add your db.
let realm = try! Realm()
let demo = DemoObject()
demo.id = "1"
let sub = SubObject()
sub.id = "1"
sub.authorName = "Author Name"
sub.headLine = "Head Line"
sub.summary = "image Url"
demo.subObject = sub
try! realm.write {
realm.add(demo, update: true)
}

Realm- updating all items in array of objects instead of appending only new one

I'm trying to add different journal entries associated with a patient in JournalEntryVC.swift.
My Patient class has an array of journal entries i.e. let journalEntries = List<Journal>() My Journal class has properties that represent journal entry attributes i.e. entryType, entryDate and entryCaption.
However, instead of only appending a new journal entry object to the array of journal entries newPatient.journalEntries.append(myJournal) when looping over the json in JournalEntryVC.swift, my previously appended journal entries' attributes are also replaced by the most recent journal entry attributes.
For example, newPatient.journalEntries[0] has the same string values for entryCaption and entryType as newPatient.journalEntries[1] and so on.
Main problem: Any ideas on how I could add a NEW journal entry with its attributes but without changing journal entry attributes for previously appended journal entries?
Thank you!
// Patient.swift
import Foundation
import RealmSwift
class Patient: Object {
dynamic var patientName = ""
dynamic var patientAvatar = ""
dynamic var patientId = 0
dynamic var isDietitian = false
//array of journal entries for each patient
let journalEntries = List<Journal>()
override class func primaryKey() -> String {
return "patientId"
}
}
// Journal.swift
import Foundation
import RealmSwift
class Journal: Object {
dynamic var entryId = ""
dynamic var entryType = ""
dynamic var entryImg = ""
dynamic var entryCaption = ""
dynamic var entryComment = ""
dynamic var entryCategory = ""
dynamic var entryDate = ""
override class func primaryKey() -> String {
return "entryId"
}
}
//JournalEntryVC.swift
import UIKit
import Alamofire
import BXProgressHUD
import SwiftyJSON
import RealmSwift
class JournalEntryVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
func reloadInitialData ( ) {
//mutable arrays containing journal entry attributes
desc.removeAllObjects()
type.removeAllObjects()
category.removeAllObjects()
metric_stat.removeAllObjects()
entryImages.removeAllObjects()
dateCreate.removeAllObjects()
comments.removeAllObjects()
entryType.removeAllObjects()
id.removeAllObjects()
//comments.removeAllObjects()
content.removeAllObjects()
patName.removeAllObjects()
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
let request = Alamofire.request(.GET, "https://gethealthie.com/entries.json", headers: [
"access-token": userCreds.objectForKey("access-token")! as! String,
"client": userCreds.objectForKey("client")! as! String,
"token-type": userCreds.objectForKey("token-type")! as! String,
"uid": userCreds.objectForKey("uid")! as! String,
"expiry": userCreds.objectForKey("expiry")! as! String
]).responseJSON { response in
print(response.response)
let json = JSON(data: response.data!)
if json.count == 0 {
BXProgressHUD.hideHUDForView(self.view);
}else {
//Realm- create object instances of Patient and Journal class
let newPatient = Patient()
let myJournal = Journal()
for i in 0 ..< json.count {
let entry = json[i]
print(entry)
let name = entry["entry_comments"]
let k = name["id"]
//add entry attributes to mutable arrays
self.type.addObject(entry["type"].stringValue)
self.desc.addObject(entry["description"].stringValue)
self.category.addObject(entry["category"].stringValue)
self.metric_stat.addObject(entry["metric_stat"].stringValue)
self.dateCreate.addObject(entry["created_at"].stringValue)
self.comments.addObject(entry["entry_comments"].rawValue)
self.entryType.addObject(entry["category"].stringValue)
let posterInfo = entry["poster"]
let first = posterInfo["first_name"].stringValue
let last = posterInfo["last_name"].stringValue
let full = first + " " + last
self.patName.addObject(full)
self.id.addObject(entry["id"].stringValue)
self.entryImages.addObject(entry["image_url"].stringValue)
//Realm- access properties in Journal class and set it equal to the current journal entry attribute i.e. json[i]
myJournal.entryType = entry["type"].stringValue
myJournal.entryCaption = entry["description"].stringValue
myJournal.entryCategory = entry["category"].stringValue
myJournal.metricStat = entry["metric_stat"].stringValue
myJournal.entryDate = entry["created_at"].stringValue
// myJournal.entryComment = entry["entry_comments"].rawValue as! String
//append a NEW journal entry to the array of journal entries in Patient class i.e. let journalEntries = List<Journal>() as the json loops thru different journal entries
newPatient.journalEntries.append(myJournal)
if i == json.count - 1 {
// do some task
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
BXProgressHUD.hideHUDForView(self.view)
}
}
}
//Realm- add newPatient object instance to realm
try! self.realm.write {
self.realm.add(newPatient)
}
}
}
}
}
}
You're instantiating a single instance of Journal outside the for loop, changing the values of that Journal, then appending it to the patient's journalEntries. Try moving let myJournal = Journal() inside your for loop.

RealmSwift - How can I store data in list

I'm new in programming and I would like to know how I can store data in a List with RealmSwift.
Considering the following model:
import RealmSwift
class ScanResults: Object{
dynamic var id = 0
dynamic var resource = ""
dynamic var scanDate = ""
let ScanResultsDetail = List<ScanResultsDetails>()
}
class ScanResultsDetails: Object{
dynamic var scanner = ""
dynamic var result = ""
}
This is an example how I store new ScanResults:
let newResults = ScanResults()
newResults.id = newResults.IncrementaID()
newResults.resource = "Test"
newResults.scanDate = "19.01.2016"
do{
try uiRealm.write({ () -> Void in
uiRealm.add(newResults)
})
}
catch{
}
My Question is now, how can I store data in the list? I can't figure it out.. Can you give me an example?
I don't see that you append any object to ScanResultsDetail in your example
Here is quick example based on swift source code (docs):
class Dog: Object {
dynamic var name = ""
dynamic var age = 0
}
class Person: Object {
dynamic var name = ""
let dogs = List<Dog>()
}
let realm = try! Realm() // Create realm pointing to default file
// Link objects
let person = Person()
person.name = "Tim"
person.dogs.append(mydog)
try! realm.write {
realm.add(person)
}

Realm.objects() returns empty objects

My class has all properties as dynamic but still when retrieving them from realm i get a collection of empty objects, and check the realm db with the realm browser and the data is there, this is my class:
class ProjectEntity: Object {
/**
Property: All properties of the ProjectEntity
**/
dynamic var ProjectId = 0
dynamic var ProjectTitle = ""
dynamic var ProjectSubtitle = ""
dynamic var ProjectType = ""
dynamic var ProjectClass = ""
dynamic var ProjectCoordinates = ""
dynamic var ProjectGraphType = ""
dynamic var ProjectModifiedOn = NSDate(timeIntervalSince1970: 0)
dynamic var ProjectCity = ""
dynamic var ProjectCounty = ""
dynamic var ProjectZip = ""
override static func primaryKey() -> String? {
return "ProjectId"
}
func getShape() -> MapShape{
let adapter = ProjectsJSONAdapter()
let shape: MapShape = adapter.parseShape(id: self.ProjectId, type: self.ProjectGraphType, jsonStr: self.ProjectCoordinates)
return shape
}
}
here is how i'm reading the data:
let projectsList = realm.objects(ProjectEntity)
for project in projectsList {
projects.append(project)//The properties in project have all their default/empty values
}
any ideas?
How are you retrieving the persisted ProjectEntity objects? The following code snippet should do the trick:
let entities = Realm().objects(ProjectEntity)
first your class need to inherit RLMObject :
class ProjectEntity: RLMObject {
...
}
and after if you want all the ProjectEntity objects try this :
let allProjectEntityObjects: RLMResults = ProjectEntity.allObjects()
if you need some extra help you can follow this tutorial from Realm :
Building a To-Do App with Realm

Resources