2017-01-19 222 views
1

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

我的问题是:我可以在哪里放置将在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 
    } 
} 

的视图控制器代码:

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个表格和调用。

+0

为什么不启动包含表视图的窗口在启动时不可见?然后在didFinishLaunching中加载表格数据,然后显示窗口。 – bhaller

回答

2

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

+0

我将ViewController代码添加到问题中。你看到的作品。我正在寻找更干净的东西。我认为隐藏和显示窗口将是同样多的额外代码。 – curt

0

我不认为有什么办法可以做到我想要的结构在问题中的方式。该视图控制器代码可以通过创建的AppDelegate的包装功能曾在它等待降至

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

。它也可以包含一个标志,表示已经加载了一个给定的表格,以避免重复呼叫。

我最终采用了不同的方法:我为每个表创建了一个具有singleton子类的超类。现在我的viewDidLoad方法是这样的:

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

如果任何人有一个更清洁的解决原来的问题来了,我会接受他们的回答在地方煤矿。

相关问题