0

In order to fully render my View from my View Controller, I need to have a response from a network request.

I have been trying to do this is many different ways, but have been unsuccessful each time.

Originally, I had gotten it to work by making a "synchronous" network request prior to calling any methods to render the View. However, the compiler is warning me that the synchronous network requests are deprecated as of ios 8.

What is the best way to accomplish this in the most performant way?

I have tried:

override func loadView() {

    dispatch_sync(dispatch_get_main_queue()){
        // GET the Markup
        let url = NSURL(string: self.PageURL)
        let request = NSURLRequest(URL: url!)

        let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())

        let RequiredViewData = session.dataTaskWithRequest(request) {(data, response, error) in
            do {
                let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
                self.RequiredViewJSON = json
                self.view = UIView(frame: UIScreen.mainScreen().bounds)
                print(data)
            } catch {
                print("error serializing JSON: \(error)")
            }
        }

        RequiredViewData.resume()
    }
}

But that just makes my app render as a blank screen.

Essentially what I need to accomplish is this: Make a network request and receive the response before any view rendering can occur.

Thanks in Advance!

luckybroman5
  • 284
  • 1
  • 8

2 Answers2

0

I never really tried to override loadView nor know if you should, but I think what you need to do is call super in this case to get your view to render again.

Edit

Also per your comment I put the main thread call "after" you get the call back from the NSURLSession. I might have a } in the wrong spot but should get you close enough.

override func loadView() {

    // GET the Markup
    let url = NSURL(string: self.PageURL)
    let request = NSURLRequest(URL: url!)

    let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())

    let RequiredViewData = session.dataTaskWithRequest(request) {(data, response, error) in
        do {
            let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
                self.RequiredViewJSON = json

                dispatch_sync(dispatch_get_main_queue()){

                    //You may also want to try commenting this out unless you are intentionally creating a blank view.
                    self.view = UIView(frame: UIScreen.mainScreen().bounds)
                    print(data)
                    //call super after you get what you need
                    super.loadView()
                }
            } catch {
                print("error serializing JSON: \(error)")
            }
        }

        RequiredViewData.resume()
    }
}

Hopefully that helps.

Skyler Lauren
  • 3,792
  • 3
  • 18
  • 30
  • Is there a way that I could not execute the network request on the main thread? – luckybroman5 Apr 07 '16 at 18:03
  • Actually I think you are doing this on a background thread anyway. I think NSURLSession is Asynchronous by default and even though you wrapped it in "dispatch_get_main_queue" the call back still happens on a background thread which would cause UI issues because that stuff needs to happen on the main thread. I will update my answer to what I believe you want. However I would highly recommend not overriding loadView. – Skyler Lauren Apr 07 '16 at 18:18
-1

The view controller should handle all of this networking logic in viewDidLoad or viewWillAppear, not in loadView. I'd suggest setting a loading state an initial empty state on the subview, then once you have what you need, update the view with that data. You may need to call setNeedsLayout on the view to update for the new data.

BlueSolrac
  • 2,191
  • 2
  • 12
  • 9