UIView在使用SwiftyJSON和Alamofire

时间:2017-11-24 03:24:34

标签: alamofire swifty-json swift3.2

我想使用API​​请求获取数据。使用SwiftyJson和Alamofire获取数据。问题是获取数据但是在获取值之前加载了视图。我如何解决问题?我的代码如下:

func fetchData(){
    Alamofire.request(favUrl, method: .get, parameters: [:]).responseJSON {
        response in
        if response.result.isSuccess{

            let dataFetched : JSON = JSON(response.result.value!)
            //print(dataFetched)
            let titleDisp = dataFetched["title"].arrayObject as? [String]
            //print(titleDisp)
            self.trackList = dataFetched["track_id"].arrayObject as? [String]

            print(self.trackList)

        }else{
            print("Error \(String(describing: response.result.error))")

        }
    }
}


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

2 个答案:

答案 0 :(得分:0)

Alamofire mathod以异步方式运行。不在UIThread中。然后在完成方法运行后必须重新加载这些视图。

例如 - tableview

func fetchData(){
    Alamofire.request(favUrl, method: .get, parameters: [:]).responseJSON {
        response in
        if response.result.isSuccess{

            let dataFetched : JSON = JSON(response.result.value!)
            //print(dataFetched)
            let titleDisp = dataFetched["title"].arrayObject as? [String]
            //print(titleDisp)
            self.trackList = dataFetched["track_id"].arrayObject as? [String]

            print(self.trackList)

            // In here you have to reload, set your uiviews or all calculation

            tableview.reloadData()

        }else{
            print("Error \(String(describing: response.result.error))")

        }
    }
}

答案 1 :(得分:0)

了解应用程序运行多个线程非常重要。主线程(也称为UI线程)执行应用程序可见部分的操作,包括显示视图,对按钮作出反应等。

您无法阻止主线程。

当你调用外部资源(如API调用或加载外部图像)时,它们会在一个单独的线程上执行。该线程独立于主线程。两个线程都没有等待另一个。在加载数据时,应用程序仍会对按钮作出反应。您要求的是在加载数据之前阻止显示视图。您可以这样做,但您必须了解这可能需要一些时间,具体取决于您的网络连接。您可以采取两种方法。

  1. 转换到显示数据但放置" Loading"屏幕上的元素,直到数据加载,然后删除"加载"元素然后用数据重新显示视图。

  2. 在显示视图之前加载数据。使前一个视图加载数据,然后转到必须显示数据的视图。

  3. 您还必须确定此数据是加载ONCE还是每次显示视图时。通过将调用放在viewDidLoad中,API调用只会发生一次,直到重新启动应用程序。如果您希望每次显示屏幕时都加载数据,请将调用放在viewWillAppear。

    // Approach #1
    func fetchData(){
    
        self.showSpinner() 
    
        Alamofire.request(favUrl, method: .get, parameters: [:]).responseJSON {
            response in
            self.hideSpinner() 
            if response.result.isSuccess {
    
                let dataFetched : JSON = JSON(response.result.value!)
                //print(dataFetched)
                let titleDisp = dataFetched["title"].arrayObject as? [String]
                //print(titleDisp)
                self.trackList = dataFetched["track_id"].arrayObject as? [String]
    
                print(self.trackList)
    
                // Actually update the relevant screen elements here.
    
            } else {
                print("Error \(String(describing: response.result.error))")
            }
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        //fetchData()
    }
    
    override func viewWillAppear() {
        super.viewWillAppear()
        fetchData()
    }
    
    func showSpinner() {
        // IMPLEMENT ME
    }
    func hideSpinner() {
        // IMPLEMENT ME
    }