如何在Alamofire完成工作后加载视图?

时间:2016-04-28 09:57:05

标签: ios swift alamofire

  • 我的问题:

我试图在SubViewController加载其视图之前通过Alamofire从服务器加载数据。编写代码后,我无法解决Alamofire的异步功能问题。在Alamofire完成其工作之前,视图始终在SubViewController中加载。

  • 我的部分代码:

ParentViewController:

通过PrepareForSegue()引领SubViewController的方式。

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    if segue.identifier == "CellDetailSegue" {
        if let indexPaths = self.dateCollectionView.indexPathsForSelectedItems() {
            let subViewController = segue.destinationViewController as! SubViewConroller
    }
}

SubViewController:

测试print()viewDidLoad()是否已加载数据,并在dataRequest()

中按viewWillAppear()加载数据
class SubViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var availablePeriods401 = [String]()
    var availablePeriods403 = [String]()
    var availablePeriods405 = [String]()

    override func viewDidLoad() {
        super.viewDidLoad() 
        self.dataRequest(self.availablePeriods401)
        self.dataRequest(self.availablePeriods403)
        self.dataRequest(self.availablePeriods405)
        print(self.availablePeriods401.count)
        print(self.availablePeriods403.count)
        print(self.availablePeriods405.count)    
    }

    func dataRequest(_ target: [String]) {
      Alamofire.request(.POST, "http://httpbin.org/get", parameters: ["foo": "bar"]).responseJSON {
            .
            .
            .
      target = Result
      }
   }

 }
  • 问题描述:

加载视图后,无法为SubViewController中的三个变量分配有效值。

三个输出的结果都是0。

但如果我在print()中设置dataRequest(),我就可以获得有效的计数。

  • 我的问题:

如何确保Alamofire完成工作?

我应该在哪里提出Alamofire请求功能? viewWillApper()viewDidApper()

我是否应该在ParentViewController的PrepareForSegue()

中完成请求作业


请教我如何解决这个问题。

非常感谢您的指导和时间。

Ethan Joe

3 个答案:

答案 0 :(得分:1)

您应该在viewDidLoad函数中调用Alamofire请求函数。当你从完成块(从那里打印数据)得到响应时,你应该reload table data

您可以重新加载tableview,

 self.tableView.reloadData()

希望这会有所帮助:)

答案 1 :(得分:1)

我注意到的第一件事是你正在做3个异步请求,而不是一个。您可以使用完成处理程序,但哪一个?我认为你有2个选择。

  1. 嵌套网络呼叫,以便完成下一个呼叫。这种方法的缺点是它们将按顺序运行,如果添加更多,则必须继续嵌套。像这样的方法可能没问题,如果你只做了2次电话,但除此之外它会变得越来越困难。
  2. 使用信号量等待,直到从所有远程调用加载所有数据。使用完成处理程序来发信号通知信号量。如果你打算使用这种方法,那么它必须在后台线程上完成,因为使用信号量会阻塞线程,你不希望在主线程上发生这种情况。
  3. 这三个电话都将同时发生。即使AlamoFire尚未完成,功能也将恢复。

        self.dataRequest(self.availablePeriods401)
        self.dataRequest(self.availablePeriods403)
        self.dataRequest(self.availablePeriods405)
    

    无论AlamoFire是否已经完成,这些都将执行。

        print(self.availablePeriods401.count)
        print(self.availablePeriods403.count)
        print(self.availablePeriods405.count)    
    

    使用信号量看起来像这样:

    override func viewWillAppear(animated: Bool) {
        // maybe show a "Please Wait" dialog?
    
        loadMyData() {
            (success) in
            // hide the "Please Wait" dialog.
    
            // populate data on screen
    
        }
    }
    
    
    
    func loadMyData(completion: MyCompletionHandler) {
    
        // Do this in an operation queue so that we are not 
        // blocking the main thread.
    
        let queue = NSOperationQueue()
        queue.addOperationWithBlock {
            let semaphore = dispatch_semaphore_create(0)
            Alamofire.request(.POST, "http://httpbin.org/get", parameters: ["foo": "bar1"]).responseJSON {
                // This block fires after the results come back
    
                // do something
    
                dispatch_semaphore_signal(semaphore);
            }
            Alamofire.request(.POST, "http://httpbin.org/get", parameters: ["foo": "bar2"]).responseJSON {
                // This block fires after the results come back
    
                // do something
    
                dispatch_semaphore_signal(semaphore);
            }
            Alamofire.request(.POST, "http://httpbin.org/get", parameters: ["foo": "bar3"]).responseJSON {
                // This block fires after the results come back
    
                // do something
    
                dispatch_semaphore_signal(semaphore);
            }
    
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
    
            completion(true)
        }
    }
    

    Apple Docs - Grand Central Dispatch

    How to use semaphores

    我遇到的问题是,如果某些网络呼叫失败,你会怎么做?

答案 2 :(得分:-1)

首先使用false

创建一个全局bool变量
 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

     if segue.identifier == "CellDetailSegue" && boolVar {
         if let indexPaths =      self.dateCollectionView.indexPathsForSelectedItems() {
             let subViewController = segue.destinationViewController as! SubViewConroller
     }
 }

调用具有segue名称的segue和来自almofire块的boolVar为真。