I'm using a custom base class for my models to be used with Realm for Swift. This is the class.
import RealmSwift
public class ModelBase: Object {
#objc public var createdAt, updatedAt: Date
required convenience init() {
createdAt = Date()
updatedAt = Date()
self.init()
}
}
Now, when trying to compile this, Xcode will throw an error
Class 'ModelBase' has not initializers
However, when I change the initializer function to required public init() and then let it call super.init(), Realm will start complaining that I need to implement additional initializers. Anyone know how I can fix the first issue?
You need to use custom initializer with declared init parameters, like this:
import RealmSwift
public class ModelBase: Object {
#objc public dynamic var createdAt, updatedAt: Date
convenience init(_ defaultDate: Date = Date()) {
self.init()
createdAt = defaultDate
updatedAt = defaultDate
}
}
in convenience init self.init() has to be called before initializing all other properties. Also you need to declare properties as dynamic since theirs getters and setters are managed by Realm itself.
or if createdAt and updatedAt are Date() by default you can omit initializer at all by declaring vars in class declaration.
public class ModelBase: Object {
#objc public dynamic var createdAt: Date = Date()
#objc public dynamic var updatedAt: Date = Date()
}
Related
I need help with converting one object to another. Might have searched 10-20 website didn't find any good answer.
public struct UniversityJoinChatViewModel {
public let id: Int?
public let name: String?
public init(nameOfModel model : UniversityGroupChatItem?) {
self.id = model?.id;
self.name = model?.name;
}
}
public struct UniversityGroupChatItem: Codable {
public let id: Int?
public let name: String?
public init(id: Int?, name: String?) {
self.id = id
self.name = name
}
}
I did this:
let say I have value UniversityGroupChatItem in variable universityGroupChatItem and my universityGroupChatItem contains is not nil and contains value. I tried this it did not work.
universityJoinChatViewModel = (universityGroupChatItem) as! UniversityJoinChatViewModel
The app crashed.
Then I tried:
map and
compactmap
None worked.
I am not getting how to convert UniversityGroupChatItem struct to UniversityJoinChatViewModel struct.
I do not understand how to convert one struct to another struct both has same number name variables.
You can't force cast one object into another (no matter struct, class, enum ect.) even if they are fully the same inside
You need to implement inits where one object takes fields from another one.
map is function to sequences, if You have only 1 object just init it with another one
Examples:
public struct UniversityJoinChatViewModel {
public let id: Int?
public let name: String?
public init(nameOfModel model : UniversityGroupChatItem?) {
self.id = model?.id;
self.name = model?.name;
}
}
public struct UniversityGroupChatItem: Codable {
public let id: Int?
public let name: String?
public init(id: Int?, name: String?) {
self.id = id
self.name = name
}
}
let universityGroupChatItem = UniversityGroupChatItem(id: 0, name: "name")
let universityJoinChatViewModel = UniversityJoinChatViewModel(nameOfModel: universityGroupChatItem)
let groupArray = Array(repeating: universityGroupChatItem, count: 10)
let joinArray = groupArray.map(UniversityJoinChatViewModel.init(nameOfModel:))
In your case, you already have the constructor that can help you to achieve what you want, so instead of trying to cast the object, create a new one:
universityJoinChatViewModel = UniversityJoinChatViewModel(nameOfModel: universityGroupChatItem)
How can the #NSManaged properties be in an extension when extensions can't contain stored properties? Why are they not the same as stored properties?
A popular format for core data files is a core data class, and then an extension containing the core data properties.
//User+CoreDataClass
#objc(User)
public class User: NSManagedObject {
var fullName: String {
return "\(firstName) \(lastName)"
}
}
//User+CoreDataProperties
extension User {
// Why can these #NSManaged properties live in an extension?
#NSManaged public var id: Int64
#NSManaged public var firstName: String
#NSManaged public var lastName: String
var storedProp: String // Error: Extensions must not contain stored properties
}
Technically #NSManaged properties are computed properties.
Core Data synthesizes getter and setter.
I am trying to define a wrapper around objects I want to store in Realm. The wrapper should contain an additional date object so that I can filter old objects. So far I have this
public final class RealmDateTaggedRealmObject: ObjectFacade {
#objc public dynamic var date: Date?
#objc public dynamic var value: ObjectFacade?
#objc private dynamic var id: String = ""
public override class func primaryKey() -> String? {
return #keyPath(id)
}
public convenience init<T: RealmMappable>(from object: RealmDateTagged<T>) {
self.init()
date = object.date
value = object.value.asRealmObject
id = object.primaryKey
}
}
The RealmMappable protocol enables transforming implementing entities into ObjectFacade. The ObjectFacade class is an empty class that inherits from Object, because I got an exception if I declared
#objc public dynamic var value: Object?
So I tried to be smart and created ObjectFacade. Turns out I'm not so smart cause it always stores nil. Also, value can't be a generic type because it is not supported in Objective-C.
Any suggestions?
Thanks!
I'm trying to get a simple NSManagedObject class to conform to Encodable so that I can easily encode it to JSON.
I have an entity named TestObject that has a one to many relationship with an entity named Device.
Everything works fine until I try to encode an NSSet (to many relationship).
import UIKit
import CoreData
import Foundation
#objc(TestObject)
public class TestObject:NSManagedObject,Encodable
{
#nonobjc public class func fetchRequest() -> NSFetchRequest<TestObject> {
return NSFetchRequest<TestObject>(entityName: "TestObject")
}
#NSManaged public var testName: String?
#NSManaged public var devices: NSSet? // of entity type "Device"
enum CodingKeys: String, CodingKey {
case testName
case devices
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy:CodingKeys.self)
try container.encode(testName,forKey:.testName)
try container.encode(devices,forKey:.devices)
}
}
The error I receive from the compiler is
reference to member 'devices' cannot be resolved without a contextual type
try container.encode(devices,forKey:.devices)
What is this compiler telling me and how can I encode my objects along with its relationships?
I know how to set 'setter' of an stored property to private (e.g. public private(set) var name: String = "John") but how do we set 'setter' of an computed property to private? In this case the 'setter' for the variable 'age'. When I tried to put an keyword private in front of set(newAge){}, XCode display an error. So is it possible to set 'setter' of an computed property to private?
public class Person {
public private(set) var name: String = "John"
var age: Int{
get {
return 10
}
set(newAge){ // how to set this setter to private so to restrict modification
}
}
}
You do it the same way as for a stored property:
private(set) var age: Int{
get {
return 10
}
set(newAge) {
// setter code here
}
}