본문 바로가기

Programing/My OSS

[Swift] Hours 5 - v1.2.1 : viewDidAppear

희찬님 환경에서 버전 정보가 여러개 붙는 버그를 발견했다.

그런데 나한테는 재현이 안된다.

처음에는 High Sierra에서만 발생하나 생각했다.

 

그러다가 원인을 찾았다.

앱버전을 붙이는 것을 viewDidAppear에서 수행하고 있었다.

    override func viewDidAppear() {
        super.viewDidAppear()
        
        let beforeTitle = self.view.window?.title
        let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
        self.view.window?.title = "\(beforeTitle!) (v\(appVersion!))"
    }

문제는 애플리케이션이 Hide 상태에서 다시 표시가 되면 이 함수가 계속 수행이 된다는 것이다.

NSViewController의 Life Cycle을 살펴보자.

그렇다고 viewDidLoad에 해당 작업을 넣어버리면 viewDidLoad 시점에서는 view.window?.title 값을 획득할 수 없다.

왜냐하면 viewDidLoad는 윈도우에 view를 추가하기 전에 호출되기 때문이다. 또한 NSViewController는 윈도우 프로퍼티를 가지지 않는다.

 

알고보니 PRODUCT_NAME 이라는 프로퍼티는 CFBundleName 에서 가져올 수 있다는 것을 알게되었다.

기존 타이틀에서 더할 것이 아닌 번들 정보에서 가져오면 계속 값이 늘어나는 문제를 없앨 수 있다.

class ViewController: NSViewController {
    var titleWithVersion: String?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let productName = Bundle.main.infoDictionary?["CFBundleName"] as? String
        let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
        self.titleWithVersion = "\(productName!) (v\(appVersion!))"
    }
    
    override func viewDidAppear() {
        super.viewDidAppear()
        self.view.window?.title = self.titleWithVersion!
    }

매번 title을 만들 것이 아니고 viewDidLoad에서 한번만 만들어서 내부 변수에 저장해두고 viewDidAppear이 호출되면 그냥 설정만 해주면 된다. 물론 이미 설정이 되어 있으면 안하는 식으로 하는 게 더 효율적이지만 체크하는 것이 더 비용일 것 같아서 그냥 여기까지만 수정했다.