2017-01-19 10 views
1

My Swift 3、Xcode 8.2 MacOSアプリケーションは、Webサービスコールによって複数のテーブルを読み込みます。テーブルは私の7つのView Controllerの1つ以上で使用されているので、AppDelegateに配置しました。問題は、AppDelegateのメソッドapplicationWillFinishLaunchingとapplicationDidFinishLaunchingがViewController viewDidLoadメソッドの後に実行されることです。その結果、テーブルビューにはデータが表示されません。 ViewController viewDidLoadメソッドの1つからデータをロードするappDelegateメソッドを呼び出すことで、正しく動作するようになりました。 ViewControllersのいずれかがアプリケーションの起動時に呼び出される可能性があるので、冗長な負荷を防ぐために、それらのすべてに呼び出しを追加し、何らかのフラグを設定する必要があります。NSApplicationDelegateコードを実行する前に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() 

コードウィンドウが表示されたら、テーブルビューが移入されていることで動作します。それは多くのコードではありませんが、すべてのView Controllerで複製する必要があります。 これはプロトタイプです。プロダクションバージョンには、14のテーブルと呼び出しがあります。

+0

テーブルビューを含むウィンドウを起動時に表示しないのはなぜですか。次にdidFinishLaunchingで、テーブルのデータをロードし、ウィンドウを表示します。 – bhaller

答えて

2

私のコメントは答えになるはずです。そう。起動時にテーブルビューを含むウィンドウが表示されないようにするだけではどうですか?次にdidFinishLaunchingで、テーブルのデータをロードし、ウィンドウを表示します。

+0

質問にViewControllerコードを追加しました。あなたが見えるものはうまくいく。私は何かクリーナーを探しています。私はウィンドウを隠して表示することはちょうど余分なコードになると思うだろう。 – curt

0

私はそれが質問に構造化されている方法を望む方法はないと思います。 ViewControllerコードは、待機中のAppDelegateでラッパー関数を作成することにより、

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

に縮小できます。また、冗長な呼び出しを行わないように、指定されたテーブルがすでにロードされていることを示すフラグを含めることもできます。

私は別のアプローチで行きました:各テーブルのためのシングルトンサブクラスを持つスーパークラスを作成しました。今私のviewDidLoadメソッドは次のようになります。

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

いずれかが、元の問題にクリーンな解決策を思い付く場合、私は私の代わりに自分の答えを受け入れるだろう。

関連する問題