RealmSwift replacement for RLMobject - swift

Whats the correct way todo this with RealmSwift, it used to be RLMobject
var stream:Results<streams>
stream = Realm().objects(streams)
this first one lives on my class as a global the second line in my viewdidload
this is what i try todo: https://dpaste.de/AKKJ
class tabelviewcontroller has no initializers
the model
class streams: Object {
dynamic var br = ""
dynamic var categorie = 0
dynamic var ct = ""
dynamic var lc = ""
dynamic var ml = ""
dynamic var mt = ""
dynamic var name = ""
dynamic var shoutcatid = 0
dynamic var stationid = 0
override static func primaryKey() -> String? {
return "stationid"
}
}

A few quick notes, its good to keep class names singular, my model would look like this:
class Stream: Object {
...
}
If you want to get all objects from streams you can just do this:
let results = Realm().objects(Stream)

var stream:Results<streams>!
solved it

Related

Create a for loop to generate a range of ViewModel #Published properties in Swift to match the CoreData model

The DataModel contains amongst other attributes 27 attributes (Int16) with names of qq1, qq2, ... qq27. It seems silly to initialise each one in the ViewModel individually if we could use a for loop. So, I tried an init(), but the #Published wrapper must be a property of a class. I tried calling a function from the initialisation with various permutations, but it doesn't seem that we can call a function from within the initialisation. It's no big deal - I could just list all 27 in the initialisation, but it's ugly and can't be efficient. Does anyone have a solution? The relevant code snippet showing both attempts, below:
class OpportunityViewModel: ObservableObject {
#Published var opportunityName = ""
#Published var opportunityDescription = ""
#Published var opportunityEstimatedValue: Int32 = 0
#Published var opportunityDead = false
#Published var opportunityCreated: Date = Date()
#Published var opportunityUpdated: Date = Date()
#Published var qualifier(qualifiers) = 0
#Published var qq1 = 0 // This should be the result, but for qq1...qq27
#Published var opportunityItem: OpportunityEntity!
init() {
var q = ""
for qualifier in 1...27 {
q = String("qq" + "\(qualifier)")
#Published var q = 0
}
}
func qualifiers () -> String {
for qualifier in 1...27 {
return String("qq" + "\(qualifier)")
}
}
}

Swift : How to merge two Realm Results in on in swift

I am querying realm for two different keywords then I want to merge those two realm result into one so I loop through its.
I have this Object descendent class:
class Item: Object {
#objc dynamic var _id: ObjectId? = nil
#objc dynamic var _partitionKey: String = ""
#objc dynamic var productBrand: String? = nil
override static func primaryKey() -> String? {
return "_id"
}
}
I'm fetching the realms
class SearchResult : ObservableObject {
#Published var storeitems: Results<Item>
storeitems = realm.objects(Item.self).sorted(byKeyPath: "_id")
let p1 = self.storeitems.filter("productDescription CONTAINS '"Cheese"'")
let p2 = self.storeitems.filter("productDescription CONTAINS '"Blue"'")
}
I am trying to merge p1 and p2 to get something like
p3 = p1 + p2
How can this be implemented with realm result?
You can adjust your filter to get what you want in one go:
let items = storeitems.filter { item in
item.productDescription.contains("Cheese") || item.productDescription.contains("Blue")
}

how to initialise variables in #NSManaged object class as a JSON value?

I want to initialise the variables in the 'Item' class like the variables 'Item2' class
this is the 'Item' class :-
import UIKit
import CoreData
import SwiftyJSON
class Item: NSManagedObject {
#NSManaged var name = String()
#NSManaged var symbol = String()
#NSManaged var checked : Bool = false
#NSManaged var buyPrice = String()
#NSManaged var rank = String()
}
this is 'Item2' class :-
import Foundation
import SwiftyJSON
class Item2 : Codable {
var name = String()
var symbol = String()
var checked : Bool = false
var buyPrice = String()
var rank = String()
init(bitJSON: JSON) {
self.name = bitJSON["name"].stringValue
self.symbol = bitJSON["symbol"].stringValue
self.buyPrice = bitJSON["price_usd"].stringValue
self.rank = bitJSON["rank"].stringValue
}
}
ManagedObject are not normal object. They are an object-oriented way to assess a database. Managed objects use a context to get all their properties. A managedObject must have context - they simply don't work without one.
extension Item {
static func insert(json:JSON, in context:NSManagedObjectContext) -> Item{
let newItem = Item.init(entity: Item.entity(), insertInto:context)
newItem.name = json["name"].stringValue
newItem.symbol = json["symbol"].stringValue
newItem.buyPrice = json["price_usd"].stringValue
newItem.rank = json["rank"].stringValue
}
}
Notice two things about this method: 1) it does not assume that it knows the context - that is a job for a higher level - for some apps it is simply inserted direclty into the viewContext, for other apps a temporary background context is created. and 2) it does not save the context - that is also not it's job - other object may be edited or created at the same time and they should all be save transactionally.
It would be used for example like this:
persistentContainer.performBackgroundTask { (context) in
let newItem = Item.insert(json: json, in: context)
do {
try context.save()
} catch {
// log to you analytic provider
}
}
Hope this helps.

How to create one Realm class from several other classes?

Good afternoon everyone,
Im currently working on a task that called "Bookmark". The short description is whenever i clicked the bookmark button, app will save the article and then display it in the BookmarkVC.
I have 3 types of object called "News", "Documents" and "ITSectionResult" and my idea is to create an object called "BookmarkItem" which contain element of 3 above objects and one property called bookmarkCategory to indicate type of objects, so that i can use it to display in BookmarkVC. I just want to work on only one realm object, so any one can help me an an idea to group these guys together?. Here i would attach my draft code as below:
For News class:
class NewsArticle:Object {
dynamic var title: String?
dynamic var body:String?
dynamic var category:String?
dynamic var createTime:String?
dynamic var image:String?
dynamic var id:String?
convenience init (title:String, body:String, category:String,
image:String, id:String, createTime:String) {
self.init()
self.title = title
self.body = body
self.category = category
self.image = image
self.id = id
self.createTime = createTime
}
Document class:
class Documents {
var id: String?
var title:String?
var createTime:CLong?
var url:String?
init (title:String, id:String, createTime:CLong?, url:String) {
self.title = title
self.id = id
self.createTime = createTime
self.url = url
}
ITSectionResult class:
class SectionSearchResult {
var title:String?
var image:String?
var id:String?
var byCategory:String?
init (title:String, image:String, id:String, byCategory:String) {
self.title = title
self.image = image
self.id = id
self.byCategory = byCategory
}
and finally the drafting BookmarkItem class:
class BookmarkItem:Object {
//Category
dynamic var bookmarkCategory:BookMarkItemCategory?
dynamic var title: NewsArticle?
dynamic var body:NewsArticle?
dynamic var category:NewsArticle?
dynamic var createTime:NewsArticle?
dynamic var image:NewsArticle?
dynamic var id:NewsArticle?
dynamic var link:String?
dynamic var url:String?
}
class BookMarkItemCategory:Object {
dynamic var name = ""
}
Here i would remind that, the BookmarkItem class uses 3 major properties to display in the BookmarkVC, "image" for filter category type(example: book image for Documents object, newspaper icon for News object) , "title" for the title and the url for display in WebView. Thank you so much, and wish you guys have a good weekend ahead.
As mentioned above in the comments by EpicPandaForce, this can be achieved by not having a class for each type and instead use a unified model.
import RealmSwift
final class UnifiedModel: Object {
dynamic var title: String = ""
dynamic var id: String = ""
dynamic var createTime: String = ""
dynamic var category: String = ""
dynamic var body: String?
dynamic var image: String?
override static func primaryKey() -> String {
return "id"
}
}
With the model I've shown above, every instance would need a title, id, create time and category while body and image could be left nil. Please feel free to follow-up if you have any other questions.
Disclaimer: I work for Realm.

How to change Realm singleton attribute value

I have a Realm object:
class TransactionDB: Object {
dynamic var transactionID : Int = -1
dynamic var registrationPlate : String = ""
dynamic var locationID : Int = 0
dynamic var time : String = ""
dynamic var subscription : String = ""
dynamic var startTime : NSDate = NSDate()
dynamic var endTime : NSDate = NSDate()
dynamic var status : Int = -2
dynamic var requestType : Int = -1
var extensions : List<ExtensionDB> = List<ExtensionDB>()
dynamic var price : Double = 0
dynamic var currency : String = ""
private dynamic var test : Int = 10
override static func primaryKey() -> String? {
return "transactionID"
}
class var sharedInstance : TransactionDB {
struct Singleton {
static let instance = TransactionDB()
}
return Singleton.instance
}
static func saveOrUpdate {
// ......
}
and a singleton version for it. So I have one object over many controllers when screens change.
A few days back I was using some older Objective-C version of Realm but now I changed to the Swift-only version 1.0.2 and I'm trying to fix all the problems.
So now it came to part that when I try to call stuff like:
TransactionDB.sharedInstance.time = ""
I get an exception. However, after I do the following, it works:
let realm = try! Realm()
try! realm.write {
TransactionDB.sharedInstance.time = ""
}
So am I creating the singleton wrong or is this just the way it has to be done? Because, for me, it is a little annoying that I would always have to use a try block when I want to change the value of some attribute.
Take a look at the first line of the Realm docs for the write section.
It states:
All changes to an object (addition, modification and deletion) must be done within a write transaction.
So yea, it's just how you have to do it.