I recently had a similar problem where the safe area insets are returning (0, 0, 0, 0) as soon as viewDidLoad is triggered. It seems that they are set fractionally later than the rest of the view loading.
I got round it by overriding viewSafeAreaInsetsDidChange and doing my layout in that instead:
override func viewSafeAreaInsetsDidChange() {
// ... your layout code here
}