There are many ways to solve this problem, but I would recommend using the completion block that the Result Enum expects. this is likely to be the fastest way.
the final listing has exactly two states, success and error, which is a big advantage for the usual two optional return values (data and errors), which lead to 4 possible states.
enum Result<T> { case Success(T) case Error(String, Int) }
Using the result in the completion block completes the puzzle.
let InvalidURLCode = 999 let NoDataCode = 998 func getFrom(urlString: String, completion:Result<NSData> -> Void) { // make sure the URL is valid, if not return custom error guard let url = NSURL(string: urlString) else { return completion(.Error("Invalid URL", InvalidURLCode)) } let request = NSURLRequest(URL: url) NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in // if error returned, extract message and code then pass as Result enum guard error == nil else { return completion(.Error(error!.localizedDescription, error!.code)) } // if no data is returned, return custom error guard let data = data else { return completion(.Error("No data returned", NoDataCode)) } // return success completion(.Success(data)) }.resume() }
because the return value is an enumeration, you must disable it.
getFrom("http://www.google.com") { result in switch result { case .Success(let data): // handle successful data response here let responseString = String(data:data, encoding: NSASCIIStringEncoding) print("got data: \(responseString)"); case .Error(let msg, let code): // handle error here print("Error [\(code)]: \(msg)") } }
another solution would be to go through two completion blocks, one for success and one for error. sort of:
func getFrom(urlString: String, successHandler:NSData -> Void, errorHandler:(String, Int) -> Void)