How to load view after Alamofire finished its job?

a 夏天 提交于 2019-12-13 10:29:11

问题


  • My Issue:

I am trying to load data from Server, through Alamofire, before SubViewController Load its view. After writing the code, I failed to solve the problem of Async Feature of Alamofire. The view is always be loaded in the SubViewController before Alamofire finished its job.

  • Part Of My Code:

ParentViewController:

Leading the way to SubViewController through PrepareForSegue().

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

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

SubViewController:

Test whether the data has been loaded by print() in the its viewDidLoad() and load the data by dataRequest() in 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
      }
   }

 }
  • Problem Description:

Three variables in the SubViewController can not be assigned the valid values after view was loaded.

Three Outputs' results are all 0.

But I can get valid count if I set print() in the dataRequest().

  • My Question:

How to make sure that Alamofire finishes its job?

Where Shall I put the Alamofire Request Function? viewWillApper()? viewDidApper()?

Should I even finished requesting job in ParentViewController's PrepareForSegue() ?


Please teach me how to solve this problem.

A big appreciation for your guide and time.

Ethan Joe


回答1:


You should call Alamofire Request Function in viewDidLoad function. and you should reload table data when you got response from completion block(from where you print the data).

You can reload tableview like,

 self.tableView.reloadData()

hope this will help :)




回答2:


The first thing I noticed is that you are doing 3 asynchronous requests, not one. You could use a completion handler but which one? I think you have 2 options.

  1. Nest the network calls so that the completion of one starts the next one. The downside to this approach is that they will run sequentially and if you add more, you have to continue nesting. An approach like this might be OK if you are only doing 2 calls but beyond that it will get more and more difficult.
  2. Use a semaphore to wait until all the data is loaded from all the remote calls. Use the completion handler to signal the semaphore. If you are going to use this approach, then it must be done on a background thread because use of a semaphore will block the thread and you don't want that happening on the main thread.

These three calls will all happen simultaneously. And the functions will return even though AlamoFire has not completed.

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

These will execute, whether AlamoFire has completed or not.

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

Using semaphores would look something like this:

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

The question I have for you is what are you going to do if some, bit not all of the web calls fail?




回答3:


First create a global bool variable with false

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

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

call prepare segue with segue name and boolVar true from almofire block.



来源:https://stackoverflow.com/questions/36911192/how-to-load-view-after-alamofire-finished-its-job

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!