🍁

Swift: NSAlertの本文が長すぎる場合の対処法

2020/10/03に公開

macOSでNSAlertを用いると、比較的簡単にエラーをユーザーに提示することができる。また、エラーに対する対処をユーザーに選択させることもできる。

しかし、ネットワークエラーなどをError(ないしNSError)で受け取ったときにそれをそのまま表示する場合、NSAlertのinformativeTextが長文となり、画面上に表示しきれないということがありうる(そもそもErrorをそのまま表示するなと言われればその通り)。
長文のNSAlert

このような表示になってしまうと、NSAlertボトムのアクションボタンがユーザーから見えない位置に移動してしまい。アプリを終了する以外でこの状態を切り抜けることが難しくなる。

NSAlertの高さや幅を調節したり、NSAlertの中身をスクロールビューにしたりといった対処も考えたが、今回はそもそも長文を省略表示してしまう対処法を実装してみた。

Errorを受け取ってNSAlertを表示する実装例

class Alert {

    static func showError(error: Error, window: NSWindow? = nil) {
        let alert = NSAlert(error: error as NSError)
	// ここで、もしもinformativeTextが既定の文字数よりも長かった場合は、
	// 後ろに三点リーダーをつけて省略表示するようにしている。
        if 500 < alert.informativeText.count {
            alert.informativeText = "\(alert.informativeText.prefix(500))…"
        }
	// windowを受け取った時はSheetに表示し、そうでない場合は独立したWindowで表示する。
        if window == nil {
            alert.runModal()
        } else {
            alert.beginSheetModal(for: window!, completionHandler: nil)
        }
    }
    
}

Discussion