【发布时间】:2017-01-19 01:47:59
【问题描述】:
我的 Swift 3,Xcode 8.2 MacOS 应用程序通过 Web 服务调用加载多个表。由于这些表被我的七个视图控制器中的一个或多个使用,我将它们放在 AppDelegate 中。
问题在于 AppDelegate 方法 applicationWillFinishLaunching 和 applicationDidFinishLaunching 在 ViewController viewDidLoad 方法之后运行。
因此,表格视图不显示任何数据。通过调用从 ViewController viewDidLoad 方法之一加载数据的 appDelegate 方法,我能够使其正常工作。由于任何 ViewController 都可以在应用程序启动时被调用,因此我必须添加对所有 ViewController 的调用以及某种标记方法以防止冗余负载。
我的问题是:在哪里可以放置在 ViewControllers 加载之前执行的代码?该代码将数据加载到多个字典数组中。这些数组在 AppDelegate 中。
我阅读了 @NSApplicationMain 并将其替换为 main.swift。我假设此时没有任何应用程序对象被实例化,因此我无法调用它们的方法,也不认为我的代码在类之外是有效的。
我的 appDelegate 的相关部分:
class AppDelegate: NSObject, NSApplicationDelegate {
var artists: [[String:Any]]? = nil
var dispatchGroup = DispatchGroup() // Create a dispatch group
func getDataFromCatBox(rest: String, loadFunction: @escaping ([[String: Any]]?) -> Void) {
let domain = "http://catbox.loc/"
let url = domain + rest
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "Get"
let session = URLSession.shared
var json: [[String:Any]]? = nil
dispatchGroup.enter()
session.dataTask(with: request) { data, response, err in
if err != nil {
print(err!.localizedDescription)
return
}
do {
json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [[String: Any]]
}
catch {
print(error)
}
loadFunction(json)
self.dispatchGroup.leave()
}.resume()
}
func loadArtistTable(array: [[String: Any]]?) {
artists = array
}
}
ViewController 代码:
override func viewDidLoad() {
super.viewDidLoad()
appDelegate = NSApplication.shared().delegate as! AppDelegate
appDelegate.getDataFromCatBox(rest: "artists.json", loadFunction: appDelegate.loadArtistTable)
appDelegate.dispatchGroup.wait()
artistTable.reloadData()
}
代码的工作原理是在窗口出现时填充 TableView。虽然代码不多,但我必须在所有视图控制器中进行复制。
这是一个原型。生产版本将有 14 个表和调用。
【问题讨论】:
-
为什么不让包含表格视图的窗口在启动时不可见?然后在didFinishLaunching中,加载表格数据,然后显示窗口。
标签: macos cocoa swift3 appdelegate