0

I have a published var called spotWallet in my BinanceStore class which conforms to observaleObject. I can create a publisher and subscribe to it. but there is property in my top level struct called balances which is an array of Balance struct. What I want to achieve is would like to update a property of Balance called price which comes from another network call. I cannot get that to work, in clean combine swiftui way.

class BinanceStore: ObservableObject, Identifiable {
    @Published var spotWallet: SpotWallet?
    @Published var loadingError: String = ""
    @Published var showAlert: Bool = false
    private var cancellableSet: Set<AnyCancellable> = []
    private let binanceFetcher: BinanceFetchable
    
    init(binanceFetcher: BinanceFetchable) {
        self.binanceFetcher = binanceFetcher
    }
    
    func AccountDetailsOnSpot() async {
        binanceFetcher.getAccountDetailsOnSpot()
            .sink { (dataResponse) in
                if dataResponse.error != nil {
                    self.createAlert(with: dataResponse.error!)
                } else {
                    self.spotWallet = dataResponse.value!
                }
            }.store(in: &cancellableSet)
    }
    
    func createAlert( with error: NetworkError ) {
        loadingError = error.localizedDescription
        self.showAlert = true
    }
}

struct SpotWallet: Codable, Hashable {
    let makerCommission, takerCommission, buyerCommission, sellerCommission: Int
    let canTrade, canWithdraw, canDeposit: Bool
    let updateTime: Int
    let accountType: String
    let balances: [Balance]
    let permissions: [String]
}


protocol BinanceFetchable {
    func getAccountDetailsOnSpot() -> AnyPublisher<DataResponse<SpotWallet, NetworkError>, Never>
}

class BinanceFetcher {
    var coinPublisher = PassthroughSubject<CoinBalance, Never>()
}

extension BinanceFetcher: BinanceFetchable {
    
    func getAccountDetailsOnSpot() -> AnyPublisher<DataResponse<SpotWallet, NetworkError>, Never> {
        let endpoint = "/api/v3/account"
        let params = BinanceWrapper.shared.makeRequestReady(queries: nil)
        let url = URL(string: "\(BinanceWrapper.BINANCE_BASE_URL)\(endpoint)")!
        return AF.request(url, parameters: params, encoding: URLEncoding.default, headers: BinanceWrapper.BINANCE_HTTP_HEADERS)
            .validate()
            .publishDecodable(type: SpotWallet.self)
            .map { response in
                response.mapError { error in
                    return NetworkError.parsing(description: error.localizedDescription)
                }
            }
            .receive(on: DispatchQueue.main)
            .eraseToAnyPublisher()
    }
    
    
}
  • You "would like to update a property of Balance called price". You haven't shown what the "Balance" structure/class looks like. Your "balances" field is a let constant - if Balance is also a structure then you're not going to be able to change it because that structure is part of "let" field. Where are you having trouble? What error are you working around? – Scott Thompson May 02 '22 at 20:15
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community May 08 '22 at 15:11

0 Answers0