@aigens/aigens-sdk-core 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/aigens/sdk/WebContainerActivity.java +182 -14
- package/android/src/main/java/com/aigens/sdk/plugins/CorePlugin.java +88 -0
- package/android/src/main/res/layout/sdk_layout_main.xml +1 -0
- package/ios/Plugin/CorePlugin.m +1 -0
- package/ios/Plugin/CorePlugin.swift +60 -1
- package/ios/Plugin/SecondWebContainerView.swift +157 -0
- package/ios/Plugin/WebContainerViewController.swift +17 -0
- package/package.json +1 -1
@@ -9,17 +9,24 @@ import android.graphics.Color;
|
|
9
9
|
import android.net.Uri;
|
10
10
|
import android.os.Build;
|
11
11
|
import android.os.Bundle;
|
12
|
+
import android.os.Handler;
|
13
|
+
import android.os.Looper;
|
12
14
|
import android.text.TextUtils;
|
13
15
|
import android.util.Log;
|
14
16
|
import android.view.View;
|
17
|
+
import android.view.ViewGroup;
|
18
|
+
import android.webkit.JavascriptInterface;
|
15
19
|
import android.webkit.ServiceWorkerClient;
|
16
20
|
import android.webkit.ServiceWorkerController;
|
17
21
|
import android.webkit.ValueCallback;
|
22
|
+
import android.webkit.WebResourceError;
|
18
23
|
import android.webkit.WebResourceRequest;
|
19
24
|
import android.webkit.WebResourceResponse;
|
20
25
|
import android.webkit.WebSettings;
|
21
26
|
import android.webkit.WebView;
|
27
|
+
import android.webkit.WebViewClient;
|
22
28
|
import android.widget.Button;
|
29
|
+
import android.widget.FrameLayout;
|
23
30
|
|
24
31
|
import com.aigens.sdk.plugins.CorePlugin;
|
25
32
|
import com.getcapacitor.Bridge;
|
@@ -286,18 +293,21 @@ public class WebContainerActivity extends BridgeActivity {
|
|
286
293
|
|
287
294
|
List<Class<? extends Plugin>> auto = loadPlugins();
|
288
295
|
|
289
|
-
|
296
|
+
if (auto != null) {
|
297
|
+
for (Class c : auto) {
|
290
298
|
|
291
|
-
|
299
|
+
String clsName = c.getName();
|
292
300
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
301
|
+
if (clsName.endsWith("SplashScreenPlugin")) {
|
302
|
+
//don't add the splash screen plugin so it doesn't show the splash screen again
|
303
|
+
} else {
|
304
|
+
allPlugins.add(c);
|
305
|
+
}
|
298
306
|
|
307
|
+
}
|
299
308
|
}
|
300
309
|
|
310
|
+
|
301
311
|
// com.getcapacitor.community.firebaseanalytics.FirebaseAnalytics
|
302
312
|
addExtraPlugins(new String[]{
|
303
313
|
"com.aigens.googlepay.GooglePayPlugin",
|
@@ -307,6 +317,10 @@ public class WebContainerActivity extends BridgeActivity {
|
|
307
317
|
"com.aigens.alipay.AliPayPlugin",
|
308
318
|
"com.aigens.alipayhk.AliPayhkPlugin",
|
309
319
|
"com.aigens.payme.PaymePlugin",
|
320
|
+
"com.aigens.sdk.alipay.AlipayPlugin",
|
321
|
+
"com.aigens.sdk.wechat.WechatPlugin",
|
322
|
+
"com.aigens.sdk.utils.AigensUtilsPlugin",
|
323
|
+
"com.aigens.sdk.preferences.AigensPreferencesPlugin"
|
310
324
|
}, allPlugins);
|
311
325
|
addExtraPlugins(intent.getStringArrayExtra("extraClasspaths"), allPlugins);
|
312
326
|
|
@@ -318,6 +332,8 @@ public class WebContainerActivity extends BridgeActivity {
|
|
318
332
|
this.config = cc;
|
319
333
|
this.bridgeBuilder.setInstanceState(currentInstanceState);
|
320
334
|
this.load();
|
335
|
+
this.bridgeBuilder.setPlugins(allPlugins);
|
336
|
+
|
321
337
|
|
322
338
|
//still have time to override webview client to avoid any intercept
|
323
339
|
|
@@ -358,23 +374,49 @@ public class WebContainerActivity extends BridgeActivity {
|
|
358
374
|
// sometime not callback , use Use manual injection js
|
359
375
|
// disableServiceWorker(this.url, this.bridge);
|
360
376
|
|
377
|
+
|
378
|
+
// test
|
379
|
+
// new Handler(getMainLooper()).postDelayed(new Runnable() {
|
380
|
+
// @Override
|
381
|
+
// public void run() {
|
382
|
+
// openSecondBrowser("https://cloud-api.loginradius.com/sso/oidc/v2/loyaltypos/authorize?client_id=1196e953-6981-4dcb-ab65-99102facbc2d&redirect_uri=https%3a%2f%2fuatyuuapi.pizzahut.com.hk%2fapi%2fV3%2fYuu%2fLogin%2fCallBack%2f4b0717d0-9203-402c-8a09-202503111111&scope=openid&response_mode=query&response_type=code&ui_locales=ecomm_zh-hant", null, new SecondBrowserInterface() {
|
383
|
+
// @Override
|
384
|
+
// public void secondBrowserInterfaceYuuLoginCallback(View targetView, String status, String yuuToken, String cardNo, String warning, boolean cancel) {
|
385
|
+
// Log.i("Jason open", status+yuuToken+cardNo+warning+cancel);
|
386
|
+
// ViewGroup parent = (ViewGroup) targetView.getParent();
|
387
|
+
// if (parent != null) {
|
388
|
+
// parent.removeView(targetView);
|
389
|
+
// }
|
390
|
+
// }
|
391
|
+
|
392
|
+
// @Override
|
393
|
+
// public void customHandler(View targetView, String params1, String params2) {
|
394
|
+
|
395
|
+
// }
|
396
|
+
// });
|
397
|
+
// }
|
398
|
+
// }, 20000);
|
399
|
+
|
361
400
|
}
|
362
401
|
|
363
402
|
@Override
|
364
403
|
protected void load() {
|
365
404
|
List<Class<? extends Plugin>> allPlugins = new ArrayList<>();
|
366
405
|
List<Class<? extends Plugin>> auto = loadPlugins();
|
367
|
-
|
406
|
+
if (auto != null) {
|
407
|
+
for (Class c : auto) {
|
368
408
|
|
369
|
-
|
409
|
+
String clsName = c.getName();
|
370
410
|
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
411
|
+
if (clsName.endsWith("SplashScreenPlugin")) {
|
412
|
+
//don't add the splash screen plugin so it doesn't show the splash screen again
|
413
|
+
} else {
|
414
|
+
allPlugins.add(c);
|
415
|
+
}
|
376
416
|
|
417
|
+
}
|
377
418
|
}
|
419
|
+
|
378
420
|
this.bridgeBuilder.setPlugins(allPlugins);
|
379
421
|
super.load();
|
380
422
|
}
|
@@ -641,9 +683,12 @@ public class WebContainerActivity extends BridgeActivity {
|
|
641
683
|
return null;
|
642
684
|
}
|
643
685
|
|
686
|
+
private boolean shouldHandleBackPress = true;
|
644
687
|
@Override
|
645
688
|
public void onBackPressed() {
|
646
689
|
|
690
|
+
if (!shouldHandleBackPress) return;
|
691
|
+
|
647
692
|
super.onBackPressed();
|
648
693
|
|
649
694
|
boolean canBack = this.bridge.getWebView().canGoBack();
|
@@ -844,5 +889,128 @@ public class WebContainerActivity extends BridgeActivity {
|
|
844
889
|
}*/
|
845
890
|
}
|
846
891
|
|
892
|
+
private static final int SECOND_WEBVIEW_ID = 1000001;
|
893
|
+
private String currentUrl = "";
|
894
|
+
public void openSecondBrowser(String url, String serviceName, SecondBrowserInterface callback) {
|
895
|
+
|
896
|
+
try {
|
897
|
+
Handler mainHandler = new Handler(getMainLooper());
|
898
|
+
mainHandler.post(() -> {
|
899
|
+
FrameLayout layout = findViewById(R.id.aigens_sdk_layout_main);
|
900
|
+
|
901
|
+
WebView existingWebView = layout.findViewById(SECOND_WEBVIEW_ID);
|
902
|
+
if (existingWebView != null) {
|
903
|
+
layout.removeView(existingWebView);
|
904
|
+
}
|
905
|
+
|
906
|
+
|
907
|
+
WebView webView = new WebView(this);
|
908
|
+
webView.setId(SECOND_WEBVIEW_ID);
|
909
|
+
|
910
|
+
// webView.setVisibility(showError ? View.VISIBLE : View.INVISIBLE);
|
911
|
+
// webView.setVisibility(View.VISIBLE);
|
912
|
+
|
913
|
+
WebSettings webSettings = webView.getSettings();
|
914
|
+
webSettings.setJavaScriptEnabled(true);
|
915
|
+
webSettings.setDomStorageEnabled(true);
|
916
|
+
|
917
|
+
|
918
|
+
layout.addView(webView, new FrameLayout.LayoutParams(
|
919
|
+
FrameLayout.LayoutParams.MATCH_PARENT,
|
920
|
+
FrameLayout.LayoutParams.MATCH_PARENT
|
921
|
+
));
|
922
|
+
|
923
|
+
webView.setWebViewClient(new WebViewClient() {
|
924
|
+
@Override
|
925
|
+
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
|
926
|
+
|
927
|
+
Uri url = request.getUrl();
|
928
|
+
// Log.i("jason shouldOverrideUrl", url.toString());
|
929
|
+
|
930
|
+
//return super.shouldOverrideUrlLoading(view, request);
|
931
|
+
currentUrl = url.toString();
|
932
|
+
new Handler(getMainLooper()).postDelayed(new Runnable() {
|
933
|
+
@Override
|
934
|
+
public void run() {
|
935
|
+
if ("about:blank".equals(currentUrl)) {
|
936
|
+
shouldHandleBackPress = true;
|
937
|
+
callback.secondBrowserInterfaceYuuLoginCallback(webView, "", "", "", "", true);;
|
938
|
+
}
|
939
|
+
}
|
940
|
+
}, 1000); // 1s
|
941
|
+
return false;
|
942
|
+
}
|
943
|
+
|
944
|
+
@Override
|
945
|
+
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
946
|
+
|
947
|
+
super.onPageStarted(view, url, favicon);
|
948
|
+
// Log.i("jason onPageStarted", url);
|
949
|
+
|
950
|
+
|
951
|
+
}
|
952
|
+
|
953
|
+
@Override
|
954
|
+
public void onPageFinished(WebView view, String url) {
|
955
|
+
// Log.i("Jason onPageFinished", url);
|
956
|
+
super.onPageFinished(view, url);
|
957
|
+
|
958
|
+
}
|
959
|
+
|
960
|
+
@Override
|
961
|
+
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
|
962
|
+
super.onReceivedError(view, request, error);
|
963
|
+
// Log.i("Jason onReceivedError", error.toString());
|
964
|
+
shouldHandleBackPress = true;
|
965
|
+
ViewGroup parent = (ViewGroup) view.getParent();
|
966
|
+
if (parent != null) {
|
967
|
+
parent.removeView(view);
|
968
|
+
}
|
969
|
+
}
|
970
|
+
});
|
971
|
+
|
972
|
+
webView.addJavascriptInterface(new SecondWebAppInterface(webView, callback), "android");
|
973
|
+
if (serviceName != null) {
|
974
|
+
webView.addJavascriptInterface(new SecondWebAppInterface(webView, callback), serviceName);
|
975
|
+
}
|
976
|
+
|
977
|
+
shouldHandleBackPress = false;
|
978
|
+
webView.loadUrl(url);
|
979
|
+
});
|
980
|
+
}catch (Exception e) {
|
981
|
+
e.printStackTrace();
|
982
|
+
}
|
983
|
+
|
984
|
+
|
985
|
+
|
986
|
+
}
|
987
|
+
|
988
|
+
public class SecondWebAppInterface {
|
989
|
+
private SecondBrowserInterface callback;
|
990
|
+
private View targetView;
|
991
|
+
public SecondWebAppInterface(View targetView, SecondBrowserInterface callback) {
|
992
|
+
this.callback = callback;
|
993
|
+
this.targetView = targetView;
|
994
|
+
}
|
995
|
+
|
996
|
+
@JavascriptInterface
|
997
|
+
public void yuuLoginHandler(String status, String yuuToken, String cardNo, String warning) {
|
998
|
+
shouldHandleBackPress = true;
|
999
|
+
callback.secondBrowserInterfaceYuuLoginCallback(targetView, status, yuuToken, cardNo, warning, false);
|
1000
|
+
}
|
1001
|
+
|
1002
|
+
@JavascriptInterface
|
1003
|
+
public void customHandler(String params1, String params2) {
|
1004
|
+
shouldHandleBackPress = true;
|
1005
|
+
callback.customHandler(targetView, params1, params2);
|
1006
|
+
}
|
1007
|
+
|
1008
|
+
}
|
1009
|
+
|
1010
|
+
public interface SecondBrowserInterface {
|
1011
|
+
void secondBrowserInterfaceYuuLoginCallback(View targetView, String status, String yuuToken, String cardNo, String warning, boolean cancel);
|
1012
|
+
void customHandler(View targetView, String params1, String params2);
|
1013
|
+
|
1014
|
+
}
|
847
1015
|
|
848
1016
|
}
|
@@ -2,15 +2,20 @@ package com.aigens.sdk.plugins;
|
|
2
2
|
|
3
3
|
import android.Manifest;
|
4
4
|
import android.app.Activity;
|
5
|
+
import android.app.ActivityManager;
|
5
6
|
import android.content.ClipData;
|
6
7
|
import android.content.ClipDescription;
|
7
8
|
import android.content.ClipboardManager;
|
9
|
+
import android.content.ComponentName;
|
8
10
|
import android.content.Context;
|
9
11
|
import android.content.Intent;
|
10
12
|
import android.content.pm.PackageInfo;
|
11
13
|
import android.content.pm.PackageManager;
|
12
14
|
import android.net.Uri;
|
15
|
+
import android.os.Build;
|
13
16
|
import android.os.Handler;
|
17
|
+
import android.view.View;
|
18
|
+
import android.view.ViewGroup;
|
14
19
|
import android.webkit.WebSettings;
|
15
20
|
import android.webkit.WebView;
|
16
21
|
|
@@ -538,4 +543,87 @@ public class CorePlugin extends Plugin {
|
|
538
543
|
call.resolve(ret);
|
539
544
|
}
|
540
545
|
|
546
|
+
@PluginMethod
|
547
|
+
public void openSecondBrowser(PluginCall call) {
|
548
|
+
String url = call.getString("url", null);
|
549
|
+
String serviceName = call.getString("serviceName", null);
|
550
|
+
if (url == null) {
|
551
|
+
call.reject("url is missing");
|
552
|
+
return;
|
553
|
+
}
|
554
|
+
|
555
|
+
ActivityManager activityManager = (ActivityManager) getActivity().getSystemService(Context.ACTIVITY_SERVICE);
|
556
|
+
if (activityManager == null) {
|
557
|
+
call.reject("activityManager is missing");
|
558
|
+
return;
|
559
|
+
}
|
560
|
+
Activity currentActivity = null;
|
561
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
562
|
+
List<ActivityManager.AppTask> tasks = activityManager.getAppTasks();
|
563
|
+
if (tasks != null && !tasks.isEmpty()) {
|
564
|
+
ActivityManager.RecentTaskInfo taskInfo = tasks.get(0).getTaskInfo();
|
565
|
+
if (taskInfo.topActivity.getClassName().equals(WebContainerActivity.class.getName())) {
|
566
|
+
try {
|
567
|
+
Class<?> activityClass = Class.forName(taskInfo.topActivity.getClassName());
|
568
|
+
currentActivity = (Activity) activityClass.newInstance();
|
569
|
+
} catch (Exception e) {
|
570
|
+
e.printStackTrace();
|
571
|
+
}
|
572
|
+
|
573
|
+
}
|
574
|
+
}
|
575
|
+
} else {
|
576
|
+
List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1);
|
577
|
+
if (tasks != null && !tasks.isEmpty()) {
|
578
|
+
ActivityManager.RunningTaskInfo taskInfo = tasks.get(0);
|
579
|
+
if (taskInfo.topActivity.getClassName().equals(WebContainerActivity.class.getName())) {
|
580
|
+
try {
|
581
|
+
Class<?> activityClass = Class.forName(taskInfo.topActivity.getClassName());
|
582
|
+
currentActivity = (Activity) activityClass.newInstance();
|
583
|
+
} catch (Exception e) {
|
584
|
+
e.printStackTrace();
|
585
|
+
}
|
586
|
+
|
587
|
+
|
588
|
+
}
|
589
|
+
}
|
590
|
+
}
|
591
|
+
|
592
|
+
if (currentActivity == null) {
|
593
|
+
call.reject("currentActivity is missing");
|
594
|
+
return;
|
595
|
+
}
|
596
|
+
|
597
|
+
if (currentActivity instanceof WebContainerActivity) {
|
598
|
+
((WebContainerActivity) currentActivity).openSecondBrowser(url, null, new WebContainerActivity.SecondBrowserInterface() {
|
599
|
+
@Override
|
600
|
+
public void secondBrowserInterfaceYuuLoginCallback(View targetView, String status, String yuuToken, String cardNo, String warning, boolean cancel) {
|
601
|
+
JSObject ret = new JSObject();
|
602
|
+
ret.put("cancel", cancel);
|
603
|
+
ret.put("yuuToken", yuuToken);
|
604
|
+
ret.put("cardNo", cardNo);
|
605
|
+
ret.put("warning", warning);
|
606
|
+
call.resolve(ret);
|
607
|
+
ViewGroup parent = (ViewGroup) targetView.getParent();
|
608
|
+
if (parent != null) {
|
609
|
+
parent.removeView(targetView);
|
610
|
+
}
|
611
|
+
}
|
612
|
+
|
613
|
+
@Override
|
614
|
+
public void customHandler(View targetView, String params1, String params2) {
|
615
|
+
JSObject ret = new JSObject();
|
616
|
+
ret.put("params1", params1);
|
617
|
+
ret.put("params2", params2);
|
618
|
+
call.resolve(ret);
|
619
|
+
ViewGroup parent = (ViewGroup) targetView.getParent();
|
620
|
+
if (parent != null) {
|
621
|
+
parent.removeView(targetView);
|
622
|
+
}
|
623
|
+
}
|
624
|
+
});
|
625
|
+
}
|
626
|
+
|
627
|
+
}
|
628
|
+
|
541
629
|
}
|
package/ios/Plugin/CorePlugin.m
CHANGED
@@ -8,6 +8,7 @@ CAP_PLUGIN(CorePlugin, "Core",
|
|
8
8
|
CAP_PLUGIN_METHOD(dismiss, CAPPluginReturnPromise);
|
9
9
|
CAP_PLUGIN_METHOD(finish, CAPPluginReturnPromise);
|
10
10
|
CAP_PLUGIN_METHOD(openBrowser, CAPPluginReturnPromise);
|
11
|
+
CAP_PLUGIN_METHOD(openSecondBrowser, CAPPluginReturnPromise);
|
11
12
|
CAP_PLUGIN_METHOD(getDeeplink, CAPPluginReturnPromise);
|
12
13
|
CAP_PLUGIN_METHOD(getMember, CAPPluginReturnPromise);
|
13
14
|
CAP_PLUGIN_METHOD(isInstalledApp, CAPPluginReturnPromise);
|
@@ -27,11 +27,20 @@ public class CorePlugin: CAPPlugin {
|
|
27
27
|
public static var member: Dictionary<String, Any>?
|
28
28
|
public static var deeplink: Dictionary<String, Any>?
|
29
29
|
|
30
|
-
|
30
|
+
static var StaticBridge: CAPBridgeProtocol?
|
31
31
|
public override func load() {
|
32
32
|
handleOpenUrl()
|
33
|
+
CorePlugin.StaticBridge = self.bridge;
|
34
|
+
}
|
35
|
+
|
36
|
+
public static func getCoreInstance() -> CorePlugin? {
|
37
|
+
if let instance = StaticBridge?.plugin(withName: "Core") as? CorePlugin {
|
38
|
+
return instance
|
39
|
+
}
|
40
|
+
return nil
|
33
41
|
}
|
34
42
|
|
43
|
+
|
35
44
|
private func handleOpenUrl() {
|
36
45
|
NotificationCenter.default.addObserver(self, selector: #selector(self.handleUniversalLink(notification:)), name: Notification.Name.capacitorOpenUniversalLink, object: nil)
|
37
46
|
|
@@ -100,13 +109,18 @@ public class CorePlugin: CAPPlugin {
|
|
100
109
|
let typeIdentifier = call.getString("typeIdentifier", "hk.com.hkicl");
|
101
110
|
|
102
111
|
let paymentData: [String: Any] = ["URL": paymentRequestUrl, "callback": callbackUrl]
|
112
|
+
// let jsonData = try! JSONSerialization.data(withJSONObject: paymentData, options: [])
|
113
|
+
// let itemProvider = NSItemProvider(item: jsonData as NSSecureCoding, typeIdentifier: typeIdentifier)
|
103
114
|
let itemProvider = NSItemProvider(item: paymentData as NSSecureCoding, typeIdentifier: typeIdentifier)
|
104
115
|
let extensionItem = NSExtensionItem()
|
105
116
|
extensionItem.attachments = [itemProvider]
|
106
117
|
|
118
|
+
// Invoke UIActivityViewController to choose Payment App
|
107
119
|
let activityViewController = UIActivityViewController(activityItems: [extensionItem], applicationActivities: nil)
|
108
120
|
|
109
121
|
activityViewController.completionWithItemsHandler = { (activityType, completed, returnedItems, activityError) in
|
122
|
+
// Start the activity chosen to complete the payment
|
123
|
+
// print("Start the activity chosen to complete the payment : \(completed)")
|
110
124
|
if !completed {
|
111
125
|
CorePlugin.HKFPSCall?.keepAlive = false;
|
112
126
|
CorePlugin.HKFPSCall = nil;
|
@@ -114,6 +128,7 @@ public class CorePlugin: CAPPlugin {
|
|
114
128
|
}
|
115
129
|
DispatchQueue.main.async {
|
116
130
|
self.bridge?.viewController?.present(activityViewController, animated: true, completion: nil)
|
131
|
+
|
117
132
|
call.keepAlive = true;
|
118
133
|
CorePlugin.HKFPSCall = call;
|
119
134
|
}
|
@@ -253,6 +268,41 @@ public class CorePlugin: CAPPlugin {
|
|
253
268
|
CorePlugin.dismissCall = call
|
254
269
|
}
|
255
270
|
|
271
|
+
var openEmbedBrowserCallback: CAPPluginCall?
|
272
|
+
@objc func openSecondBrowser(_ call: CAPPluginCall) {
|
273
|
+
aigensprint("CorePlugin openEmbedBrowser")
|
274
|
+
guard let url = call.getString("url") else {
|
275
|
+
call.reject("url is missing")
|
276
|
+
return;
|
277
|
+
}
|
278
|
+
let serviceName = call.getString("serviceName")
|
279
|
+
|
280
|
+
DispatchQueue.main.async {
|
281
|
+
guard let currentVc = self.bridge?.viewController?.view else {
|
282
|
+
call.reject("currentVc is missing")
|
283
|
+
return;
|
284
|
+
}
|
285
|
+
|
286
|
+
let secondView = SecondWebContainerView()
|
287
|
+
self.insertView(secondView, currentVc)
|
288
|
+
secondView.delegate = self
|
289
|
+
secondView.serviceName = serviceName
|
290
|
+
secondView.loadUrl(urlString: url)
|
291
|
+
call.keepAlive = true
|
292
|
+
self.openEmbedBrowserCallback = call
|
293
|
+
}
|
294
|
+
|
295
|
+
}
|
296
|
+
|
297
|
+
public func insertView(_ newView: SecondWebContainerView, _ parentView: UIView) {
|
298
|
+
parentView.subviews
|
299
|
+
.filter { $0 is SecondWebContainerView }
|
300
|
+
.forEach { $0.removeFromSuperview() }
|
301
|
+
|
302
|
+
parentView.addSubview(newView)
|
303
|
+
newView.setCustomFrame(CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height:UIScreen.main.bounds.size.height))
|
304
|
+
}
|
305
|
+
|
256
306
|
|
257
307
|
@objc func openBrowser(_ call: CAPPluginCall) {
|
258
308
|
|
@@ -489,6 +539,15 @@ public class CorePlugin: CAPPlugin {
|
|
489
539
|
|
490
540
|
|
491
541
|
|
542
|
+
}
|
543
|
+
|
544
|
+
extension CorePlugin: SecondWebContainerDelegate {
|
545
|
+
|
546
|
+
public func secondWebContainerViewYuuLoginCallback(view: UIView, data: [String: Any]) {
|
547
|
+
guard let callback = openEmbedBrowserCallback else {return}
|
548
|
+
callback.resolve(data)
|
549
|
+
view.removeFromSuperview()
|
550
|
+
}
|
492
551
|
}
|
493
552
|
|
494
553
|
|
@@ -0,0 +1,157 @@
|
|
1
|
+
//
|
2
|
+
// SecondWebContainerView.swift
|
3
|
+
// AigensSdkCore
|
4
|
+
//
|
5
|
+
// Created by 陈培爵 on 2025/3/10.
|
6
|
+
//
|
7
|
+
|
8
|
+
import WebKit
|
9
|
+
|
10
|
+
@objc public protocol SecondWebContainerDelegate: AnyObject {
|
11
|
+
func secondWebContainerViewYuuLoginCallback(view: UIView, data: [String: Any])
|
12
|
+
}
|
13
|
+
|
14
|
+
@objc open class SecondWebContainerView: UIView {
|
15
|
+
|
16
|
+
public let webView: WKWebView
|
17
|
+
|
18
|
+
private let messageHandlerName = "YuuLoginHandler"
|
19
|
+
private let messageHandlerName2 = "yuuLoginHandler"
|
20
|
+
private var messageHandler: SecondWebViewMessageHandler?
|
21
|
+
|
22
|
+
public weak var delegate: SecondWebContainerDelegate?
|
23
|
+
|
24
|
+
private var currentUrl: String?
|
25
|
+
public var serviceName: String?
|
26
|
+
override init(frame: CGRect) {
|
27
|
+
// 创建 WebView 配置
|
28
|
+
let webConfiguration = WKWebViewConfiguration()
|
29
|
+
webView = WKWebView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height:UIScreen.main.bounds.size.height), configuration: webConfiguration)
|
30
|
+
|
31
|
+
super.init(frame: frame)
|
32
|
+
setupView()
|
33
|
+
}
|
34
|
+
|
35
|
+
required public init?(coder: NSCoder) {
|
36
|
+
fatalError("init(coder:) has not been implemented")
|
37
|
+
}
|
38
|
+
|
39
|
+
private func setupView() {
|
40
|
+
|
41
|
+
addSubview(webView)
|
42
|
+
webView.translatesAutoresizingMaskIntoConstraints = false
|
43
|
+
NSLayoutConstraint.activate([
|
44
|
+
webView.topAnchor.constraint(equalTo: topAnchor),
|
45
|
+
webView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
46
|
+
webView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
47
|
+
webView.bottomAnchor.constraint(equalTo: bottomAnchor)
|
48
|
+
])
|
49
|
+
|
50
|
+
|
51
|
+
webView.navigationDelegate = self
|
52
|
+
webView.allowsBackForwardNavigationGestures = false
|
53
|
+
webView.scrollView.minimumZoomScale = 1.0
|
54
|
+
webView.scrollView.maximumZoomScale = 1.0
|
55
|
+
|
56
|
+
// 禁用双击缩放
|
57
|
+
let disableDoubleTapScript = """
|
58
|
+
var script = document.createElement('script');
|
59
|
+
script.textContent = 'document.documentElement.style.webkitTouchCallout = "none";';
|
60
|
+
document.documentElement.appendChild(script);
|
61
|
+
"""
|
62
|
+
let userScript = WKUserScript(source: disableDoubleTapScript,
|
63
|
+
injectionTime: .atDocumentEnd,
|
64
|
+
forMainFrameOnly: true)
|
65
|
+
webView.configuration.userContentController.addUserScript(userScript)
|
66
|
+
|
67
|
+
}
|
68
|
+
|
69
|
+
deinit {
|
70
|
+
|
71
|
+
print("SecondWebContainerView deinit")
|
72
|
+
webView.configuration.userContentController.removeScriptMessageHandler(forName: messageHandlerName)
|
73
|
+
}
|
74
|
+
|
75
|
+
public func loadUrl(urlString: String) {
|
76
|
+
guard let url = URL(string: urlString) else {
|
77
|
+
aigensprint("secondview Invalid URL: \(urlString)")
|
78
|
+
return
|
79
|
+
}
|
80
|
+
|
81
|
+
messageHandler = SecondWebViewMessageHandler(serviceName: self.serviceName, callback: { [weak self] message in
|
82
|
+
guard let s = self else { return }
|
83
|
+
self?.delegate?.secondWebContainerViewYuuLoginCallback(view: s, data: message)
|
84
|
+
})
|
85
|
+
|
86
|
+
webView.configuration.userContentController.add(messageHandler!, name: messageHandlerName)
|
87
|
+
webView.configuration.userContentController.add(messageHandler!, name: messageHandlerName2)
|
88
|
+
if let name = serviceName {
|
89
|
+
webView.configuration.userContentController.add(messageHandler!, name: name)
|
90
|
+
}
|
91
|
+
|
92
|
+
let request = URLRequest(url: url)
|
93
|
+
webView.load(request)
|
94
|
+
webView.navigationDelegate = self
|
95
|
+
}
|
96
|
+
|
97
|
+
|
98
|
+
public func setCustomFrame(_ frame: CGRect) {
|
99
|
+
self.frame = frame
|
100
|
+
layoutIfNeeded()
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
private class SecondWebViewMessageHandler: NSObject, WKScriptMessageHandler {
|
105
|
+
private let callback: ([String: Any]) -> Void
|
106
|
+
|
107
|
+
private let messageHandlerName = "YuuLoginHandler"
|
108
|
+
private let messageHandlerName2 = "yuuLoginHandler"
|
109
|
+
private var serviceName: String?
|
110
|
+
init(serviceName: String?, callback: @escaping ([String: Any]) -> Void) {
|
111
|
+
self.callback = callback
|
112
|
+
self.serviceName = serviceName
|
113
|
+
}
|
114
|
+
|
115
|
+
func userContentController(_ userContentController: WKUserContentController,
|
116
|
+
didReceive message: WKScriptMessage) {
|
117
|
+
// print("jason message:\(message.name)")
|
118
|
+
|
119
|
+
guard (message.name == messageHandlerName || message.name == messageHandlerName2 || message.name == serviceName ?? ""),
|
120
|
+
let messageBody = message.body as? [String: Any] else {
|
121
|
+
return
|
122
|
+
}
|
123
|
+
|
124
|
+
aigensprint("Received credit card token: \(messageBody)")
|
125
|
+
callback(messageBody)
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
// MARK: - WKNavigationDelegate 实现
|
130
|
+
extension SecondWebContainerView: WKNavigationDelegate {
|
131
|
+
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
132
|
+
if let navURL = navigationAction.request.url {
|
133
|
+
currentUrl = navURL.absoluteString
|
134
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
|
135
|
+
if let url = self.currentUrl, url == "about:blank" {
|
136
|
+
self.delegate?.secondWebContainerViewYuuLoginCallback(view: self, data: ["cancel": true])
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
}
|
141
|
+
|
142
|
+
|
143
|
+
decisionHandler(.allow)
|
144
|
+
}
|
145
|
+
|
146
|
+
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
147
|
+
print("jason secondnavURL didFinish")
|
148
|
+
}
|
149
|
+
|
150
|
+
public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
|
151
|
+
|
152
|
+
print("jason secondnavURL didFail")
|
153
|
+
self.removeFromSuperview()
|
154
|
+
}
|
155
|
+
}
|
156
|
+
|
157
|
+
|
@@ -301,6 +301,23 @@ import Capacitor
|
|
301
301
|
return str.removingPercentEncoding ?? str
|
302
302
|
}
|
303
303
|
|
304
|
+
public func insertView(_ newView: SecondWebContainerView) {
|
305
|
+
|
306
|
+
if let parentView = self.view {
|
307
|
+
parentView.subviews
|
308
|
+
.filter { $0 is SecondWebContainerView }
|
309
|
+
.forEach { $0.removeFromSuperview() }
|
310
|
+
|
311
|
+
}
|
312
|
+
|
313
|
+
if webContainerView.superview != nil {
|
314
|
+
self.view.insertSubview(newView, belowSubview: webContainerView)
|
315
|
+
} else {
|
316
|
+
self.view.addSubview(newView)
|
317
|
+
}
|
318
|
+
newView.setCustomFrame(CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height:UIScreen.main.bounds.size.height))
|
319
|
+
}
|
320
|
+
|
304
321
|
public final func loadWebViewCustom() {
|
305
322
|
|
306
323
|
//let bridge = self.bridge
|