在ViewController viewDidLoad

时间:2017-01-19 01:48:00

标签: macos cocoa swift3 appdelegate

My Swift 3,Xcode 8.2 MacOS应用程序通过Web服务调用加载多个表。由于这些表由我的七个视图控制器中的一个或多个使用,因此我将它们放在AppDelegate中。问题是AppDelegate方法applicationWillFinishLaunching和applicationDidFinishLaunching在ViewController viewDidLoad方法之后运行。因此,表视图不显示任何数据。通过调用从一个ViewController viewDidLoad方法加载数据的appDelegate方法,我能够正常工作。由于可以在应用程序启动时调用任何ViewControllers,我必须将调用添加到所有这些以及某种标记方法以防止冗余加载。

我的问题是:在哪里可以放置在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。虽然它不是很多代码,但我必须在我的所有View控制器上复制。 这是一个原型。生产版本将有14个表和调用。

2 个答案:

答案 0 :(得分:2)

我想我的评论应该是一个答案。所以。为什么不在启动时使包含表视图的窗口不可见?然后在didFinishLaunching中,加载表数据,然后显示窗口。

答案 1 :(得分:0)

我不认为有任何方法可以按照我想要的方式来解决问题。 ViewController代码可以简化为

appDelegate = NSApplication.shared().delegate as! AppDelegate
appDelegate.getDataFromCatBox(rest: "artists.json", loadFunction: appDelegate.loadArtistTable

通过在AppDelegate中创建一个包含等待的包装函数。它还可以包含一个标志,表明已经加载了一个给定的表,以便不进行冗余调用。

我最终采用了不同的方法:我为每个表创建了一个包含singleton子类的超类。现在我的viewDidLoad方法如下所示:

artists.loadTable()  // The sublass
artistTable.reloadData()

如果有人为原始问题提出了更清晰的解决方案,我会接受他们的答案代替我的。