2017-01-19 1 views
1

My Swift 3, Xcode 8.2 MacOS 앱은 웹 서비스 호출을 통해 여러 테이블을로드합니다. 테이블은 내 7 개의 뷰 컨트롤러 중 하나 이상에서 사용되므로 AppDelegate에 배치했습니다. 문제는 AppDelegate 메소드 인 applicationWillFinishLaunching과 applicationDidFinishLaunching이 ViewController viewDidLoad 메소드 다음에 실행된다는 것입니다. 결과적으로 테이블 뷰에는 데이터가 표시되지 않습니다. ViewController viewDidLoad 메서드 중 하나에서 데이터를로드하는 appDelegate 메서드를 호출하여 제대로 작동하도록 만들 수있었습니다. 어떤 ViewController도 응용 프로그램을 시작할 때 호출 될 수 있기 때문에 중복 호출을 방지하기 위해 모든 호출과 플래그 지정 메소드의 일종을 추가해야합니다.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() 

코드는 윈도우가 나타날 때의 TableView가 채워져 있는지에 작동합니다. 코드가 많지는 않지만 모든 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() 

경우에, 나는 내 자리에 자신의 답변을 받아 들일 수 있습니다.

관련 문제