How to Collect The Return Value of a Function (Swift 3)

How to collect the return value of a function (Swift 3)

You can return like below,

let userName = "Jake" //Global variable of the class
let userInfo = test() //Jake

func test() -> String { //single - element tuple will don't have label for return.

return self.userName
}

If you like to return with labels then you need tow or more return values like below,

   func test() -> (name:String,age:Int) {        
return (self.userName,125)
}

And access specific values by test().name

Return value from Function in swift

You cannot return something from a closure which doesn't have a return value.

You need an asynchronous completion handler

func parseElevation(completion: @escaping (String) -> Void)  {
webView.evaluateJavaScript("document.body.innerHTML") { result, error in
guard let html = result as? String, error == nil else {
return
}

let leftSideOfTheValue = """
<pre style="word-wrap: break-word; white-space: pre-wrap;">
"""

let rightSideOfTheValue = """
</pre>
"""

guard let leftRange = html.range(of: leftSideOfTheValue) else {
print("cant find left range")
return
}

guard let righRange = html.range(of: rightSideOfTheValue) else {
print("cant find right range")
return
}

let rangeOfTheValue = leftRange.upperBound..<righRange.lowerBound

let elevationInfo = (html[rangeOfTheValue])

let last9 = elevationInfo.suffix(11)

if let index = (last9.range(of: ",")?.upperBound)
{
//prints "value"
let afterEqualsTo = String(last9.suffix(from: index))
completion(afterEqualsTo)
}
}
}

and call it

parseElevation { elevation in
print(elevation)
}

Notes:

  • elevation in the second snippet is only available inside the closure {}.

  • Consider that the completion handler is only called if a result is evaluated. All return statements leave the closure silently.

Return value for function in nested function (Swift 3 | Xcode)

There is no way to return from the outer function from within the inner one. The only way I can think of is by using a completion handler, that you can then call from within the nested function like so:

func checkIfUserExists(userID : String, completion: @escaping (_ userExists: Bool) -> Void)

Getting a return value from a func in another class

There are some ways to do this.

    class complileResults {

var theTestResults : [String: String] = [
"conType": "",
"date": "",
"time": "",
"jitter": "",
"loss": "",
"dspeed": "",
"uspeed": "",
"delay": ""
]
}

class TestView: UIViewController, XMLParserDelegate {

let result = complileResults()

override func viewDidLoad() {
super.viewDidLoad()
result.theTestResults["conType"] = "WiFi"
print(result.theTestResults["conType"] ?? "Err")
}
}

Or this one which is a bit more generic.

class orcomplileResults {

var theTestResults : [String: String] = [
"conType": "",
"date": "",
"time": "",
"jitter": "",
"loss": "",
"dspeed": "",
"uspeed": "",
"delay": ""
]

func setResult(key: String, value: String) {
theTestResults[key] = value
}

func getResult(key: String) -> String {
return (theTestResults[key] ?? "Err")
}
}

class orTestView: UIViewController, XMLParserDelegate {

let result = orcomplileResults()

override func viewDidLoad() {
super.viewDidLoad()
result.setResult(key: "conType", value: "WiFi")
print(result.getResult(key: "conType"))
}
}

Functions and returning values

So in Swift, a function that has no arrow has a return type of Void:

func funcWithNoReturnType() {
//I don't return anything, but I still can return to jump out of the function
}

This could be rewritten as:

func funcWithNoReturnType() -> Void {
//I don't return anything, but I still can return to jump out of the function
}

so in your case...

func deposit(amount : Double) {
balance += amount
}

your method deposit takes a single parameter of Type Double and this returns nothing, which is exactly why you do not see a return statement in your method declaration. This method is simply adding, or depositing more money into your account, where no return statement is needed.

However, onto your withdraw method:

func withdraw(amount : Double) -> Bool {
if balance > amount {
balance -= amount
return true
} else {
println("Insufficient funds")
return false
}
}

This method takes a single parameter of Type Double, and returns a Boolean. In regard to your withdraw method, if your balance is less than the amount you're trying to withdraw (amount), then that's not possible, which is why it returns false, but if you do have enough money in your account, it gracefully withdraws the money, and returns true, to act as if the operation was successful.

I hope this clears up a little bit of what you were confused on.

Completion handler swift 3 return a variable from function

Two issues:

  • The completion handler passes a HistoryKey instance and has no return value so the signature must be the other way round.
  • The call of the completion handler must be inside the completion block of the data task.

To be able to parse the received data outside the completion block return the data on success

enum ConnectionResult {
case success(Data)
case failure(Error)
}

private func getHistoryKeys(searchterm: String, completion: @escaping (ConnectionResult) -> ()) {
let url = PubmedAPI.createEsearchURL(searchString: searchterm)
let task = session.dataTask(with: url) { (data, response, error) in
if let error = error {
completion(.failure(error))
} else {
completion(.success(data!))
}
}
task.resume()
}

and call it

getHistoryKeys(searchterm: String) { connectionResult in 
switch connectionResult {
case .success(let data):
let myParser = XMLParser(data: data)
myParser.delegate = self
myParser.parse()
// get the parsed data from the delegate methods

case .failure(let error): print(error)
}
}

how to return value after the execution of the block? Swift

You cannot simply return here as the reverseGeocodeLocation function is running asynchronously so you will need to use your own completion block:

var superPlace: MKPlacemark!

func getPlaceMarkInfo(coordinate: CLLocationCoordinate2D, completion: (superPlace: MKPlacemark?) -> ()) {
let location = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
geocoder.reverseGeocodeLocation(location) { (arrayPlaceMark, error) -> Void in
if error == nil {
let firstPlace = arrayPlaceMark!.first!
let addressDictionaryPass = firstPlace.addressDictionary as! [String : AnyObject]

self.superPlace = MKPlacemark(coordinate: location.coordinate, addressDictionary: addressDictionaryPass)
completion(superPlace: superPlace)
} else {
completion(superPlace: nil)
}
}
}

can't get returned values in a structure in swift 3

The better way to solve this is by passing on the sensor object to the InfoTableViewController in the prepare(forSegue:) and then inside InfoTableViewControlleryou can call sensor.lastMeasurement.speedInMetersPerSecond or any other var that is inside there. Since the class is passed on by reference it will retain the data even when you transition to a new ViewController.

  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let infoVC = segue.destination as? InfoTableViewController {
infoVC.sensor = self.sensor
}
if segue.identifier == Constants.ScanSegue {

// Scan segue
bluetoothManager.startScan()
scanViewController = (segue.destination as? UINavigationController)?.viewControllers.first as? ScanViewController
}

}
Then of course you can do whatever you want with this data in the new VC( assign the values to labels or whatnot)

Return multiple values from a function in swift

Return a tuple:

func getTime() -> (Int, Int, Int) {
...
return ( hour, minute, second)
}

Then it's invoked as:

let (hour, minute, second) = getTime()

or:

let time = getTime()
println("hour: \(time.0)")


Related Topics



Leave a reply



Submit