M
M
Mimuss2017-01-17 01:18:43
iOS
Mimuss, 2017-01-17 01:18:43

Why such a long UILabel initialization?

There is a simple code that makes a POST request to the Yandex Translator API. The answer is a translated text. However, when receiving a response (and even outputting a response to the console), the initialization of the UILabel takes a very long time, after a few seconds. How to fix it? Why is this happening?

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var textField: UITextField!{
        didSet{
            textField.delegate = self
            textField.text = textToTranslate
        }
    }

    @IBOutlet weak var label: UILabel!{
        didSet{
            print("didSet")
        }
    }

    var textToTranslate: String?{
        didSet{
            TranslateTheText()
        }
    }

    private func TranslateTheText(){
        var request = URLRequest(url: URL(string: "https://translate.yandex.net/api/v1.5/tr.json/translate")!)
        request.httpMethod = "POST"
        let key = "trnsl.1.1.20170105T183003Z.a061e235d7abde36.51b76f0ff88678b7d1cdd254edd2951b4fb00dbf"
        let postString = "key=" + key + "&text=" + textToTranslate! + "&lang=en-ru"
        request.httpBody = postString.data(using: .utf8)

        let task = URLSession.shared.dataTask(with: request) { [weak weakSelf = self] data, response, error in
            guard let data = data, error == nil else {               // check for fundamental networking error
                print("error=\(error)")
                return
            }

            if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {   // check for http errors
                print("statusCode should be 200, but is \(httpStatus.statusCode)")
                print("response = \(response)")
            }

            var parsedObject: Any?
            do {
                parsedObject = try JSONSerialization.jsonObject(with: data,options: JSONSerialization.ReadingOptions.allowFragments)
            }
            catch let error {
                print ("error: \(error)")
            }

            if let source = parsedObject as? [String: Any]{
                if let text = source["text"] as? Array<String>{
                    for temp in text{
                        print(temp)
                        weakSelf?.label.text = temp
                    }
                }
            }
            let responseString = String(data: data, encoding: .utf8)
            print("responseString = \(responseString)")
        }
        task.resume()
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        textToTranslate = textField.text
        return true
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vyacheslav Beltyukov, 2017-01-17
@Mimuss

Let's deal with everything in order:
1. The initialization of the UILabel occurs during the loading of the view from the xib and this happens long before you enter the text :)
2. Based on the first point, I think you wanted to ask "why the answer shows up this late?
Everything has already been said here by ManWithBear . I'll just add how it should look like:

DispatchQueue.main.async { [weak self] in
    self?.label.text = temp
}

3. And in the end, I would like to give some recommendations on the code-style: a) it is not worth
writing . weakSelfjust [weak self]works great. In this situation, the code is easier to read and syntax highlighting works more correctly;
b) capitalized methods are not named
c) if you need to extract several optianals in a row, this can be done in one if statement:
if let source = parsedObject as? [String: Any], let text = source["text"] as? [String] {
    for temp in text {
        print(temp)
        self?.label.text = temp
    }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question