简体   繁体   English

我如何从swift中的viewdidload函数中的GET请求函数中进行数组

[英]how do I array from a GET request function in viewdidload function in swift

I'm very new to swift, so I will probably have a lot of faults in my code but what I'm trying to achieve is send a GET request to a server with paramters inside a function. 我对swift非常新,所以我的代码可能会有很多错误,但我想要实现的是将GET请求发送到一个函数内有参数的服务器。 I want to use the array I receive from the server in my viewdidload and in other functions but cant seem to find a way to store the array so i can use it. 我想在我的viewdidload和其他函数中使用从服务器接收的数组,但似乎无法找到存储数组的方法,以便我可以使用它。 in my function it is filled, but out of my function it is empty 在我的函数中它被填充,但是在我的函数中它是空的

var scenarioArray: Array<Any> = []


let idPersoon = UserDefaults.standard.object(forKey: "idPersoon") as! String

override func viewDidLoad() {
super.viewDidLoad()
ScenarioArray()
print(scenarioArray)
print(self.scenarioArray)
}
func ScenarioArray()  {

    var request = URLRequest(url: URL(string: "http://dtsl.ehb.be/app&web/ios_php/getAllScenariosByPersoon.php?persoonID="+idPersoon)!)
    request.httpMethod = "GET"
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {                                                 // check for fundamental networking error
            print("error=\(error)")
            return
        }
        do {
            if let jsonResult = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary {
                self.scenarioArray = (jsonResult["Scenarios"] as! NSArray) as! Array<Any>
                print("ASynchronous\(self.scenarioArray)")

            }
        } catch let error as NSError {
            print(error.localizedDescription)
            }



    }
    task.resume()
}

Your "problem" is that you are trying to GET data from a server, meaning that you are doing a network call. 您的“问题”是您尝试从服务器获取数据,这意味着您正在进行网络呼叫。

Now...you don't know how long that network call will take when you launch it, if you are on a good network then it might be fast, but if you are on 3G network it might take a while. 现在......你不知道启动网络呼叫需要长时间,如果你在一个良好的网络上,那么它可能会很快,但如果你在3G网络上,它可能需要一段时间。

If the call to your server was done synchronously, the result would be that each and every time you'd try to fetch data your code would focus on doing just that, meaning that nothing else would go on... that is not what you want :) 如果对您的服务器的调用是同步完成的,那么结果就是每次您尝试获取数据时,您的代码都会专注于执行此操作,这意味着没有其他任何内容会继续...这不是您的意思想:)

Instead, when you use URLSession , and call task.resume() that method is executed asynchronously, meaning that it starts on another thread in the background where it will fetch data. 相反,当您使用URLSession并调用task.resume() ,该方法是异步执行的,这意味着它在后台的另一个线程上启动,它将获取数据。

In the meantime, your main thread is free to handle UI rendering and so on. 与此同时,您的主线程可以自由处理UI呈现等。 At some point in the near future your network call finishes and you now have valid data and must inform whoever needs to know. 在不久的将来,您的网络呼叫结束,您现在拥有有效数据,并且必须通知需要知道的任何人。

So when you do a call to dataTask(with: completionHandler:) , what you are actually saying is something along the lines of: 所以当你调用dataTask(with:completionHandler :)时 ,你实际上说的是:

"hey...go fetch this data in the background please, and when you're done, I'd like to execute the code I've passed you here in the completionHandler with the parameters you tell me about". “哎......走在后台获取这些数据请,当你做,我想执行我在这里通过你的代码completionHandler你告诉我有关的参数”。

Hope that makes just a little sense :) 希望这只是有点意义:)

Now...you have this code: 现在......你有这个代码:

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard let data = data, error == nil else {                                                 // check for fundamental networking error
        print("error=\(error)")
        return
    }
    do {
        if let jsonResult = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary {
            self.scenarioArray = (jsonResult["Scenarios"] as! NSArray) as! Array<Any>
            print("ASynchronous\(self.scenarioArray)")

        }
    } catch let error as NSError {
        print(error.localizedDescription)
    }
}

That last part of the function call ( { data, response, error in... ) is the completionHandler , which is not executed straight away. 函数调用的最后一部分( { data, response, error in... )是completionHandler ,它不会立即执行。 It is not executed until the retrieval of data has completed. 在数据检索完成之前不会执行。

And therefore when you do a call to your ScenarioArray() function in viewDidLoad , what will happen is that the asynchronous call to fetch data will start in the background and your viewDidLoad will continue what it is doing, meaning that when you say: 因此,当您在viewDidLoad调用ScenarioArray()函数时,会发生异步调用获取数据将在后台启动,并且viewDidLoad将继续它正在执行的操作,这意味着当您说:

print(scenarioArray)
print(self.scenarioArray)

then you can not expect scenarioArray to be populated yet as your task is busy fetching that data in the background. 那么当你的task忙于在后台获取数据时,你不能指望scenarioArray被填充。

So...what you need to do, as @vadian says, is to update your UI once the data has been fetched , meaning, in the completionHandler . 所以......正如@vadian所说,你需要做的是在获取数据后更新你的UI,这意味着在completionHandler

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard let data = data, error == nil else {                                                 // check for fundamental networking error
        print("error=\(error)")
        return
    }
    do {
        if let jsonResult = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary {
            self.scenarioArray = (jsonResult["Scenarios"] as! NSArray) as! Array<Any>
            print("ASynchronous\(self.scenarioArray)")
            //Now you have data, reload the UI with the right scenarioArray
        }
    } catch let error as NSError {
        print(error.localizedDescription)
    }
}

Hope that makes sense and helps you. 希望有意义并帮助你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM