URLSession completion handlers - howto

Discussion in 'iOS Programming' started by mentaluproar, Dec 30, 2017.

  1. mentaluproar, Dec 30, 2017
    Last edited: Dec 30, 2017

    mentaluproar macrumors 68000

    mentaluproar

    Joined:
    May 25, 2010
    Location:
    Ohio, USA
    #1
    I'm writing my first iOS app and I'm stuck on getting my app to wait for get a response from an HTTP POST request. I can't make any sense from the material I find online or in the ebook from apple. Is there a walkthrough that explains this? I've been staring at this for a week.

    EDIT: Sorry and thanks for moving this, mods.
     
  2. bjet767 macrumors 6502a

    Joined:
    Oct 2, 2010
    #2
    A completion handler is a series of instructions which will run after a process is complete while iOS goes on its merry way and processes any other lines of code after the function containing the completion handler.


    Essentially you can’t stop or pause iOS and wait for something to happen, so the completion handler is essentially a process which will happen after the URL is loaded (or whatever you are doing).

    This probably isn’t a great description, but think of it this way; you ask to load some file or thing via a URL you have listed. While that URL is loading the next line of code in your app is executed, even though the URL has not finished loading. So the answer is a “completion handler” a part of the instruction/function which is loading your URL. The simplest is to report an error or let the user know the data is downloaded and ready to use.
     
  3. ArrayOfLilly macrumors newbie

    ArrayOfLilly

    Joined:
    Aug 16, 2017
    Location:
    Budapest, Hungary
    #3
    I'm started to learn swift 4 recently too, and I'm using an Udemy course from Angela Yu, her course maybe worth a look. In her lesson she uses Alamofire library to handle networking, http requests and responses. It's much easier than write from scratch every time all your callback functions, etc..
     
  4. PhoneyDeveloper macrumors 68040

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #4
    Networking is a big topic but there are many many examples of this online. I would look at https://www.raywenderlich.com to find a tutorial, although there are many others. Come back with specific questions once you have code that you think should work.
     
  5. Krevnik macrumors 68040

    Krevnik

    Joined:
    Sep 8, 2003
    #5
    To add to what bjet767 says, the main goal here is to not wait at all, but rather act on the result when it becomes available. That's the purpose of completion handlers. The completion handler should be the one calling into the code that needs the results from the server. The code sending the request should not be expecting the result in a return value or anything. That way lies pain and suffering.

    This is probably a good use of a playground, IMO to learn this stuff, rather than buried in your app itself. Here's a starting point you can use:

    Code:
    //: Playground - noun: a place where people can play
    import Foundation
    import XCPlayground
    
    struct Object1 {
        func sendRequest(toObject: Object2) {
            let theUrl = URL(string: "http://google.com")!
    
            let dataTask = URLSession.shared.dataTask(with: theUrl) {
                data, response, error in
    
                toObject.receiveResult(data: data, response: response, error: error)
            }
    
            dataTask.resume()
        }
    }
    
    struct Object2 {
        func receiveResult(data: Data?, response: URLResponse?, error: Error?) {
            guard let validData = data else {
                print("Failed to get Result")
                return
            }
    
            print(validData)
            if let resultHtml = String(data: validData, encoding: String.Encoding.ascii) {
                print(resultHtml)
            } else {
                print("Couldn't get the string of the response data")
            }
    
            // Let the playground know that we have our result and exit....
            XCPlaygroundPage.currentPage.finishExecution()
        }
    }
    
    var sender = Object1()
    var receiver = Object2()
    
    sender.sendRequest(toObject: receiver)
    
    // Hack for making sure we are allowed to continue execution while we wait for a response during the playground.
    XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
    
     
  6. PhoneyDeveloper macrumors 68040

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #6
    @Krevnik, you might want to point out the completion handler in your code
     
  7. bjet767 macrumors 6502a

    Joined:
    Oct 2, 2010
    #7
  8. mentaluproar thread starter macrumors 68000

    mentaluproar

    Joined:
    May 25, 2010
    Location:
    Ohio, USA
    #8
    I tried alamofire early on, but when I release an app to the app store, I'd like to have as few external pieces as possible, so I pulled it.
    I understand what a completion handler is, just not how to wield it.
     
  9. bjet767 macrumors 6502a

    Joined:
    Oct 2, 2010
    #9
    Since no one is really sure what you want your app to do, it might help if you explain more.

    Do you want:

    Some sort of delay message/visual while the data is loading?
    Th user allowed to do something else while waiting?

    Be more specific and don’t forget Stack Overflow is your friend when there’s coding questions.
     
  10. mentaluproar thread starter macrumors 68000

    mentaluproar

    Joined:
    May 25, 2010
    Location:
    Ohio, USA
    #10
    Sorry. I want the app to show an indicator while waiting, but more importantly, I need a POST query to complete and use part of the response in another POST query.
     

Share This Page