Reputation:
I have a function which is a part of some WebScraping Code. Pretty "deep" in the function I have a value which I want to display in a chart. To do that I need to get the variable "elevation" out of the function parseElevation(). I have tried
func parseElevation() -> String {
This however doesn't work because the variable "elevation" is "one layer deeper.
This is the code:
func parseElevation() {
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))
print(afterEqualsTo)
let elevation = afterEqualsTo
}
}
}
Does somebody have an idea how to solve this problem. I have always had a problem with returning values in swift.
Upvotes: 0
Views: 581
Reputation: 285069
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.
Upvotes: 2