UIWindow Keyboard Notifications for Hosted Content

I’m using the standard UIResponder keyboard notifications to observe when the keyboard appears and adjust the content inset of a scroll view so that its content is visible when scrolled all the way down. This works fine, same as it always has. However, this app is a Message app extension, so the window of my view controller is not the same size as the main UIScreen. The keyboard notification coordinates are in terms of the main screen, but the frames of all of my views are in terms of the window. The window is pinned to the bottom of the display, but its frame starts at 0, 0. Is there a way for me to programatically determine the position of this UIWindow in the UIScreen frame? Here’s the code I’m using:


@objc func adjustKeyboard(for notification: Notification) {
    guard let scrollView = scrollView,
        let superview = scrollView.superview,
        let window = scrollView.window,
        let userInfo = notification.userInfo,
        let frameValue = userInfo[UIResponder.keyboardFrameEndUserInfoKey]
            as? NSValue
        else { return }
    
    let frame = frameValue.cgRectValue
    
    let coordinateSpace = UIScreen.main.fixedCoordinateSpace
    
    let frameInSuperview = superview.convert(frame, from: coordinateSpace)
    
    // The window is at the bottom of the screen but its frame needs to be
    // adjusted for that difference
    let offset = scrollView.frame.maxY - frameInSuperview.minY
        + (coordinateSpace.bounds.height - window.frame.height)
    
    animate(alongsideKeyboardNotification: notification, animations: {
        print("Intersection height: \(offset)")
        scrollView.contentInset.bottom = offset
        scrollView.verticalScrollIndicatorInsets.bottom = offset
    })
}

func animate(alongsideKeyboardNotification notification: Notification,
             animations: @escaping () -> Void,
             completion: ((Bool) -> Void)? = nil) {
    let durationKey = UIResponder.keyboardAnimationDurationUserInfoKey
    let curveKey = UIResponder.keyboardAnimationCurveUserInfoKey
    
    guard let userInfo = notification.userInfo,
        let duration = (userInfo[durationKey] as? NSNumber)?.doubleValue,
        let curveValue = (userInfo[curveKey] as? NSNumber)?.intValue,
        let curve = UIView.AnimationCurve(rawValue: curveValue) else {
            animations()
            return
    }
    
    UIView.animate(withDuration: duration,
                   delay: 0,
                   options: curve.asOptions,
                   animations: animations,
                   completion: completion)
}

extension UIView.AnimationCurve {
    
    var asOptions: UIView.AnimationOptions {
        switch self {
        case .easeInOut:
            return .curveEaseInOut
        case .easeIn:
            return .curveEaseIn
        case .easeOut:
            return .curveEaseOut
        case .linear:
            return .curveLinear
        @unknown default:
            return []
        }
    }
    
}


Ideally, I would not need line 19—which won’t work if, for instance, the window were at the top of the screen. I’d rather not hard-code it for that reason. Any ideas?

UIWindow Keyboard Notifications for Hosted Content
 
 
Q