gpt4 book ai didi

ios - Swift 2 api调用比其他函数运行时间更长

转载 作者:行者123 更新时间:2023-11-29 01:09:15 25 4
gpt4 key购买 nike

首先让我说我是 Swift 2 的新手,并且正在构建我的第一个应用程序,该应用程序为数据 (JSON) 调用 api (php)。我遇到的问题是,当我调用 api 时,其他函数在 api 可以发回数据之前运行。

我研究了某种类型的 onComplete 以在 api 响应完成后调用函数。我相信对于你们中的大多数人来说这很容易,但我似乎无法理解它。

提前致谢!

class ViewController: UIViewController {

var Selects = [Selectors]()

var list = [AnyObject]()

var options = [String]()

var index = 0

@IBOutlet var Buttons: [UIButton]!

override func viewDidLoad() {
super.viewDidLoad()
self.API()
self.Render()
}

func API() {
let url = NSURL(string: "http:api.php")
let request = NSMutableURLRequest(URL: url!)

let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if data == nil {
print("request failed \(error)")
return
}
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)

if let songs = json["songs"] as? [[String: AnyObject]] {
for song in songs {
self.list.append(song)
}
}
self.Selects = [Selectors(Name: self.list[self.index]["name"] as? String, Options: self.BuildOptions(), Correct: 2)]
}
catch let error as NSError {
print("json error: \(error.localizedDescription)")
}
}
task.resume()
}

func BuildOptions() {
// BuildOptions stuff happens here
}

func Render() {
// I do stuff here with the data
}
}

最佳答案

所以我假设您的 Render() 方法在数据从 api 返回之前被调用?将您的 api 调用代码保留在 View Controller 中是糟糕的设计,但由于您是新手,我不会对此进行扩展。在您的情况下,它就像不在 viewDidLoad() 中调用您的 Render() 方法一样简单 - 在解析完 JSON 中的数据后调用它(在 self.Selects = [Selectors... 行)。 NSURLSession.sharedSession().dataTaskWithRequest(request) 方法被异步调用,并且在该方法完成获取您的数据后执行带有 data、response、error 参数的回调 block 数据,因此它可能发生在 viewDidLoad 长时间完成并且最初没有数据可处理的情况下,因为异步方法仍在等待 API 的响应。

编辑 - 说到处理 api 调用,明智的做法是将它们与特定 View Controller 分开,以维护干净的可重用代码库。您应该调用 API 并等待它的回调,所以我只对您的 API 函数执行此操作,它看起来像这样:

 static func callAPI(callback: [AnyObject]? -> Void ) {
let url = NSURL(string: "http:api.php")
let request = NSMutableURLRequest(URL: url!)

let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if data == nil {
completion(nil)
}
do {
var list = [AnyObject]()
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)

if let songs = json["songs"] as? [[String: AnyObject]] {
for song in songs {
self.list.append(song)
}
}
completion(list)
}
catch let error as NSError {
print("json error: \(error.localizedDescription)")
completion(nil)
}
}
task.resume()
}

一般来说,方法应该做一件特定的事情 - 在您的情况下调用 api 并返回数据或错误。在回调时在 View Controller 中初始化您的选择器。使用上面的代码,您的 View Controller 的 viewDidLoad 看起来像这样:

override func viewDidLoad() {
super.viewDidLoad()
YourApiCallingClass.callApi() {
result in
if let list = result {
self.list = list
self.Selects = [Selectors(Name: self.list[self.index]["name"] as? String, Options: self.BuildOptions(), Correct: 2)]
self.Render()
} else {
//Handle situation where no data will be returned, you can add second parameter to the closue in callApi method that will hold your custom errors just as the dataTaskWithRequest does :D
}

}
}

现在你有了很好的关注点分离,API 方法是可重用的, View Controller 只处理它获取数据时发生的事情。如果你在等待的时候在屏幕中间点击一个 UIActivityIndi​​cator 就好了,它看起来会很整洁和专业 :P

关于ios - Swift 2 api调用比其他函数运行时间更长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35962115/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com