Skip to content

Commit b77e38d

Browse files
Merge pull request #75 from smallcase/dhruv/migrate-to-sceneDelegate
Dhruv/migrate to scene delegate
2 parents 4d18a88 + e86d3d0 commit b77e38d

11 files changed

Lines changed: 182 additions & 35 deletions

File tree

loans/ios/Classes/ScLoanFlutterPlugin.swift

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,47 @@ import Flutter
99
import UIKit
1010
import Loans
1111

12+
@MainActor
1213
public class SwiftScLoanFlutterPlugin: NSObject, FlutterPlugin {
13-
14-
@MainActor
15-
let currentViewController: UIViewController = (UIApplication.shared.delegate?.window??.rootViewController)!
14+
15+
var currentViewController: UIViewController {
16+
let foregroundScene = UIApplication.shared.connectedScenes
17+
.filter({ $0.activationState == .foregroundActive })
18+
.compactMap({ $0 as? UIWindowScene })
19+
.first
20+
21+
if let scene = foregroundScene {
22+
let keyWindow: UIWindow?
23+
if #available(iOS 15.0, *) {
24+
keyWindow = scene.keyWindow
25+
} else {
26+
keyWindow = scene.windows.first(where: { $0.isKeyWindow })
27+
}
28+
if let rootVC = keyWindow?.rootViewController {
29+
return rootVC
30+
}
31+
}
32+
33+
if let windowScene = UIApplication.shared.connectedScenes
34+
.compactMap({ $0 as? UIWindowScene })
35+
.first {
36+
let window: UIWindow?
37+
if #available(iOS 15.0, *) {
38+
window = windowScene.keyWindow ?? windowScene.windows.first
39+
} else {
40+
window = windowScene.windows.first(where: { $0.isKeyWindow }) ?? windowScene.windows.first
41+
}
42+
if let rootVC = window?.rootViewController {
43+
return rootVC
44+
}
45+
}
46+
47+
if let rootVC = UIApplication.shared.delegate?.window??.rootViewController {
48+
return rootVC
49+
}
50+
51+
fatalError("SwiftScLoanFlutterPlugin: No root view controller found. Ensure a UIWindow is set up in SceneDelegate or AppDelegate.")
52+
}
1653

1754
public static func register(with registrar: FlutterPluginRegistrar) {
1855
let channel = FlutterMethodChannel(name: "scloans", binaryMessenger: registrar.messenger())

scgateway/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,5 @@ android {
6464

6565
dependencies {
6666
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
67-
implementation 'com.smallcase.gateway:sdk:6.0.8'
67+
implementation 'com.smallcase.gateway:sdk:6.1.0'
6868
}

scgateway/android/src/main/kotlin/com/example/scgateway_flutter_plugin/ScgatewayFlutterPluginTxnExt.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ fun ScgatewayFlutterPlugin.txnOnSuccessCallback(transactionResult: TransactionRe
5757

5858
result.success(transRes.toString())
5959

60+
}
61+
SmallcaseGatewaySdk.Result.IMR_SETUP -> {
62+
63+
val transRes = JSONObject(transactionResult.data!!)
64+
transRes.put("success", true)
65+
transRes.put("transaction", "IMR_SETUP")
66+
67+
result.success(transRes.toString())
68+
6069
}
6170
else -> {
6271

@@ -68,6 +77,7 @@ fun ScgatewayFlutterPlugin.txnOnSuccessCallback(transactionResult: TransactionRe
6877

6978
} catch (e: Exception) {
7079
e.printStackTrace()
80+
result.error("TXN_ERROR", e.message ?: "Unknown error in transaction callback", null)
7181
}
7282
}
7383

scgateway/ios/Classes/SwiftScgatewayFlutterPlugin.swift

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,57 @@ enum IntentType: String {
88
case holding = "HOLDINGS_IMPORT"
99
case fetchFunds = "FETCH_FUNDS"
1010
case sipSetup = "SIP_SETUP"
11+
case imrSetup = "IMR_SETUP"
1112
case authoriseHoldings = "AUTHORISE_HOLDINGS"
1213
}
1314

15+
@MainActor
1416
public class SwiftScgatewayFlutterPlugin: NSObject, FlutterPlugin, FlutterStreamHandler {
1517

16-
@MainActor
17-
let currentViewController: UIViewController = (UIApplication.shared.delegate?.window??.rootViewController)!
18-
1918
private var eventSink: FlutterEventSink?
2019
private var notificationObserver: NSObjectProtocol?
2120

21+
var currentViewController: UIViewController {
22+
let foregroundScene = UIApplication.shared.connectedScenes
23+
.filter({ $0.activationState == .foregroundActive })
24+
.compactMap({ $0 as? UIWindowScene })
25+
.first
26+
27+
if let scene = foregroundScene {
28+
let keyWindow: UIWindow?
29+
if #available(iOS 15.0, *) {
30+
keyWindow = scene.keyWindow
31+
} else {
32+
keyWindow = scene.windows.first(where: { $0.isKeyWindow })
33+
}
34+
if let rootVC = keyWindow?.rootViewController {
35+
return rootVC
36+
}
37+
}
38+
39+
// Any connected scene fallback (covers edge cases where no scene is .foregroundActive yet)
40+
if let windowScene = UIApplication.shared.connectedScenes
41+
.compactMap({ $0 as? UIWindowScene })
42+
.first {
43+
let window: UIWindow?
44+
if #available(iOS 15.0, *) {
45+
window = windowScene.keyWindow ?? windowScene.windows.first
46+
} else {
47+
window = windowScene.windows.first(where: { $0.isKeyWindow }) ?? windowScene.windows.first
48+
}
49+
if let rootVC = window?.rootViewController {
50+
return rootVC
51+
}
52+
}
53+
54+
// Fallback (AppDelegate-based window)
55+
if let rootVC = UIApplication.shared.delegate?.window??.rootViewController {
56+
return rootVC
57+
}
58+
59+
fatalError("SwiftScgatewayFlutterPlugin: No root view controller found. Ensure a UIWindow is set up in SceneDelegate or AppDelegate.")
60+
}
61+
2262
public static func register(with registrar: FlutterPluginRegistrar) {
2363
let channel = FlutterMethodChannel(name: "scgateway_flutter_plugin", binaryMessenger: registrar.messenger())
2464
let instance = SwiftScgatewayFlutterPlugin()
@@ -342,6 +382,40 @@ public class SwiftScgatewayFlutterPlugin: NSObject, FlutterPlugin, FlutterStream
342382
/// Catch exception
343383
}
344384

385+
// MARK: IMR_SETUP
386+
case .imrSetup(let smallcaseAuthToken, let imrAction, let transactionId, let signup):
387+
388+
do {
389+
let jsonEncoder = JSONEncoder()
390+
let jsonData = try jsonEncoder.encode(imrAction)
391+
392+
let data = try? JSONSerialization.jsonObject(with: jsonData, options: [])
393+
394+
if let imrResponse = data as? [String: Any] {
395+
396+
print("IMR_SETUP response: \(imrResponse)")
397+
398+
var resDict: [String: Any] = [:]
399+
400+
resDict["success"] = true
401+
resDict["data"] = imrResponse
402+
resDict["smallcaseAuthToken"] = smallcaseAuthToken
403+
resDict["transaction"] = "IMR_SETUP"
404+
resDict["transactionId"] = transactionId
405+
resDict["signup"] = signup
406+
407+
let jsonData = try JSONSerialization.data(withJSONObject: resDict, options: [])
408+
let jsonString = String(data: jsonData, encoding: .utf8)
409+
410+
result(jsonString)
411+
412+
return
413+
}
414+
415+
} catch {
416+
result(FlutterError(code: "IMR_SETUP_ERROR", message: error.localizedDescription, details: nil))
417+
}
418+
345419
default:
346420
return
347421
}

scgateway/ios/scgateway_flutter_plugin.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Scgateway Flutter plugin.
1515
s.source = { :path => '.' }
1616
s.source_files = 'Classes/**/*'
1717
s.dependency 'Flutter'
18-
s.dependency 'SCGateway', '7.1.7'
18+
s.dependency 'SCGateway', '7.2.0'
1919
s.xcconfig = {'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES'}
2020
s.vendored_frameworks = 'SCGateway.xcframework'
2121
s.platform = :ios, '13.0'

scgateway/lib/scgateway_flutter_plugin.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class ScgatewayIntent {
1313
static const AUTHORISE_HOLDINGS = "AUTHORISE_HOLDINGS";
1414
static const FETCH_FUNDS = "FETCH_FUNDS";
1515
static const SIP_SETUP = "SIP_SETUP";
16+
static const IMR_SETUP = "IMR_SETUP";
1617
static const CANCEL_AMO = "CANCEL_AMO";
1718
static const MF_HOLDINGS_IMPORT = "MF_HOLDINGS_IMPORT";
1819
}

smart_investing/ios/Podfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Uncomment this line to define a global platform for your project
2-
platform :ios, '14.0'
2+
platform :ios, '15.0'
33

44
source 'https://cdn.cocoapods.org'
55
# private podspec for smallcase

smart_investing/ios/Podfile.lock

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ PODS:
66
- mixpanel_flutter (2.4.4):
77
- Flutter
88
- Mixpanel-swift (= 5.1.0)
9-
- SCGateway (7.1.7)
9+
- SCGateway-dhruv-migrate-to-sceneDelegate-007ae6e (7.1.6-24-debug)
1010
- scgateway_flutter_plugin (0.0.1):
1111
- Flutter
12-
- SCGateway (= 7.1.7)
12+
- SCGateway-dhruv-migrate-to-sceneDelegate-007ae6e (= 7.1.6-24-debug)
1313
- scloans (0.0.1):
1414
- Flutter
15-
- SCLoans (= 7.1.2)
16-
- SCLoans (7.1.2)
15+
- SCLoans-dhruv-migrate-to-sceneDelegate-80eca69 (= 7.1.1-39-debug)
16+
- SCLoans-dhruv-migrate-to-sceneDelegate-80eca69 (7.1.1-39-debug)
1717

1818
DEPENDENCIES:
1919
- Flutter (from `Flutter`)
@@ -22,10 +22,11 @@ DEPENDENCIES:
2222
- scloans (from `.symlinks/plugins/scloans/ios`)
2323

2424
SPEC REPOS:
25+
https://github.com/smallcase/cocoapodspec-internal.git:
26+
- SCGateway-dhruv-migrate-to-sceneDelegate-007ae6e
27+
- SCLoans-dhruv-migrate-to-sceneDelegate-80eca69
2528
trunk:
2629
- Mixpanel-swift
27-
- SCGateway
28-
- SCLoans
2930

3031
EXTERNAL SOURCES:
3132
Flutter:
@@ -41,11 +42,11 @@ SPEC CHECKSUMS:
4142
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
4243
Mixpanel-swift: 7b26468fc0e2e521104e51d65c4bbf7cab8162f8
4344
mixpanel_flutter: a0b6b937035899cd01951735ad5f87718b2ffee5
44-
SCGateway: a0f1bc86e449c7d440d8661e0936095b6f345179
45-
scgateway_flutter_plugin: 604e1c130e22438e5243d8b841c97f06edff01be
46-
SCLoans: 4accc0a0a483f3943cc513a50800485201fed4dd
47-
scloans: b53430d71d481c4770f13506722d2ab6d26a92ff
45+
SCGateway-dhruv-migrate-to-sceneDelegate-007ae6e: b09149fc113aa409ad828253763c720520a2b642
46+
scgateway_flutter_plugin: 3ed28fc720e0fdf9ca79c638509a5310788ce48b
47+
scloans: 3c4c1632b4a972373933c81cf91b70265b9a606b
48+
SCLoans-dhruv-migrate-to-sceneDelegate-80eca69: ab2115d77604c531216613247d237a8b08e283a4
4849

49-
PODFILE CHECKSUM: 32b0659ca3529b1ef2c9e5c229290749c8c79710
50+
PODFILE CHECKSUM: 06f3d79628f5881e8468842b1f97f7d12c291209
5051

5152
COCOAPODS: 1.16.2

smart_investing/ios/Runner/AppDelegate.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ import Flutter
22
import UIKit
33

44
@main
5-
@objc class AppDelegate: FlutterAppDelegate {
5+
@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
66
override func application(
77
_ application: UIApplication,
88
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
99
) -> Bool {
10-
GeneratedPluginRegistrant.register(with: self)
1110
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
1211
}
12+
13+
nonisolated func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
14+
GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
15+
}
1316
}

smart_investing/ios/Runner/Info.plist

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,26 @@
8383
<true/>
8484
<key>UIApplicationSupportsIndirectInputEvents</key>
8585
<true/>
86+
<key>UIApplicationSceneManifest</key>
87+
<dict>
88+
<key>UIApplicationSupportsMultipleScenes</key>
89+
<false/>
90+
<key>UISceneConfigurations</key>
91+
<dict>
92+
<key>UIWindowSceneSessionRoleApplication</key>
93+
<array>
94+
<dict>
95+
<key>UISceneClassName</key>
96+
<string>UIWindowScene</string>
97+
<key>UISceneConfigurationName</key>
98+
<string>flutter</string>
99+
<key>UISceneDelegateClassName</key>
100+
<string>FlutterSceneDelegate</string>
101+
<key>UISceneStoryboardFile</key>
102+
<string>Main</string>
103+
</dict>
104+
</array>
105+
</dict>
106+
</dict>
86107
</dict>
87108
</plist>

0 commit comments

Comments
 (0)