2017-01-19 2 views
1

My Swift 3, Xcode 8.2 Приложение MacOS загружает несколько таблиц через вызовы веб-сервисов. Поскольку таблицы используются одним или несколькими из семи моих контроллеров представления, я поместил их в AppDelegate. Проблема заключается в том, что приложения AppDelegate методыWillFinishLaunching и applicationDidFinishLaunching запускаются после методов ViewDontLLL ViewController. В результате в представлениях таблицы нет данных. Я смог заставить его работать правильно, вызвав метод appDelegate, который загружает данные из одного из методов ViewDontLLL ViewController. Поскольку любой из ViewControllers можно было бы вызвать при запуске приложения, мне пришлось бы добавить вызов ко всем из них и какой-то метод меток для предотвращения избыточных нагрузок.Выполнение NSApplicationDelegate Code Before ViewController 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 
    } 
} 

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 таблиц и выписок.

+0

Почему бы не просто сделать окно, содержащее вид стола, невидимым при запуске? Затем в файле didFinishLaunching загрузите данные таблицы, а затем покажите окно. – bhaller

ответ

2

Я думаю, что мой комментарий должен быть ответом. Так. Почему бы просто не сделать окно со списком таблиц невидимым при запуске? Затем в файле didFinishLaunching загрузите данные таблицы, а затем покажите окно.

+0

Я добавил код ViewController к вопросу. То, что вы видите, работает. Я ищу что-то более чистое. Я бы подумал, что скрывать и показывать окна было бы столько же дополнительного кода. – curt

0

Я не думаю, что есть какой-либо способ сделать то, что я хочу, как он структурирован в вопросе. Код ViewController может быть уменьшена до

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

создав функцию-обертку в AppDelegate, которая имела ждать в нем. Он также может содержать флаг, указывающий, что данная таблица уже загружена, чтобы не делать избыточный вызов.

Я закончил с другим подходом: я создал суперклас с одноэлементными подклассами для каждой таблицы. Теперь мой метод viewDidLoad выглядит следующим образом:

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

Если какая-либо один приходит с чистым решением исходной задачей, я принимаю их ответ на месте шахты.

Смежные вопросы