From bd46e146e7110f4329e9b75b89e85165f133ba46 Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Fri, 19 Jul 2024 14:17:39 +0300 Subject: [PATCH] Fix navigation bug on iOS (#89) * fix navigation bug on iOS * prepare 10.1.5 release * refactor common code functionality for embedding swiftui view for each of the job screens into a new function and reuse it in those screens. --------- Co-authored-by: Tobi Omotayo --- CHANGELOG.md | 4 ++ example/ios/Podfile.lock | 4 +- ...FlutterPlatformView+EmbedSwiftUIView.swift | 46 +++++++++++++++++++ ios/Classes/SmileIDBiometricKYC.swift | 9 +--- ios/Classes/SmileIDDocumentVerification.swift | 9 +--- .../SmileIDEnhancedDocumentVerification.swift | 9 +--- .../SmileIDSmartSelfieAuthentication.swift | 9 +--- .../SmileIDSmartSelfieEnrollment.swift | 9 +--- pubspec.yaml | 2 +- 9 files changed, 58 insertions(+), 43 deletions(-) create mode 100644 ios/Classes/FlutterPlatformView+EmbedSwiftUIView.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index dfa7a25..fa95138 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Release Notes +## 10.1.5 + +* Fix navigation issue on iOS Flutter app + ## 10.1.4 * Bump iOS to 10.2.2 (https://github.com/smileidentity/ios/releases/tag/v10.2.2) which fixes retry crash) diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index be066cd..b0c3eaa 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -31,8 +31,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/smile_id/ios" SPEC CHECKSUMS: - Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 - integration_test: 13825b8a9334a850581300559b8839134b124670 + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4 lottie-ios: fcb5e73e17ba4c983140b7d21095c834b3087418 smile_id: 6d62c54b3fcf0e2fb685c33b28c868477244ac54 SmileID: 9d95463475f933422b2ce136474813b528dbedb7 diff --git a/ios/Classes/FlutterPlatformView+EmbedSwiftUIView.swift b/ios/Classes/FlutterPlatformView+EmbedSwiftUIView.swift new file mode 100644 index 0000000..f0498e0 --- /dev/null +++ b/ios/Classes/FlutterPlatformView+EmbedSwiftUIView.swift @@ -0,0 +1,46 @@ +import Flutter +import UIKit +import SwiftUI + +extension FlutterPlatformView { + /// Embeds a SwiftUI view into a UIKit view hierarchy for a view class that conforms to `FlutterPlatformView` + /// - Parameters: + /// - swiftUIView: The SwiftUI view to be integrated. This can be any view conforming + /// to the `View` protocol. + /// - parentView: The UIKit view that will contain the SwiftUI view. + /// - frame: The frame to be used for the hosted SwiftUI view. + /// - Returns: The `UIViewController` (specifically, a `UIHostingController`) that hosts + /// the SwiftUI view. This can be used for further configuration or management. + /// + /// - Note: This function attempts to find the appropriate parent view controller to add + /// the hosting controller as a child. It first checks for a `UINavigationController` + /// with a `FlutterViewController`, which is common in Flutter-based apps with SwiftUI + /// integration. If not found, it falls back to the root view controller. + /// + /// - Important: Ensure that you maintain a strong reference to the returned view controller + /// to prevent it from being deallocated. + func embedView( + _ swiftUIView: T, + in parentView: UIView, + frame: CGRect + ) -> UIViewController { + let hostingController = UIHostingController(rootView: swiftUIView) + + hostingController.view.frame = frame + hostingController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] + parentView.addSubview(hostingController.view) + + if let navigationController = UIApplication.shared.windows.first?.rootViewController as? UINavigationController, + let flutterViewController = navigationController.viewControllers.first as? FlutterViewController { + flutterViewController.addChild(hostingController) + parentView.addSubview(hostingController.view) + hostingController.view.setNeedsLayout() + hostingController.view.layoutIfNeeded() + } else { + let rootViewController = UIApplication.shared.windows.first?.rootViewController + rootViewController?.addChild(hostingController) + } + + return hostingController + } +} diff --git a/ios/Classes/SmileIDBiometricKYC.swift b/ios/Classes/SmileIDBiometricKYC.swift index 37464fa..720e0f3 100644 --- a/ios/Classes/SmileIDBiometricKYC.swift +++ b/ios/Classes/SmileIDBiometricKYC.swift @@ -45,14 +45,7 @@ class SmileIDBiometricKYC : NSObject, FlutterPlatformView, BiometricKycResultDel extraPartnerParams: args["extraPartnerParams"] as? [String: String] ?? [:], delegate: self ) - let childViewController = UIHostingController(rootView: screen) - - childViewController.view.frame = frame - childViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] - _view.addSubview(childViewController.view) - let rootViewController = UIApplication.shared.windows.first?.rootViewController - rootViewController?.addChild(childViewController) - _childViewController = childViewController + _childViewController = embedView(screen, in: _view, frame: frame) } func view() -> UIView { diff --git a/ios/Classes/SmileIDDocumentVerification.swift b/ios/Classes/SmileIDDocumentVerification.swift index e9f1947..3ccae82 100644 --- a/ios/Classes/SmileIDDocumentVerification.swift +++ b/ios/Classes/SmileIDDocumentVerification.swift @@ -42,14 +42,7 @@ class SmileIDDocumentVerification : NSObject, FlutterPlatformView, DocumentVerif extraPartnerParams: args["extraPartnerParams"] as? [String: String] ?? [:], delegate: self ) - let childViewController = UIHostingController(rootView: screen) - - childViewController.view.frame = frame - childViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] - _view.addSubview(childViewController.view) - let rootViewController = UIApplication.shared.windows.first?.rootViewController - rootViewController?.addChild(childViewController) - _childViewController = childViewController + _childViewController = embedView(screen, in: _view, frame: frame) } func view() -> UIView { diff --git a/ios/Classes/SmileIDEnhancedDocumentVerification.swift b/ios/Classes/SmileIDEnhancedDocumentVerification.swift index 51e8c47..8366c29 100644 --- a/ios/Classes/SmileIDEnhancedDocumentVerification.swift +++ b/ios/Classes/SmileIDEnhancedDocumentVerification.swift @@ -42,14 +42,7 @@ class SmileIDEnhancedDocumentVerification : NSObject, FlutterPlatformView, Enhan extraPartnerParams: args["extraPartnerParams"] as? [String: String] ?? [:], delegate: self ) - let childViewController = UIHostingController(rootView: screen) - - childViewController.view.frame = frame - childViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] - _view.addSubview(childViewController.view) - let rootViewController = UIApplication.shared.windows.first?.rootViewController - rootViewController?.addChild(childViewController) - _childViewController = childViewController + _childViewController = embedView(screen, in: _view, frame: frame) } func view() -> UIView { diff --git a/ios/Classes/SmileIDSmartSelfieAuthentication.swift b/ios/Classes/SmileIDSmartSelfieAuthentication.swift index 2bb697c..fa29879 100644 --- a/ios/Classes/SmileIDSmartSelfieAuthentication.swift +++ b/ios/Classes/SmileIDSmartSelfieAuthentication.swift @@ -34,14 +34,7 @@ class SmileIDSmartSelfieAuthentication : NSObject, FlutterPlatformView, SmartSel extraPartnerParams: args["extraPartnerParams"] as? [String: String] ?? [:], delegate: self ) - let childViewController = UIHostingController(rootView: screen) - - childViewController.view.frame = frame - childViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] - _view.addSubview(childViewController.view) - let rootViewController = UIApplication.shared.windows.first?.rootViewController - rootViewController?.addChild(childViewController) - _childViewController = childViewController + _childViewController = embedView(screen, in: _view, frame: frame) } func view() -> UIView { diff --git a/ios/Classes/SmileIDSmartSelfieEnrollment.swift b/ios/Classes/SmileIDSmartSelfieEnrollment.swift index 4f558a9..275f657 100644 --- a/ios/Classes/SmileIDSmartSelfieEnrollment.swift +++ b/ios/Classes/SmileIDSmartSelfieEnrollment.swift @@ -34,14 +34,7 @@ class SmileIDSmartSelfieEnrollment : NSObject, FlutterPlatformView, SmartSelfieR extraPartnerParams: args["extraPartnerParams"] as? [String: String] ?? [:], delegate: self ) - let childViewController = UIHostingController(rootView: screen) - - childViewController.view.frame = frame - childViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] - _view.addSubview(childViewController.view) - let rootViewController = UIApplication.shared.windows.first?.rootViewController - rootViewController?.addChild(childViewController) - _childViewController = childViewController + _childViewController = embedView(screen, in: _view, frame: frame) } func view() -> UIView { diff --git a/pubspec.yaml b/pubspec.yaml index 19c03be..398467a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: smile_id description: The Official Smile ID Flutter SDK -version: 10.1.4 +version: 10.1.5 homepage: "https://usesmileid.com" environment: