Получение данных из API через Singleton

swift

#1

Здравствуйте, случилась такая проблема я не понимаю как мне достать данные из json так что бы я их мог использовать в любом месте.
сам код

import Foundation

enum ApiType {
    case getRocket
    
    var request: URLRequest {
        let url = URL(string: "https://api.spacexdata.com/v4/rockets/")!
        let request = URLRequest(url: url)
        return request
    }
}

class ApiManager{
    static let shared = ApiManager()

    func getInfo(completion: @escaping (Rocket) -> Void){
        let request = ApiType.getRocket.request
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            if let data = data, let rocket = try? JSONDecoder().decode(Rocket.self, from: data) {
                completion(rocket)
            }else{
                completion([])
            }
        }
        task.resume()
    }
} 

ViewController

import UIKit

class ViewController: UIViewController {
@IBOutlet weak var test: UILabel!
override func viewDidLoad() {
    super.viewDidLoad()
    
    var a = "1"
    ApiManager.shared.getInfo { RocketInf in
        self.test.text = RocketInf[0].company!
        a = RocketInf[0].company!
        print(a) // выводит SpaceX
    }
    print(a) // выводит 1
}

}

Когда я получаю данные через ApiManager.shared.getInfo то полученные данные я могу использовать только внутри скобок, а мне надо вынести ее в переменную что бы потом ввести на экран. Так же не получается сразу добавить в label
Подскажите как перезаписать полученные данные в переменную или сразу ввести на экран (например в label)?


#2
@IBOutlet weak var test: UILabel!

var a: Rocket?

override func viewDidLoad() {
    super.viewDidLoad()
    
    ApiManager.shared.getInfo { RocketInf in
        self.a = RocketInf
        self.updateLabel()
    }

    updateLabel()
}

func updateLabel() {
    DispatchQueue.main.async {
        if let model = self.a {
            self.test.text = model[0].company!
        } else {
            self.test.text = "No value"
        }
    }
}

#3

тут я дописал self так как без него не пропускает

Ошибка: UILabel.text must be used from main thread only

и в итоге в label выводит No value
Может ли быть ошибка в том как я получаю данные из API? (весь код выше осталась только структура Json )


#4

Поправил моменты.

При первом запуске экрана будет выводиться “No value”. После того как запрос отработает и вернутся данные, должно вывести название. Если нет, то посмотрите что возвращается, через принт или через дебагер.
В остальном логика верная.


#5

Спасибо за помощь, смог решить проблему добавив DispatchQueue.main.async, сейчас буду разбираться что это

func updateLabel() {
        if let model = a{
            DispatchQueue.main.async {
                self.test.text = model[0].company!
            }
        } else {
            self.test.text = "No value"
        }
    }