Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# React Native Module 25.0.0 Changelog

## Version 25.4.2 - April 10, 2026

Patch release that fixes a `UIViewControllerHierarchyInconsistency` crash in the Airship embedded view wrapper on iOS when an embedded view is pushed and popped on a navigation stack.

### Changes
- Fixed iOS embedded view wrapper to properly remove its hosted `UIHostingController` as a child view controller when its window is detached, avoiding a `UIViewControllerHierarchyInconsistency` crash on re-attachment.

## Version 25.4.1 - March 26, 2026

Patch release that fixes an Xcode 26.4 Swift compiler crash affecting iOS builds.
Expand Down
34 changes: 21 additions & 13 deletions ios/AirshipEmbeddedViewWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,20 @@ public final class AirshipEmbeddedViewWrapper: UIView {

public override func didMoveToWindow() {
super.didMoveToWindow()
guard !self.isAdded else { return }
self.viewController.willMove(toParent: self.parentViewController())
self.parentViewController().addChild(self.viewController)
self.viewController.didMove(toParent: self.parentViewController())

if self.window == nil {
if self.isAdded {
self.viewController.willMove(toParent: nil)
self.viewController.removeFromParent()
self.isAdded = false
}
return
}

guard !self.isAdded, let parentVC = self.parentViewController() else { return }
self.viewController.willMove(toParent: parentVC)
parentVC.addChild(self.viewController)
self.viewController.didMove(toParent: parentVC)
self.viewController.view.isUserInteractionEnabled = true
isAdded = true
}
Expand All @@ -53,18 +63,16 @@ public final class AirshipEmbeddedViewWrapper: UIView {
}
}

extension UIView
{
//Get Parent View Controller from any view
func parentViewController() -> UIViewController {
extension UIView {
func parentViewController() -> UIViewController? {
var responder: UIResponder? = self
while !(responder is UIViewController) {
responder = responder?.next
if nil == responder {
break
while let r = responder {
if let vc = r as? UIViewController {
return vc
}
responder = r.next
}
return (responder as? UIViewController)!
return nil
}
}

Expand Down
2 changes: 1 addition & 1 deletion ios/AirshipReactNative.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class AirshipReactNative: NSObject {
AirshipProxy.shared
}

public static let version: String = "25.4.0"
public static let version: String = "25.4.2"

private let eventNotifier = EventNotifier()

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ua/react-native-airship",
"version": "25.4.1",
"version": "25.4.2",
"description": "Airship plugin for React Native apps.",
"source": "./src/index.tsx",
"main": "./lib/module/index.js",
Expand Down
Loading