Search code examples
xmlswiftuixml-parsingdecodingdecoder

XMLParser in SwiftUI Decoder.shared


I have a Decoder written using SwiftyXMLParser

And I am in a hurry for help, as my knowledge is not enough to use decoded data in SwiftUI. Namely, I want to use the resulting text in other files of the project. From the example I think you should understand what I want. But the program doesn't work. Point out a bug or help write a code to use it in SwiftUI

XML

<horo>
<date yesterday="02.05.2021" today="03.05.2021" tomorrow="04.05.2021" tomorrow02="05.05.2021"/>
<aries>
<yesterday> Сегодня вам, возможно, будет трудно собраться с мыслями и еще труднее решиться на какие-либо активные действия. Не стоит стараться пересилить упрямый организм, он таких вещей не прощает. </yesterday>
<today> Сегодня вы будете способны превратить самые тривиальные слова в изысканный сонет. Если вам удастся еще и слушателя найти соответствующего - проблема "где и с кем провести субботний вечер" будет решена. Возможно, навсегда. </today>
<tomorrow> Сегодня вам предстоит день, полный борьбы с непониманием в как рядах близких вам людей так и среди прочих. Возможно, вы его так и не победите. </tomorrow>
<tomorrow02> Сила вашего обаяния сегодня во многом будет зависеть от изысканности вашей речи. С помощью пары-другой изящный оборотов вы сможете покорить чье-то сердце. </tomorrow02>
</aries>
</horo>

HoroscopeDecoder.swift

import SwiftyXMLParser


I am very broken, my head is boiling. I can't sleep, I just don't know what to do. help me please


Solution

  • If everything else is working like you said it is in the comments, this should probably fix it:

    class ViewModel : ObservableObject {
        @Published var text = ""
        
        func updateText() {
            HoroscopeDecoder.shared.run(sign: .scorpio, period: .today) { prediction in
                DispatchQueue.main.async {
                  self.text = prediction
                }
            }
        }
    }
    
    struct ContentView: View {
        
        @StateObject var viewModel = ViewModel()
        
        
        var body: some View {
            Text(viewModel.text)
                .padding()
                .onAppear {
                    viewModel.updateText()
                }
        }
        
    }
    

    In general, you don't want to do asynchronous tasks in your View code and especially not in init, which may be called many times. Instead, call it in onAppear.

    Also, your URL task will return on a different thread -- you want to use DispatchQueue.main.async once you're ready to update the UI.