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
Related
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)
}
I am trying to create a one to many relationship between medication table and side effects table. RealmObject is a custom class created from Object class.
Model definitions:
class Medication: RealmObject {
#objc dynamic var name : String?
#objc dynamic var form : String?
#objc dynamic var id : String?
let medToSideEffect = List<SideEffect>()
override class func primaryKey() -> String? {
return "id"
}
}
class SideEffect: RealmObject {
#objc dynamic var masterSideEffectId : String = ""
#objc dynamic var entityType : String = ""
#objc dynamic var entityId : String = ""
#objc dynamic var sideEffect : String = ""
#objc dynamic var id : String = ""
#objc dynamic var uniqueId : String = ""
override class func primaryKey() -> String? {
return "uniqueId"
}
}
Test code:
let medicationItem = Medication(dict: medication)
let sideEffectItems = List<SideEffect>()
for sideEffect in sideEffectList {
let sideEffectItem = SideEffect()
sideEffectItem.id = self.getMongoId()
sideEffectItem.entityType = "Medicine"
sideEffectItem.entityId = medicationItem.id!
sideEffectItem.sideEffect = (sideEffect as? String)!
sideEffectItem.uniqueId = "\(medicationItem.id!)_\(((sideEffect as? NSString)?.replacingOccurrences(of: " ", with: "_"))!)"
sideEffectItems.append(sideEffectItem)
medicationItem.medToSideEffect.append(sideEffectItem)
}
After this process, when i print the medicationItem, Output is this
Medication {
name = Paracetomol 650mg;
form = tab;
id = 5af96e79efb27f6bd5c25a66;
}
The side effects were supposed to be added to the medication object. but that is not the case anymore. It was working fine until the latest update Realm 3.11.0.
Please let me know, if the code is incorrect.
Maybe because yYou declare your list as 'immutable', and maybe because your list is a struct and therefore a copy is returned.
let medToSideEffect = List<SideEffect>()
And so it cannot be changed. Try (warning untested code)
public private(set) var medToSideEffect = List<SideEffect>()
and add a func
public func append(sideEffect: SideEffect) {
self.medToSideEffect.append(sideEffect)
}
The 'public private (set)' bit means that the list is visible externally but can only be modified by the owning class instance.
EDIT:
https://stackoverflow.com/a/52704564/6700116
Found the solution.
Go to your target Build Settings and set Reflection Metadata Level flag to All
The issue is discussed here.
https://github.com/realm/realm-cocoa/issues/5944#issuecomment-426948127
I have a model like this:
class CalendarEvent: Object, Mappable {
dynamic var exId = ""
#objc dynamic var title:String = ""
#objc dynamic var desc:String = ""
dynamic var fullDate = Date()
dynamic var date = ""
dynamic var time = ""
dynamic var location = ""
dynamic var subcategory:Subcategory?
dynamic var update = false
var participants = List<Participant>()
}
class Category:Object, Mappable{
dynamic var exId = ""
#objc dynamic var name="";
var subcategories = List<Subcategory>()
}
class Subcategory:Object, Mappable{
dynamic var exId = ""
dynamic var name = ""
let category = LinkingObjects(fromType: Category.self, property: "subcategories")
dynamic var active:Bool = true
dynamic var update = false
}
I need to know which CalendarEvents are from a category, when is from a subcategory I can do:
var results = realm.objects(CalendarEvent.self)
results = results.filter("ANY subcategory.exId == %#", subcategory!.exId)
But when I need to obtain the CalendarEvents filtered by category I don´t know how to do it. I looked after the solution but didn´t find anywhere. Please help!
For the record, I found the solution. It´s easy, you need to subdivide in queries and chain then using "IN". For example:
let resultsSubcategory = realm.objects(Subcategory.self).filter("ANY category.exId == %#", category?.exId)
results = results.filter("subcategory IN %#", resultsSubcategory)
I try to read json and create Realm, so my code:
func workWithFileJSON () {
//local file JSON
let file = Bundle.main.path(forResource: "MobileDbSchema", ofType: "json")!
let url = URL(fileURLWithPath: file)
let jsonData = NSData(contentsOf: url)!
//Parce JSON
let json = try! JSONSerialization.jsonObject(with: jsonData as Data, options: [])
try! realm.write {
//Create data from JSON to our objects
realm.create(DataRoot.self, value: json, update: true)
}
}
and file with classes:
import Foundation
import RealmSwift
class DataRoot: Object {
dynamic var id = 0
dynamic var name = ""
let transport_type = List<Transport_type>()
override class func primaryKey() -> String? {
return "id"
}
}
class Transport_type: Object {
dynamic var id = 0
dynamic var name = ""
let routes = List<Routes>()
override class func primaryKey() -> String? {
return "id"
}
}
class Routes: Object {
dynamic var id = 0
dynamic var name = ""
let directions = List<Directions>()
override class func primaryKey() -> String? {
return "id"
}
}
class Directions: Object {
dynamic var id = 0
dynamic var name = ""
dynamic var dayIdFrom = 0
dynamic var dayIdTo = 0
let stops = List<Stops>()
override class func primaryKey() -> String? {
return "id"
}
}
class Stops: Object {
dynamic var id = 0
dynamic var busStop: BusStop?
let timetable = List<Timetable>()
override class func primaryKey() -> String? {
return "id"
}
}
class BusStop: Object {
dynamic var id = 0
dynamic var name = ""
dynamic var descript = ""
override class func primaryKey() -> String? {
return "id"
}
}
class Timetable: Object {
dynamic var hour = 0
dynamic var minute = 0
dynamic var group_index = 0
dynamic var notes = ""
}
after my first run I see good data in Realm:
but after second run I see data in Timetable x 2 and etc. time after each run.
In Timetable there are no primary keys (here don't need it). Why after each update (run) I see increase data in Timetable and how to resolve my mistake?
Even if your app doesn't need primary keys, Realm.add(_:update:) requires your Object class to implement one so it is able to identify pre-existing entries as opposed to new ones. If you do not specify a primary key, even if update: is set to true, it will add each item from JSON as a new object.
Ideally, you should be able to implement some kind of primary ID for each entry in the JSON feed so you can simply pass that along to Realm.
However, if you cannot implement primary keys, but you know that every new JSON object you pull down is a complete snapshot of your timetables, then you could also simply consider deleting all of the pre-existing timetable objects in your Realm file before adding the latest ones from the JSON file.
I have some Realm classes that look like this:
class Friends: Object {
dynamic var name = true
dynamic var role = true
dynamic var type = true
dynamic var owner: Profile?
}
class Profile: Object {
dynamic var uuid = NSUUID().UUIDString
dynamic var name = ""
dynamic var date = NSDate(timeIntervalSinceNow: 1)
dynamic var section = 0
dynamic var code = ""
dynamic var gender = 0
dynamic var type = ""
let friends = List<Friends>()
override static func primaryKey() -> String? {
return "uuid"
}
}
class Sub: Profile {
dynamic var owner: Master?
}
class Master: Object {
dynamic var type = ""
dynamic var name = ""
dynamic var date = ""
let subs = List<Sub>()
}
I understand that to retrieve the objects from realm I have to do this:
var master = try! Realm().objects(Master)
let profile = master[indexPath.row]
let date = profile.date
let name = profile.name
let type = profile.type
The question is: How do I retrieve objects from the 'subs'(List) ?
When you retrieve a master object you can access its subs list like any other property:
let subs = profile.subs
This gives you a list that you can iterate over:
for sub in profile.subs {
// do something with the sub object
}
Or you can filter the subs to find a particular object:
if let subjectWithId = profile.subs.filter("uuid == '7382a8d83'").first {
// do something with the subject
}
Or you can use subscripting to access elements by index:
let secondProfile = profile.subs[1]