-2

I know the following piece of code is wrong, but I want to show my intent. I want to write a method that will be called by multiple times. and this fetching method will tell me if it is successfully reached.

func fetch(url: String) -> Bool? {
    let defaultSession = URLSession(configuration: URLSessionConfiguration.default)
    let url = URL(string: url)
    var bool: Bool? = nil
    if let url = url {
        defaultSession.dataTask(with: url, completionHandler: { data, response, error in
            if let error = error {
                print(error)
                return
            }
            DispatchQueue.main.async {
                if let httpResponse = response as? HTTPURLResponse, 200...299 ~= httpResponse.statusCode, let data = data {
                    // handle the data.
                    bool = true
                } else {
                    print("something really wrong")
                    bool = false
                }
            }
        }).resume()
    }
    return bool
}

if let bool = fetch(url: "https://www.google.com.hk/webhp?hl=en&sa=X&ved=0ahUKEwimubK7r-HVAhVFmZQKHazMAMMQPAgD"), bool == true {
    // if it is true, I can go for next step.
}
Carl Hung
  • 545
  • 4
  • 17
  • by "multiple fetching" you mean what? I only see the url being used once. Also you don't need `var bool: Bool? = nil`. optionals are `nil` by default. You can just write as `var bool: Bool?` – mfaani Aug 18 '17 at 18:45
  • i said i know which is wrong. i know when i declare `var` the default value is nil. which is a scratch. – Carl Hung Aug 18 '17 at 18:47
  • it's unknown which part *you* know is wrong. Otherwise you'd fix it. Again what do you mean by multiple fetching? – mfaani Aug 18 '17 at 18:48
  • 2
    See https://stackoverflow.com/questions/25203556/returning-data-from-async-call-in-swift-function or other Q&As about "How to return a value from an asynchronous function" – Martin R Aug 18 '17 at 18:48
  • @Marin R, I know this trick. but this time is different, i want to return something. not passing a closure to do something. – Carl Hung Aug 18 '17 at 18:50
  • 1
    @CarlHung That is not a trick, that it how to do things with asynchronous methods. If you want to blockingly wait you need Futures – Christopher Oezbek Aug 18 '17 at 18:51
  • @Christopher Oezbek, yes, blocking and wait until the job finished. and return me if it is successful. – Carl Hung Aug 18 '17 at 18:52
  • There is no native Future API in Swift you must use some library: https://medium.com/@johnsundell/under-the-hood-of-futures-promises-in-swift-69bd6e7ab972 – Christopher Oezbek Aug 18 '17 at 19:00
  • Possible duplicate of [Returning data from async call in Swift function](https://stackoverflow.com/questions/25203556/returning-data-from-async-call-in-swift-function) – Christopher Oezbek Aug 18 '17 at 19:01

1 Answers1

0

Making the UI wait on completion of some API call is not recommended. The app will have no control over how long that API call will take. Situations with bad network connectivity can take several seconds to respond.

You can handle a situation like this is to use a completion handler.

func fetch(url: String, completion: @escaping (_ success: Bool) -> Void) {
    let defaultSession = URLSession(configuration: URLSessionConfiguration.default)
    let url = URL(string: url)

    if let url = url {
        defaultSession.dataTask(with: url, completionHandler: { data, response, error in
            if let error = error {
                print(error)
                return
            }

            if let httpResponse = response as? HTTPURLResponse, 200...299 ~= httpResponse.statusCode, let data = data {
                // handle the data.
                completion(true)
            } else {
                print("something really wrong")
                completion(false)
            }
        }).resume()
    }
}


func testFetch () {
    fetch(url: "https://www.google.com.hk/webhp?hl=en&sa=X&ved=0ahUKEwimubK7r-HVAhVFmZQKHazMAMMQPAgD") { (success) in
            // if it is true, I can go for next step.
        DispatchQueue.main.async {
            if success {
                // it was good
            }
            else {
                // not good
            }
        }
    }
}
ryantxr
  • 4,119
  • 1
  • 11
  • 25