Saturday, February 24, 2024
HomeiOS Developmentios - Modifications to @Revealed var in ObservableObject not updating view

ios – Modifications to @Revealed var in ObservableObject not updating view


I’ve a view that appears like this:

import SwiftUI
import CoreImage
import CoreImage.CIFilterBuiltins

public struct ShareView: View {
    
    @ObservedObject var viewModel: ShareViewModel
    
    @Surroundings(.presentationMode) var presentationMode: Binding<PresentationMode>
    
    @State var showInfoPopup = false
    
    @State var sessionId: String?
    
    let buttonColor = Coloration(#colorLiteral(crimson: 0.02179291099, inexperienced: 0.05895387381, blue: 0.05662788451, alpha: 1))
    let textColor = Coloration(#colorLiteral(crimson: 1, inexperienced: 1, blue: 1, alpha: 1))
    let accentColor = Coloration(#colorLiteral(crimson: 0.8581416011, inexperienced: 0.9824749827, blue: 0.7862659097, alpha: 1))
    let secondaryTextColor = Coloration(#colorLiteral(crimson: 0.4152581692, inexperienced: 0.4603296518, blue: 0.4508641362, alpha: 1))
    @State var isInitalAppear = true
    
    @State var userName: String?
    @State var userAlias: String?
    
    @State var identify: String = ""
    @State var alias: String = ""
    
    @State var gadgets: [ItemViewModel] = []
    @State var totalViewModel: TotalViewModel = TotalViewModel(complete: 0.00, subtotal: 0.00, tax: 0.00)
    
    let clearItems: (() -> Void)
    
    init(gadgets: [ItemViewModel], totalViewModel: TotalViewModel, clearClosure: @escaping (() -> Void) ) {
        self.viewModel = ShareViewModel()
        self.clearItems = clearClosure
        self.gadgets = gadgets
        self.totalViewModel = totalViewModel
    }
    

    var retryBack : some View { Button(motion: {
        self.presentationMode.wrappedValue.dismiss()
        clearItems()
        }) {
            HStack {
            Textual content("Begin Over")
                .font(.customized("PublicSans-Medium", dimension: 18))
                .padding(7)
                .padding(.main, 5)
                .foregroundColor(textColor)
                .padding(.trailing, 5)
        }
        .background(buttonColor)
        .cornerRadius(20.0)
        .padding(.backside, 15)
        }
    }
    
    public var physique: some View {
        VStack {
            Textual content(viewModel.gadgets.first?.identify ?? "")
            Textual content("Don't be concerned. nWe'll do the maths.")
                .font(.customized("PublicSans-Daring", dimension: 45))
                .foregroundColor(buttonColor)
                .padding(.horizontal)
                .lineLimit(4)
            if let information = viewModel.generateQR(textual content: "https://instance.com/(self.sessionId ?? "")"),
               let picture = UIImage(information:information) {
                Picture(uiImage: picture)
                    .interpolation(.none)
                    .resizable()
                    .body(width: 200, peak: 200)
                HStack {
                    Button {
                        UIPasteboard.basic.string = "https://instance.com/(self.sessionId ?? "")"
                    } label: {
                        VStack {
                            Picture(systemName: "doc.on.doc")
                                .resizable()
                                .body(width: 20, peak: 20)
                                .foregroundColor(buttonColor)
                                .padding(8)
                                .padding(.main, 3)
                                .background(accentColor)
                                .cornerRadius(10.0)
                                .padding(.trailing, 5)
                        }
                        .background(buttonColor)
                        .cornerRadius(20.0)
                        .padding(5)
                    }
                    NavigationLink(vacation spot: SplitView(viewModel: viewModel, sessionId: $sessionId, alias: $userAlias, identify: $userName), label: {
                        HStack {
                            Textual content("Break up")
                                .font(.customized("PublicSans-Medium", dimension: 22))
                                .padding(7)
                                .foregroundColor(textColor)
                                .padding(.main, 4)
                            
                            Picture(systemName: "arrow.left.and.proper.sq.")
                                .resizable()
                                .body(width: 15, peak: 15)
                                .foregroundColor(buttonColor)
                                .padding(8)
                                .background(accentColor)
                                .cornerRadius(10.0)
                                .shadow(coloration: Coloration.black.opacity(0.3), radius: 2, x: 0, y: 3)
                                .padding(.trailing, 5)
                        }
                        .background(buttonColor)
                        .cornerRadius(20.0)
                        .padding(3)
                    })
                    
                }
                
            }
        }
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 15) 
                .fill(Coloration.white)
                .shadow(coloration: Coloration.black.opacity(0.3), radius: 6, x: 0, y: 3)
        )
        .navigationBarBackButtonHidden(true)
        .onAppear {
            if self.isInitalAppear {
                self.showInfoPopup = true
                self.isInitalAppear = false
                Job {
                    guard self.sessionId == nil else { return }
                    self.sessionId = await self.viewModel.createShareSession()
                }
            }
        }.sheet(isPresented: $showInfoPopup, onDismiss: {
            userAlias = alias
            userName = identify
            if let userAlias = self.userAlias {
                Job {
                    await self.viewModel.setVenmo(alias: userAlias)
                }
            }
        }) {
            UserInfoView(isPresented: $showInfoPopup, userName: $identify, userAlias: $alias)
        }
        
        VStack (alignment: .middle) {
            Divider()
            HStack {
                retryBack
                Button(motion: {
                    self.showInfoPopup.toggle()
                    }) {
                        HStack {
                        Textual content("Edit")
                            .font(.customized("PublicSans-Medium", dimension: 18))
                            .padding(7)
                            .padding(.main, 5)
                            .foregroundColor(textColor)
                            .padding(.trailing, 5)
                    }
                    .background(buttonColor)
                    .cornerRadius(20.0)
                    .padding(.backside, 15)
                    }
            }
            .padding(.high)
        }
        .padding()
        .onAppear {
            self.viewModel.setData(gadgets: self.gadgets, totalViewModel: self.viewModel.totalViewModel)
        }
    }
}

this view has the next noticed object var:

@ObservedObject var viewModel: ShareViewModel

Which is outlined as such:

import Basis
import SwiftUI
import FirebaseCore
import FirebaseFirestore

@MainActor
class ShareViewModel: ObservableObject {
    @Revealed var database = Firestore.firestore()
    @Revealed var gadgets: [ItemViewModel] = []
    @Revealed var sessionId: String?
    @Revealed var isFirstAppear = true
    @Revealed var totalViewModel: TotalViewModel
    @Revealed var complete: Float
    @Revealed var splitTip: Float?
    @Revealed var splitTax: Float
    @Revealed var individuals: Int = 1
    
     
    var chosenItems = [UUID: Float]()
    
    public init(gadgets: [ItemViewModel], totalViewModel: TotalViewModel) {
        self.gadgets = gadgets
        self.totalViewModel = totalViewModel
        self.complete = 0
        self.splitTip = totalViewModel.tip
        self.splitTax = totalViewModel.tax
    }
    
    public func generateQR(textual content: String) -> Information? {
        let filter = CIFilter.qrCodeGenerator()
        guard let information = textual content.information(utilizing: .ascii, allowLossyConversion: false) else { return nil }
        filter.message = information
        guard let ciimage = filter.outputImage else { return nil }
        let rework = CGAffineTransform(scaleX: 10, y: 10)
        let scaledCIImage = ciimage.remodeled(by: rework)
        let uiimage = UIImage(ciImage: scaledCIImage)
        return uiimage.pngData()!
    }
    
    public func setVenmo(alias: String) async {
        guard let sessionId = sessionId else { return }
        let sessionRef = database.assortment("classes").doc(sessionId)

        do {
            let sessionDoc = strive await sessionRef.getDocument()

            guard var sessionData = sessionDoc.information(),
                  var _ = sessionData["items"] as? [[String: Any]] else {
                print("Session or gadgets not discovered")
                return
            }
            
            sessionData["alias"] = alias
            strive await sessionRef.setData(sessionData)

            print("Alias up to date efficiently")
        } catch {
            print("Error updating alias")
        }
        
        
    }
    
    lazy var totalClosure: (ItemViewModel, Bool) -> Void = { [weak self] merchandise, wasAdded in
        guard let self = self else { return }

        let worth = merchandise.worth
        let amount = merchandise.amount
        let identify = merchandise.identify
        let currentSessionUsers = merchandise.individuals
        
        if wasAdded {
            let toAdd = worth
            self.chosenItems[item.id] = toAdd
        } else {
            self.chosenItems.removeValue(forKey: merchandise.id)
        }
        self.recomputeTotal(individuals: currentSessionUsers)
    }
    
    personal func recomputeTotal(individuals: Int) {
        var newtotal: Float = 0
        for (key, worth) in self.chosenItems {
            let splitQuantity = self.gadgets.filter {
                $0.id == key
            }.first?.patrons.rely ?? 1
            newtotal += (worth / Float(splitQuantity))
            print("Key: (key), Worth: (worth)")
        }
        self.splitTax = self.totalViewModel.tax / Float(individuals)
        if let tip = self.totalViewModel.tip {
            self.splitTip = tip / Float(individuals)
        }
        self.complete = newtotal + self.splitTax + (self.splitTip ?? 0)
        self.individuals = individuals
        self.objectWillChange.ship()
    }

    
    @MainActor
    public func hear(sessionID: String) async {
        self.sessionId = sessionID
        let _ = Firestore.firestore().assortment("classes").doc(sessionID)
            .addSnapshotListener { documentSnapshot, error in
                Job {
                    guard let doc = documentSnapshot else {
                        print("Error fetching doc: (error!)")
                        return
                    }
                    guard let information = doc.information() else {
                        print("Doc information was empty.")
                        return
                    }
                    do {
                        // Convert Firestore doc information to JSON information
                        let jsonData = strive JSONSerialization.information(withJSONObject: information)
                        
                        // Decode JSON information utilizing JSONDecoder
                        let decoder = JSONDecoder()
                        let sessionData = strive decoder.decode(SessionData.self, from: jsonData)
                        
                        self.gadgets = sessionData.gadgets
                        let currentSessionUsers = self.gadgets.first?.individuals
                        if let currentSessionUsers = currentSessionUsers {
                            self.recomputeTotal(individuals: currentSessionUsers)
                        }
                        
                    } catch {
                        print("Error decoding information: (error)")
                    }
                    print("Present information: (information)")
                }
            }
    }
    
    @MainActor
    public func createShareSession() async -> String? {
        do {
            var itemsData: [[String: Any]] = []
            
            for merchandise in self.gadgets {
                let itemData: [String: Any] = [
                    "id": item.id.uuidString,
                    "price": item.price,
                    "name": item.name,
                    "quantity": item.quantity,
                    "buyers": [],
                    "individuals": merchandise.individuals
                ]
                itemsData.append(itemData)
            }
            
            let sessionData: [String: Any] = [
                "items": itemsData
            ]
            
            let ref = strive await self.database.assortment("classes").addDocument(information: sessionData)
            await hear(sessionID: ref.documentID)
            return ref.documentID
        } catch {
            print("Error including doc: (error)")
            return nil
        }
    }
    
    
    
}

It doesn’t matter what I strive, adjustments to the @Revealed properties within the viewModel don’t replicate within the view. For instance, I’ve Textual content(viewModel.gadgets.first?.identify ?? “”) which I’d anticipate to vary on the viewModel’s listener fireplace. I’ve confirmed that every one my FireStore logic works. How can I repair this and what am I doing unsuitable right here? Thanks!



Supply hyperlink

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments