【Swift】iPhoneのNotchの半径を取得する

# はじめに
非公開のクラスやプロパティにアクセスしているので審査に通るのかは不明です
（自分は試したことないです）
今後OSのアップデートによって使えなくなる可能性もあります
また、今回紹介するものは、簡単に利用できるように[こちら](https://github.com/p-x9/NotchCorners)にライブラリとしてまとめてるので是非使ってください。
https://github.com/p-x9/NotchCorners

# 本編
## 準備
statusBarManagerからプロパティを辿っていく形で取得するので、まずUIApplicationの拡張を書きます。
KVCを利用するので、安全のため`responds(to:)`でメソッドが存在するかの確認を行なっています

(ディスプレイの角の半径(Display Corner Radius)を取得するだけの場合は必要ありません)

```swift
extension UIApplication {
    var statusBarProviderClassName: String? {
        // KeyWindowを取得
        let window = self.windows.first {
            $0.isKeyWindow
        }
        guard let keyWindow = window,
              let windowScene = keyWindow.windowScene,
              let statusBarManager = windowScene.statusBarManager else {
            return nil
        }

        // _UIStatusBarLocalView
        guard statusBarManager.responds(to: Selector(("createLocalStatusBar"))),
              let statusBarLocalView = statusBarManager.perform(Selector(("createLocalStatusBar"))).takeUnretainedValue() as? UIView else {
            return nil
        }
        // UIStatusBar
        guard statusBarLocalView.responds(to: Selector(("statusBar"))),
              let statusBar = statusBarLocalView.perform(Selector(("statusBar"))).takeUnretainedValue() as? UIView else {
            return nil
        }
        //  _UIStatusBar
        guard statusBar.responds(to: Selector(("statusBar"))),
              let _statusBar = statusBar.perform(Selector(("statusBar"))).takeUnretainedValue() as? UIView else {
            return nil
        }

        // Get _UIStatusVisualProvider_iOS
        if _statusBar.responds(to: Selector(("_visualProviderClassName"))) {
            return _statusBar.value(forKey: "_visualProviderClassName") as? String
        }
        return nil
    }
}
```

これを利用してNotchの各種プロパティを取得していきます。

## Notch Size
```swift
let notchSizeKey = "notchSize"
public var notchSize: CGSize {
        guard let className = UIApplication.shared.statusBarProviderClassName,
              let providerClass = NSClassFromString(className),
              providerClass.responds(to: Selector(notchSizeKey)) else {
            return .zero
        }

        return providerClass.value(forKey: notchSizeKey) as! CGSize
    }
```

## Notch Top Radius
![top](https://github.com/p-x9/NotchCorners/raw/main/Resources/top.png)

```swift
let notchTopCornerRadiusKey = "notchTopCornerRadius"
public var notchTopCornerRadius: CGFloat {
        guard let className = UIApplication.shared.statusBarProviderClassName,
              let providerClass = NSClassFromString(className) as? NSObject.Type,
              providerClass.responds(to: Selector(notchTopCornerRadiusKey)),
              let notchTopCornerRadius = providerClass.value(forKey: notchTopCornerRadiusKey) as? CGFloat  else {
            return 0
        }

        return notchTopCornerRadius
    }
```

## Notch Bottom Radius
![bottom](https://github.com/p-x9/NotchCorners/raw/main/Resources/bottom.png)

```swift
let notchBottomCornerRadiusKey = "notchBottomCornerRadius"
public var notchBottomCornerRadius: CGFloat {
        guard let className = UIApplication.shared.statusBarProviderClassName,
              let providerClass = NSClassFromString(className) as? NSObject.Type,
              providerClass.responds(to: Selector(notchBottomCornerRadiusKey)),
              let notchBottomCornerRadius = providerClass.value(forKey: notchBottomCornerRadiusKey) as? CGFloat  else {
            return 0
        }

        return notchBottomCornerRadius
    }
```

## Display Corner Radius
![d](https://github.com/p-x9/NotchCorners/raw/main/Resources/corner.png)

```swift
let displayCornerRadiusKey = "_displayCornerRadius"
public var displayCornerRadius: CGFloat {
        guard let cornerRadius = self.value(forKey: displayCornerRadiusKey) as? CGFloat else {
            return 0
        }

        return cornerRadius
    }
```

# 終わりに
今回取得したNotchのプロパティを使ってこんなのも作ってみました
![anim](https://user-images.githubusercontent.com/50244599/134858058-0417f18f-7649-4060-923c-787a0690b85c.gif)

もしこれを使ってAppStoreの審査に通ったら教えてほしいです
ありがとうございました。