I tried the completion handler as suggested by Gurdev and got something. It does return the values of my array in the MAIN function. But the issue is the same: I have to use Sleep() function for 3 seconds for the HTTP request to complete. This is like hard coding as it could take less or more than 3 seconds to complete. When I remove the Sleep() command, I end up returning a VOID array.
The relevant code is pated below.
Thanks!
--------Web Class--------
import Foundation
import UIKit
class Web {
var ar1 = [Double]()
var ar2 = [Double]()
func getData(str: String, completion: (_ result: [[Double]]) -> Void) {
let request = NSMutableURLRequest(url: URL(string: str)!)
httpGet(request as URLRequest!){
(data, error) -> Void in
if error != nil {
print(error ?? "Error")
} else {
let delimiter = "\t"
let lines:[String] = data.components(separatedBy: CharacterSet.newlines) as [String]
for line in lines {
var values:[String] = []
if line != "" {
values = line.components(separatedBy: delimiter)
let str1 = (values[0])//FIRST COLUMN
let str2 = (values[1])//SECOND COLUMN
let db1 = NumberFormatter().number(from: str1)?.doubleValue
self.ar1.append(db1!)
let db2 = NumberFormatter().number(from: str2)?.doubleValue
self.ar2.append(db2!)
}
}
}
}//end of request
sleep(3) // This delay sends data to MAIN, Otherwise NOT
let dta = [self.ar1, self.ar2]
completion(dta)
}
func httpGet(_ request: URLRequest!, callback: @escaping (String, String?) -> Void) {
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: {
(data, response, error) -> Void in
if error != nil {
callback("", error!.localizedDescription)
} else {
let result = NSString(data: data!, encoding:
String.Encoding.ascii.rawValue)!
callback(result as String, nil)
}
})
task.resume()
}
} --------Web Class--------
-------Call In Class--------
Web().getData (str: "https://dl.dropboxusercontent.com/s/f6j7w7zeqaavzqw/s02.txt?dl=0")
{
(result: [[Double]]) in
let x = result[0]
let y = result[1]
}
-------Call In Class--------
Essentially, I am trying to access my variable "ar1" at a certain point in my code but I cannot. I am trying to return the value too but it returns NULL at that point.
What is wrong here ?
I tried like the below code :
import Foundation
import UIKit
class Web {
var ar1 = [Double]()
var ar2 = [Double]()
func getData(str: String) -> [Double] {
let request = NSMutableURLRequest(url: URL(string: str)!)
httpGet(request as URLRequest!){
(data, error) -> Void in
if error != nil {
print(error ?? "Error")
} else {
let delimiter = "\t"
let lines:[String] = data.components(separatedBy: CharacterSet.newlines) as [String]
for line in lines {
var values:[String] = []
if line != "" {
values = line.components(separatedBy: delimiter)
let str1 = (values[0])//FIRST COLUMN
let str2 = (values[1])//SECOND COLUMN
let db1 = NumberFormatter().number(from: str1)?.doubleValue
self.ar1.append(db1!)
let db2 = NumberFormatter().number(from: str2)?.doubleValue
self.ar2.append(db2!)
}
}
dump (self.ar1) // "ar1" accessible HERE (returns all elements)
}
}//end of request
//BUT I WANT TO RETURN "ar1" HERE !
// So that I can use it in my MAIN class
dump (self.ar1) // "ar1" not accessible here (returns ZERO elements)
return self.ar1
}
func httpGet(_ request: URLRequest!, callback: @escaping (String, String?) -> Void) {
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: {
(data, response, error) -> Void in
if error != nil {
callback("", error!.localizedDescription)
} else {
let result = NSString(data: data!, encoding:
String.Encoding.ascii.rawValue)!
callback(result as String, nil)
}
})
task.resume()
}
}
In your code you are returning the
ar1
from the return statement of your method whereas the value toar1
is being set in Aysnchronous callback completion handler. You should use the completion handler block where you are trying to access the value ofar1
. HTTPGet function is running in Async mode and value inar1
is set in the callback handler block.Let me know if you need any further help on this.