-
Notifications
You must be signed in to change notification settings - Fork 4
Dhruv/migrate to scene delegate #75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8b03d5e
0648e6d
076c6f5
bc1df86
0c8be55
00434bc
343e9a7
e86d3d0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -57,6 +57,15 @@ fun ScgatewayFlutterPlugin.txnOnSuccessCallback(transactionResult: TransactionRe | |
|
|
||
| result.success(transRes.toString()) | ||
|
|
||
| } | ||
| SmallcaseGatewaySdk.Result.IMR_SETUP -> { | ||
|
|
||
| val transRes = JSONObject(transactionResult.data!!) | ||
| transRes.put("success", true) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [CRITICAL]
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was not a threat as its already in try-catch block.So, no hard crash but still added result.error("TXN_ERROR", e.message ?: "Unknown error in transaction callback", null) logging for local insight |
||
| transRes.put("transaction", "IMR_SETUP") | ||
|
|
||
| result.success(transRes.toString()) | ||
|
|
||
| } | ||
| else -> { | ||
|
|
||
|
|
@@ -68,6 +77,7 @@ fun ScgatewayFlutterPlugin.txnOnSuccessCallback(transactionResult: TransactionRe | |
|
|
||
| } catch (e: Exception) { | ||
| e.printStackTrace() | ||
| result.error("TXN_ERROR", e.message ?: "Unknown error in transaction callback", null) | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,17 +8,57 @@ enum IntentType: String { | |
| case holding = "HOLDINGS_IMPORT" | ||
| case fetchFunds = "FETCH_FUNDS" | ||
| case sipSetup = "SIP_SETUP" | ||
| case imrSetup = "IMR_SETUP" | ||
| case authoriseHoldings = "AUTHORISE_HOLDINGS" | ||
| } | ||
|
|
||
| @MainActor | ||
| public class SwiftScgatewayFlutterPlugin: NSObject, FlutterPlugin, FlutterStreamHandler { | ||
|
|
||
| @MainActor | ||
| let currentViewController: UIViewController = (UIApplication.shared.delegate?.window??.rootViewController)! | ||
|
|
||
| private var eventSink: FlutterEventSink? | ||
| private var notificationObserver: NSObjectProtocol? | ||
|
|
||
| var currentViewController: UIViewController { | ||
| let foregroundScene = UIApplication.shared.connectedScenes | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [MEDIUM]
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both ScLoan & ScGateway are published separately. |
||
| .filter({ $0.activationState == .foregroundActive }) | ||
| .compactMap({ $0 as? UIWindowScene }) | ||
| .first | ||
|
|
||
| if let scene = foregroundScene { | ||
| let keyWindow: UIWindow? | ||
| if #available(iOS 15.0, *) { | ||
| keyWindow = scene.keyWindow | ||
| } else { | ||
| keyWindow = scene.windows.first(where: { $0.isKeyWindow }) | ||
| } | ||
| if let rootVC = keyWindow?.rootViewController { | ||
| return rootVC | ||
| } | ||
| } | ||
|
|
||
| // Any connected scene fallback (covers edge cases where no scene is .foregroundActive yet) | ||
| if let windowScene = UIApplication.shared.connectedScenes | ||
| .compactMap({ $0 as? UIWindowScene }) | ||
| .first { | ||
| let window: UIWindow? | ||
| if #available(iOS 15.0, *) { | ||
| window = windowScene.keyWindow ?? windowScene.windows.first | ||
| } else { | ||
| window = windowScene.windows.first(where: { $0.isKeyWindow }) ?? windowScene.windows.first | ||
| } | ||
| if let rootVC = window?.rootViewController { | ||
| return rootVC | ||
| } | ||
| } | ||
|
|
||
| // Fallback (AppDelegate-based window) | ||
| if let rootVC = UIApplication.shared.delegate?.window??.rootViewController { | ||
| return rootVC | ||
| } | ||
|
|
||
| fatalError("SwiftScgatewayFlutterPlugin: No root view controller found. Ensure a UIWindow is set up in SceneDelegate or AppDelegate.") | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [CRITICAL] Same
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Flutter's method channel dispatch (handle(_:result:)) cannot fire before the FlutterViewController is installed as the root VC — the Flutter engine itself requires a valid window to initialize. By the time any Flutter call arrives, all three fallback chains (foreground scene → any scene → AppDelegate window) already have a rootViewController. |
||
|
|
||
| public static func register(with registrar: FlutterPluginRegistrar) { | ||
| let channel = FlutterMethodChannel(name: "scgateway_flutter_plugin", binaryMessenger: registrar.messenger()) | ||
| let instance = SwiftScgatewayFlutterPlugin() | ||
|
|
@@ -342,6 +382,40 @@ public class SwiftScgatewayFlutterPlugin: NSObject, FlutterPlugin, FlutterStream | |
| /// Catch exception | ||
| } | ||
|
|
||
| // MARK: IMR_SETUP | ||
| case .imrSetup(let smallcaseAuthToken, let imrAction, let transactionId, let signup): | ||
|
|
||
| do { | ||
| let jsonEncoder = JSONEncoder() | ||
| let jsonData = try jsonEncoder.encode(imrAction) | ||
|
|
||
| let data = try? JSONSerialization.jsonObject(with: jsonData, options: []) | ||
|
|
||
| if let imrResponse = data as? [String: Any] { | ||
|
|
||
| print("IMR_SETUP response: \(imrResponse)") | ||
|
|
||
| var resDict: [String: Any] = [:] | ||
|
|
||
| resDict["success"] = true | ||
| resDict["data"] = imrResponse | ||
| resDict["smallcaseAuthToken"] = smallcaseAuthToken | ||
| resDict["transaction"] = "IMR_SETUP" | ||
| resDict["transactionId"] = transactionId | ||
| resDict["signup"] = signup | ||
|
|
||
| let jsonData = try JSONSerialization.data(withJSONObject: resDict, options: []) | ||
| let jsonString = String(data: jsonData, encoding: .utf8) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [MEDIUM]
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shifted to try from try! |
||
|
|
||
| result(jsonString) | ||
|
|
||
| return | ||
| } | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [MEDIUM] If
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. result(FlutterError(code: "IMR_SETUP_ERROR", message: error.localizedDescription, details: nil)) capturing for local insights now |
||
| } catch { | ||
| result(FlutterError(code: "IMR_SETUP_ERROR", message: error.localizedDescription, details: nil)) | ||
| } | ||
|
|
||
| default: | ||
| return | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| # Uncomment this line to define a global platform for your project | ||
| platform :ios, '14.0' | ||
| platform :ios, '15.0' | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [MEDIUM] Bumping to iOS 15 drops support for iOS 14 users. The
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SmartInvesting level issue |
||
| source 'https://cdn.cocoapods.org' | ||
| # private podspec for smallcase | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,14 +6,14 @@ PODS: | |
| - mixpanel_flutter (2.4.4): | ||
| - Flutter | ||
| - Mixpanel-swift (= 5.1.0) | ||
| - SCGateway (7.1.7) | ||
| - SCGateway-dhruv-migrate-to-sceneDelegate-007ae6e (7.1.6-24-debug) | ||
| - scgateway_flutter_plugin (0.0.1): | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [CRITICAL] These are debug branch builds (
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WIll be updated on release |
||
| - Flutter | ||
| - SCGateway (= 7.1.7) | ||
| - SCGateway-dhruv-migrate-to-sceneDelegate-007ae6e (= 7.1.6-24-debug) | ||
| - scloans (0.0.1): | ||
| - Flutter | ||
| - SCLoans (= 7.1.2) | ||
| - SCLoans (7.1.2) | ||
| - SCLoans-dhruv-migrate-to-sceneDelegate-80eca69 (= 7.1.1-39-debug) | ||
| - SCLoans-dhruv-migrate-to-sceneDelegate-80eca69 (7.1.1-39-debug) | ||
|
|
||
| DEPENDENCIES: | ||
| - Flutter (from `Flutter`) | ||
|
|
@@ -22,10 +22,11 @@ DEPENDENCIES: | |
| - scloans (from `.symlinks/plugins/scloans/ios`) | ||
|
|
||
| SPEC REPOS: | ||
| https://github.com/smallcase/cocoapodspec-internal.git: | ||
| - SCGateway-dhruv-migrate-to-sceneDelegate-007ae6e | ||
| - SCLoans-dhruv-migrate-to-sceneDelegate-80eca69 | ||
| trunk: | ||
| - Mixpanel-swift | ||
| - SCGateway | ||
| - SCLoans | ||
|
|
||
| EXTERNAL SOURCES: | ||
| Flutter: | ||
|
|
@@ -41,11 +42,11 @@ SPEC CHECKSUMS: | |
| Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 | ||
| Mixpanel-swift: 7b26468fc0e2e521104e51d65c4bbf7cab8162f8 | ||
| mixpanel_flutter: a0b6b937035899cd01951735ad5f87718b2ffee5 | ||
| SCGateway: a0f1bc86e449c7d440d8661e0936095b6f345179 | ||
| scgateway_flutter_plugin: 604e1c130e22438e5243d8b841c97f06edff01be | ||
| SCLoans: 4accc0a0a483f3943cc513a50800485201fed4dd | ||
| scloans: b53430d71d481c4770f13506722d2ab6d26a92ff | ||
| SCGateway-dhruv-migrate-to-sceneDelegate-007ae6e: b09149fc113aa409ad828253763c720520a2b642 | ||
| scgateway_flutter_plugin: 3ed28fc720e0fdf9ca79c638509a5310788ce48b | ||
| scloans: 3c4c1632b4a972373933c81cf91b70265b9a606b | ||
| SCLoans-dhruv-migrate-to-sceneDelegate-80eca69: ab2115d77604c531216613247d237a8b08e283a4 | ||
|
|
||
| PODFILE CHECKSUM: 32b0659ca3529b1ef2c9e5c229290749c8c79710 | ||
| PODFILE CHECKSUM: 06f3d79628f5881e8468842b1f97f7d12c291209 | ||
|
|
||
| COCOAPODS: 1.16.2 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,12 +2,15 @@ import Flutter | |
| import UIKit | ||
|
|
||
| @main | ||
| @objc class AppDelegate: FlutterAppDelegate { | ||
| @objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate { | ||
| override func application( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [MEDIUM]
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SmartInvesting level issue: conforming to |
||
| _ application: UIApplication, | ||
| didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? | ||
| ) -> Bool { | ||
| GeneratedPluginRegistrant.register(with: self) | ||
| return super.application(application, didFinishLaunchingWithOptions: launchOptions) | ||
| } | ||
|
|
||
| nonisolated func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { | ||
| GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry) | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[CRITICAL]
fatalErrorwill hard-crash the app if called during edge-case lifecycle moments — cold launch, background transitions, or multi-window on iPad. Change the return type toUIViewController?and let call sites handlenilgracefully instead of crashing unconditionally.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Flutter's method channel dispatch (handle(_:result:)) cannot fire before the FlutterViewController is installed as the root VC — the Flutter engine itself requires a valid window to initialize. By the time any Flutter call arrives, all three fallback chains (foreground scene → any scene → AppDelegate window) already have a rootViewController.