iOS 14 Widgets + Realm + SwiftUI 2.0?

Viewed 691

I use Realm + SwiftUI 2.0, iOS 14. I successfully linked (read/write) Realm to Swift 2.0 iOS app.

final class DataEntryStore: ObservableObject {
    
    private var entryCancellable: AnyCancellable?
    private(set) var entryDB = DataObservable<Entry>()
    // could store related references to other related DataObservables
    
    @Published private(set) var entries: [Entry] = []
    
    // MARK: - init
    init() {
        entryDB = DataObservable<Entry>()
        entryCancellable = entryDB.$items.assign(to: \.entries, on: self)
    }
}

class RealmEntry: Object, UUIDIdentifiable {
    @objc dynamic var id: String = UUID().uuidString
    @objc dynamic var entryType = ""
    @objc dynamic var entryDate = Date()
    @objc dynamic var note: String?
    @objc dynamic var trainingType: String?
    @objc dynamic var trainingTime = 0
    
    override static func primaryKey() -> String? {
        return "id"
    }
}

// MARK: - Abstracted Data Struct which is what is presented with the UI

// UI Model
struct Entry: Hashable, RealmConvertible {
    typealias RealmType = RealmEntry
    
    // MARK: - Properties
    
    var id: String
    var entryType: DataEntryType
    var entryDate: Date
    var note: String?
    var trainingType: TrainingType?
    var trainingTime: Int

    func toRealmObject() -> RealmEntry {
        let realmObj = RealmEntry()
        
        realmObj.id = id
        realmObj.entryType = entryType.rawValue
        realmObj.entryDate = entryDate
        realmObj.note = note
        
        if let trainingTypeValue = trainingType?.rawValue {
            realmObj.trainingType = trainingTypeValue
        }
        realmObj.trainingTime = trainingTime
        
        return realmObj
    }

    static func fromRealmObject(_ obj: RealmEntry) -> Entry {
        Entry(obj)
    }
    
    init() {
        self.id = UUID().uuidString
        self.entryType = .note
        self.entryDate = Date()
        self.trainingTime = 0
    }
    
    init(_ obj: RealmEntry) {
        self.id = obj.id
        self.entryType = DataEntryType(fromRawValue: obj.entryType)
        self.entryDate = obj.entryDate
        self.note = obj.note
        if let trainingType = obj.trainingType {
            self.trainingType = TrainingType(fromRawValue: trainingType)
        }
        self.trainingTime = obj.trainingTime
    }
}

protocol StringIdentifiable {
    var id: String { get }
}

protocol UUIDIdentifiable: Identifiable { var id: String { get } }
//protocol Initializable { init() }

// MARK: - Map Between the Two

protocol RealmConvertible where Self: Equatable & UUIDIdentifiable {
    associatedtype RealmType: Object & UUIDIdentifiable
    
    func toRealmObject() -> RealmType
    init(_ dest: RealmType)
}

// Dynamic Realm Binding for live data editing

extension RealmConvertible {
    func realmBinding() -> Binding<Self> {
        let h = RealmHelper()
        return Binding<Self>(get: {
            if let r = h.get(self.toRealmObject()) {
                // get the latest realm version for most uptodate data and map back to abstracted structs on init
                return Self(r)
            } else {
                // otherwise return self as it's the most uptodate version of the data struct
                return self
            }
        }, set: h.updateConvertible)
    }
}

However, I am having an issue when tried to link (read) it to Widget Extension.

@main
struct MyWidget: Widget {
    let kind = "MyWidget"

    var body: some WidgetConfiguration { IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in
            WidgetView()
        }
        .supportedFamilies([.systemSmall, .systemMedium])
        .configurationDisplayName("My Widget")
        .description("This is widget.")
    }
}

struct WidgetView: View {
    @EnvironmentObject var data: DataEntryStore
    
    var body: some View {
        Text(data.getRealmData)
        ViewWithRealmDataFromMainApp()
    }
}

I have tried to follow these instructions by using "App Groups" and Shared Objects to Main iOS App and to Widget Extension, but it didn't work.

More than that, if I link it to Realm, I can't even show static data on the widget. It shows blurry rectangles.

How to show data from the Realm on the iOS 14 widget?

https://i.stack.imgur.com/yzUG1.jpg https://i.stack.imgur.com/nKy6i.jpg

0 Answers
Related