Установка текста на метке с использованием данных JSON - PullRequest
0 голосов
/ 22 ноября 2018
}

Привет, ребята, у меня проблема с установкой значения для метки.Метка должна отображать количество элементов в массиве внутри моего JSON (ссылка - followers_url переменная).Я звоню alamo и делаю запрос с этим URL.Когда я печатаю значение в методе parseData(), я получаю правильный результат.Когда я печатаю его внутри configureView() и viewDidLoad(), я всегда получаю 0.

Установка текста метки также работает только внутри метода parseData().Любые идеи, как я могу заставить его работать?

Ответы [ 3 ]

0 голосов
/ 22 ноября 2018

Вы должны узнать кое-что о методах парсинга iOS.Затем узнайте, как создать модель, используя класс или структуру.Тогда вы получите идею.

Вам также следует изучить Object Mapper .

0 голосов
/ 22 ноября 2018

Вы имеете дело с асинхронной операцией.Асинхронные операции - это «действия», которые отправляются и требуют от вас ожидания до их завершения.Подумайте о загрузке веб-сайта в Safari.Когда вы наберете, скажем, stackoverflow.com в вашем браузере, загрузчик уведомит, что что-то загружается.Пока страница загружается, вы, очевидно, не можете видеть, что находится на веб-странице.Там только пустая белая страница.

То же самое происходит с вашим запросом.Когда вы вызываете функцию callAlamo, вы указываете приложению начать загрузку чего-либо.Это требует от вас подождать, пока задача не будет выполнена.Если вы подсчитаете элементы в followersAndFollowingArray сразу после вызова сервера, то вы получите его пустым, поскольку запрос все еще ожидает завершения.Это все равно что делать вид, что вы просматриваете веб-сайт stackoverflow.com сразу после того, как набрали URL.Вы не можете.

Вот где замыкания пригодятся.Вы можете использовать замыкания для выполнения чего-либо, когда другое действие было завершено.В этом случае я бы запустил веб-запрос, отобразил спиннинг загрузки, чтобы уведомить пользователя о том, что что-то загружается, и, наконец, заполнил followersLabel вместе с остановкой анимации.Вы можете сделать что-то подобное

func callAlamo(url: String, completion: @escaping ([User]) -> Void) {
    if Connectivity.isConnectedToInternet {
        Alamofire.request(url).validate().responseJSON { response in
            let userData = self.parseData(data: response.data!)
            completion(userData)
        }
    }
}

Кроме того, вы должны разрешить методу parseData вернуть проанализированный массив Users, чтобы функция callAlamo могла его использовать.

func parseData(data : Data) -> [User] {
    do {
        return try JSONDecoder().decode([User].self, from: data)
    } catch let jsonErr {
        print("Error serializing", jsonErr)
        return [User]()
    }
}

Наконец, вы можете выполнить функцию callAlamo внутри метода configureView, выполнив действие после завершения запроса к серверу.В нашем случае мы хотим заполнить метку.

private func configureView(){
    followersLabel.text = String(followers)

    // Starting the loading animation
    startAnimation()

    callAlamo(url: "Hello") { userData in
        // Assigning the callAlamo result to your followers array
        // once the server request has been completed
        self.followersAndFollowingArray = userData

        // This will return the number you'd expect
        print(self.followersAndFollowingArray.count)

        // Stopping the loading animation
        stopAnimation()
    }
}

Прямо сейчас у вас, вероятно, не будет методов startAnimation и stopAnimation, но вы можете свободно их реализовывать, я просто хотелчтобы дать вам представление о классической реализации.

0 голосов
/ 22 ноября 2018
Alamofire.request(url).validate().responseJSON { response in
            self.parseData(data: response.data!)
        }

Этот запрос выполняется в другом фоновом потоке.Поэтому, когда вы вызываете функцию callAlamo, ответ получен в блоке завершения ({response in).Поэтому, когда вы вызываете print () после callAlamo.ответ еще не получен и вызывается print, поэтому значение не обновляется.Поэтому, пожалуйста, выполняйте операцию с ответом только через блок завершения.Если вы хотите установить запись метки, вы устанавливаете код метки после self.parseData в блоке завершения ({ответ в).Убедитесь, что вы установили его в основной очереди, поскольку операцию пользовательского интерфейса необходимо выполнять только в основной очереди

Следующий вопрос поможет установить метку в основном потоке.

В Swift каквызвать метод с параметрами в главном потоке GCD?

Вам необходимо понять концепцию многопоточности, чтобы лучше понять это.Следуйте этому https://medium.com/@gabriel_lewis/threading-in-swift-simply-explained-5c8dd680b9b2

...