diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/FlutterWebViewFactory.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/FlutterWebViewFactory.java index bc9a325b..86185543 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/FlutterWebViewFactory.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/FlutterWebViewFactory.java @@ -13,6 +13,7 @@ import io.flutter.plugin.platform.PlatformView; import io.flutter.plugin.platform.PlatformViewFactory; public class FlutterWebViewFactory extends PlatformViewFactory { + public static final String VIEW_TYPE_ID = "com.pichillilorenzo/flutter_inappwebview"; private final InAppWebViewFlutterPlugin plugin; public FlutterWebViewFactory(final InAppWebViewFlutterPlugin plugin) { diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java index 4fbbb1dd..55ef9ff4 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java @@ -87,7 +87,7 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware { chromeSafariBrowserManager = new ChromeSafariBrowserManager(this); flutterWebViewFactory = new FlutterWebViewFactory(this); platformViewRegistry.registerViewFactory( - "com.pichillilorenzo/flutter_inappwebview", flutterWebViewFactory); + FlutterWebViewFactory.VIEW_TYPE_ID, flutterWebViewFactory); platformUtil = new PlatformUtil(this); inAppWebViewStatic = new InAppWebViewStatic(this); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewStatic.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewStatic.java index 6b263e92..8fdcc4e8 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewStatic.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewStatic.java @@ -12,7 +12,6 @@ import androidx.webkit.WebViewCompat; import androidx.webkit.WebViewFeature; import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl; -import com.pichillilorenzo.flutter_inappwebview.types.Disposable; import java.lang.reflect.Method; import java.util.HashMap; @@ -24,7 +23,7 @@ import java.util.Set; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; -public class InAppWebViewStatic extends ChannelDelegateImpl implements Disposable { +public class InAppWebViewStatic extends ChannelDelegateImpl { protected static final String LOG_TAG = "InAppWebViewStatic"; public static final String METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_static"; diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java index adde338a..6dba0384 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java @@ -9,7 +9,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl; -import com.pichillilorenzo.flutter_inappwebview.types.Disposable; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -23,10 +22,10 @@ import java.util.TimeZone; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; -public class MyCookieManager extends ChannelDelegateImpl implements Disposable { +public class MyCookieManager extends ChannelDelegateImpl { protected static final String LOG_TAG = "MyCookieManager"; public static final String METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_cookiemanager"; - + @Nullable public static CookieManager cookieManager; @Nullable public InAppWebViewFlutterPlugin plugin; @@ -305,5 +304,6 @@ public class MyCookieManager extends ChannelDelegateImpl implements Disposable { public void dispose() { super.dispose(); plugin = null; + cookieManager = null; } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyWebStorage.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyWebStorage.java index 285fba54..b9ff890a 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyWebStorage.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyWebStorage.java @@ -7,7 +7,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl; -import com.pichillilorenzo.flutter_inappwebview.types.Disposable; import java.util.ArrayList; import java.util.HashMap; @@ -17,10 +16,11 @@ import java.util.Map; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; -public class MyWebStorage extends ChannelDelegateImpl implements Disposable { +public class MyWebStorage extends ChannelDelegateImpl { protected static final String LOG_TAG = "MyWebStorage"; public static final String METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_webstoragemanager"; + @Nullable public static WebStorage webStorageManager; @Nullable public InAppWebViewFlutterPlugin plugin; @@ -38,15 +38,23 @@ public class MyWebStorage extends ChannelDelegateImpl implements Disposable { getOrigins(result); break; case "deleteAllData": - webStorageManager.deleteAllData(); - result.success(true); + if (webStorageManager == null) { + webStorageManager.deleteAllData(); + result.success(true); + } else { + result.success(false); + } break; case "deleteOrigin": { - String origin = (String) call.argument("origin"); - webStorageManager.deleteOrigin(origin); + if (webStorageManager == null) { + String origin = (String) call.argument("origin"); + webStorageManager.deleteOrigin(origin); + result.success(true); + } else { + result.success(false); + } } - result.success(true); break; case "getQuotaForOrigin": { @@ -57,7 +65,7 @@ public class MyWebStorage extends ChannelDelegateImpl implements Disposable { case "getUsageForOrigin": { String origin = (String) call.argument("origin"); - getUsageForOrigin(origin, result); + getUsageForOrigin(origin, result); } break; default: @@ -66,6 +74,10 @@ public class MyWebStorage extends ChannelDelegateImpl implements Disposable { } public void getOrigins(final MethodChannel.Result result) { + if (webStorageManager == null) { + result.success(new ArrayList<>()); + return; + } webStorageManager.getOrigins(new ValueCallback() { @Override public void onReceiveValue(Map value) { @@ -86,6 +98,10 @@ public class MyWebStorage extends ChannelDelegateImpl implements Disposable { } public void getQuotaForOrigin(String origin, final MethodChannel.Result result) { + if (webStorageManager == null) { + result.success(0); + return; + } webStorageManager.getQuotaForOrigin(origin, new ValueCallback() { @Override public void onReceiveValue(Long value) { @@ -95,6 +111,10 @@ public class MyWebStorage extends ChannelDelegateImpl implements Disposable { } public void getUsageForOrigin(String origin, final MethodChannel.Result result) { + if (webStorageManager == null) { + result.success(0); + return; + } webStorageManager.getUsageForOrigin(origin, new ValueCallback() { @Override public void onReceiveValue(Long value) { @@ -107,5 +127,6 @@ public class MyWebStorage extends ChannelDelegateImpl implements Disposable { public void dispose() { super.dispose(); plugin = null; + webStorageManager = null; } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/PlatformUtil.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/PlatformUtil.java index 0437a2f1..8f42e701 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/PlatformUtil.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/PlatformUtil.java @@ -6,7 +6,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl; -import com.pichillilorenzo.flutter_inappwebview.types.Disposable; import java.text.SimpleDateFormat; import java.util.Date; @@ -16,7 +15,7 @@ import java.util.TimeZone; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; -public class PlatformUtil extends ChannelDelegateImpl implements Disposable { +public class PlatformUtil extends ChannelDelegateImpl { protected static final String LOG_TAG = "PlatformUtil"; public static final String METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_platformutil"; diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/RequestPermissionHandler.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/RequestPermissionHandler.java deleted file mode 100755 index c1ca8fe3..00000000 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/RequestPermissionHandler.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.pichillilorenzo.flutter_inappwebview; - -import android.app.Activity; -import android.content.pm.PackageManager; -import android.util.Log; - -import androidx.annotation.NonNull; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public abstract class RequestPermissionHandler implements ActivityCompat.OnRequestPermissionsResultCallback { - - private static Map> actionDictionary = new HashMap<>(); - - public static void checkAndRun(Activity activity, String permission, int requestCode, Runnable runnable) { - - int permissionCheck = ContextCompat.checkSelfPermission(activity.getApplicationContext(), permission); - - if (permissionCheck != PackageManager.PERMISSION_GRANTED) { - if (actionDictionary.containsKey(requestCode)) - actionDictionary.get(requestCode).add(runnable); - else - actionDictionary.put(requestCode, Arrays.asList(runnable)); - ActivityCompat.requestPermissions(activity, new String[]{permission}, requestCode); - } - else - runnable.run(); - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) { - if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) { - List callbacks = actionDictionary.get(requestCode); - for (Runnable runnable : callbacks) { - runnable.run(); - callbacks.remove(runnable); - } - } - } - -} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/WebViewFeatureManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/WebViewFeatureManager.java index 1df294b4..ac38dd94 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/WebViewFeatureManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/WebViewFeatureManager.java @@ -5,12 +5,11 @@ import androidx.annotation.Nullable; import androidx.webkit.WebViewFeature; import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl; -import com.pichillilorenzo.flutter_inappwebview.types.Disposable; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; -public class WebViewFeatureManager extends ChannelDelegateImpl implements Disposable { +public class WebViewFeatureManager extends ChannelDelegateImpl { protected static final String LOG_TAG = "WebViewFeatureManager"; public static final String METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_webviewfeature"; diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java index 2af399ee..dca7150f 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java @@ -9,7 +9,6 @@ import androidx.annotation.Nullable; import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin; import com.pichillilorenzo.flutter_inappwebview.Util; import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl; -import com.pichillilorenzo.flutter_inappwebview.types.Disposable; import java.io.Serializable; import java.util.HashMap; @@ -20,7 +19,7 @@ import java.util.UUID; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; -public class ChromeSafariBrowserManager extends ChannelDelegateImpl implements Disposable { +public class ChromeSafariBrowserManager extends ChannelDelegateImpl { protected static final String LOG_TAG = "ChromeBrowserManager"; public static final String METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_chromesafaribrowser"; diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/credential_database/CredentialDatabaseHandler.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/credential_database/CredentialDatabaseHandler.java index 851f0648..bb532a9e 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/credential_database/CredentialDatabaseHandler.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/credential_database/CredentialDatabaseHandler.java @@ -9,7 +9,6 @@ import androidx.annotation.RequiresApi; import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin; import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl; -import com.pichillilorenzo.flutter_inappwebview.types.Disposable; import com.pichillilorenzo.flutter_inappwebview.types.URLCredential; import com.pichillilorenzo.flutter_inappwebview.types.URLProtectionSpace; @@ -22,10 +21,11 @@ import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; @RequiresApi(api = Build.VERSION_CODES.O) -public class CredentialDatabaseHandler extends ChannelDelegateImpl implements Disposable { +public class CredentialDatabaseHandler extends ChannelDelegateImpl { protected static final String LOG_TAG = "CredentialDatabaseHandler"; public static final String METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_credential_database"; + @Nullable public static CredentialDatabase credentialDatabase; @Nullable public InAppWebViewFlutterPlugin plugin; @@ -42,80 +42,97 @@ public class CredentialDatabaseHandler extends ChannelDelegateImpl implements Di case "getAllAuthCredentials": { List> allCredentials = new ArrayList<>(); - List protectionSpaces = credentialDatabase.protectionSpaceDao.getAll(); - for (URLProtectionSpace protectionSpace : protectionSpaces) { - List> credentials = new ArrayList<>(); - for (URLCredential credential : credentialDatabase.credentialDao.getAllByProtectionSpaceId(protectionSpace.getId())) { - credentials.add(credential.toMap()); + if (credentialDatabase != null) { + List protectionSpaces = credentialDatabase.protectionSpaceDao.getAll(); + for (URLProtectionSpace protectionSpace : protectionSpaces) { + List> credentials = new ArrayList<>(); + for (URLCredential credential : credentialDatabase.credentialDao.getAllByProtectionSpaceId(protectionSpace.getId())) { + credentials.add(credential.toMap()); + } + Map obj = new HashMap<>(); + obj.put("protectionSpace", protectionSpace.toMap()); + obj.put("credentials", credentials); + allCredentials.add(obj); } - Map obj = new HashMap<>(); - obj.put("protectionSpace", protectionSpace.toMap()); - obj.put("credentials", credentials); - allCredentials.add(obj); } result.success(allCredentials); } break; case "getHttpAuthCredentials": { - String host = (String) call.argument("host"); - String protocol = (String) call.argument("protocol"); - String realm = (String) call.argument("realm"); - Integer port = (Integer) call.argument("port"); - List> credentials = new ArrayList<>(); - for (URLCredential credential : credentialDatabase.getHttpAuthCredentials(host, protocol, realm, port)) { - credentials.add(credential.toMap()); + if (credentialDatabase != null) { + String host = (String) call.argument("host"); + String protocol = (String) call.argument("protocol"); + String realm = (String) call.argument("realm"); + Integer port = (Integer) call.argument("port"); + + for (URLCredential credential : credentialDatabase.getHttpAuthCredentials(host, protocol, realm, port)) { + credentials.add(credential.toMap()); + } } result.success(credentials); } break; case "setHttpAuthCredential": { - String host = (String) call.argument("host"); - String protocol = (String) call.argument("protocol"); - String realm = (String) call.argument("realm"); - Integer port = (Integer) call.argument("port"); - String username = (String) call.argument("username"); - String password = (String) call.argument("password"); + if (credentialDatabase != null) { + String host = (String) call.argument("host"); + String protocol = (String) call.argument("protocol"); + String realm = (String) call.argument("realm"); + Integer port = (Integer) call.argument("port"); + String username = (String) call.argument("username"); + String password = (String) call.argument("password"); - credentialDatabase.setHttpAuthCredential(host, protocol, realm, port, username, password); - - result.success(true); + credentialDatabase.setHttpAuthCredential(host, protocol, realm, port, username, password); + result.success(true); + } else { + result.success(false); + } } break; case "removeHttpAuthCredential": { - String host = (String) call.argument("host"); - String protocol = (String) call.argument("protocol"); - String realm = (String) call.argument("realm"); - Integer port = (Integer) call.argument("port"); - String username = (String) call.argument("username"); - String password = (String) call.argument("password"); + if (credentialDatabase != null) { + String host = (String) call.argument("host"); + String protocol = (String) call.argument("protocol"); + String realm = (String) call.argument("realm"); + Integer port = (Integer) call.argument("port"); + String username = (String) call.argument("username"); + String password = (String) call.argument("password"); - credentialDatabase.removeHttpAuthCredential(host, protocol, realm, port, username, password); - - result.success(true); + credentialDatabase.removeHttpAuthCredential(host, protocol, realm, port, username, password); + result.success(true); + } else { + result.success(false); + } } break; case "removeHttpAuthCredentials": { - String host = (String) call.argument("host"); - String protocol = (String) call.argument("protocol"); - String realm = (String) call.argument("realm"); - Integer port = (Integer) call.argument("port"); + if (credentialDatabase != null) { + String host = (String) call.argument("host"); + String protocol = (String) call.argument("protocol"); + String realm = (String) call.argument("realm"); + Integer port = (Integer) call.argument("port"); - credentialDatabase.removeHttpAuthCredentials(host, protocol, realm, port); - - result.success(true); + credentialDatabase.removeHttpAuthCredentials(host, protocol, realm, port); + result.success(true); + } else { + result.success(false); + } } break; case "clearAllAuthCredentials": - credentialDatabase.clearAllAuthCredentials(); - if (plugin != null && plugin.applicationContext != null) { - WebViewDatabase.getInstance(plugin.applicationContext).clearHttpAuthUsernamePassword(); + if (credentialDatabase != null) { + credentialDatabase.clearAllAuthCredentials(); + if (plugin != null && plugin.applicationContext != null) { + WebViewDatabase.getInstance(plugin.applicationContext).clearHttpAuthUsernamePassword(); + } + result.success(true); + } else { + result.success(false); } - result.success(true); break; default: result.notImplemented(); @@ -126,5 +143,6 @@ public class CredentialDatabaseHandler extends ChannelDelegateImpl implements Di public void dispose() { super.dispose(); plugin = null; + credentialDatabase = null; } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/headless_in_app_webview/HeadlessInAppWebViewManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/headless_in_app_webview/HeadlessInAppWebViewManager.java index eeb9183b..62409008 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/headless_in_app_webview/HeadlessInAppWebViewManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/headless_in_app_webview/HeadlessInAppWebViewManager.java @@ -27,7 +27,6 @@ import androidx.annotation.NonNull; import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin; import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl; import com.pichillilorenzo.flutter_inappwebview.webview.in_app_webview.FlutterWebView; -import com.pichillilorenzo.flutter_inappwebview.types.Disposable; import java.util.Collection; import java.util.HashMap; @@ -37,7 +36,7 @@ import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.Result; -public class HeadlessInAppWebViewManager extends ChannelDelegateImpl implements Disposable { +public class HeadlessInAppWebViewManager extends ChannelDelegateImpl { protected static final String LOG_TAG = "HeadlessInAppWebViewManager"; public static final String METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_headless_inappwebview"; diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserManager.java index 0e73319c..189ed20d 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserManager.java @@ -37,7 +37,6 @@ import androidx.annotation.Nullable; import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin; import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl; -import com.pichillilorenzo.flutter_inappwebview.types.Disposable; import java.io.Serializable; import java.util.ArrayList; @@ -53,7 +52,7 @@ import io.flutter.plugin.common.MethodChannel.Result; /** * InAppBrowserManager */ -public class InAppBrowserManager extends ChannelDelegateImpl implements Disposable { +public class InAppBrowserManager extends ChannelDelegateImpl { protected static final String LOG_TAG = "InAppBrowserManager"; public static final String METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappbrowser"; diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/proxy/ProxyManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/proxy/ProxyManager.java index 2d49f1c8..261fdecb 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/proxy/ProxyManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/proxy/ProxyManager.java @@ -8,7 +8,6 @@ import androidx.webkit.WebViewFeature; import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin; import com.pichillilorenzo.flutter_inappwebview.types.ChannelDelegateImpl; -import com.pichillilorenzo.flutter_inappwebview.types.Disposable; import com.pichillilorenzo.flutter_inappwebview.types.ProxyRuleExt; import java.util.HashMap; @@ -17,7 +16,7 @@ import java.util.concurrent.Executor; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; -public class ProxyManager extends ChannelDelegateImpl implements Disposable { +public class ProxyManager extends ChannelDelegateImpl { protected static final String LOG_TAG = "ProxyManager"; public static final String METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_proxycontroller"; diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/IChannelDelegate.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/IChannelDelegate.java index 3de75d6f..b050788a 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/IChannelDelegate.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/IChannelDelegate.java @@ -4,8 +4,7 @@ import androidx.annotation.Nullable; import io.flutter.plugin.common.MethodChannel; -public interface IChannelDelegate extends MethodChannel.MethodCallHandler { +public interface IChannelDelegate extends MethodChannel.MethodCallHandler, Disposable { @Nullable MethodChannel getChannel(); - void dispose(); } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/URLRequest.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/URLRequest.java index 313c78f2..dd156a5d 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/URLRequest.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/URLRequest.java @@ -1,6 +1,5 @@ package com.pichillilorenzo.flutter_inappwebview.types; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.util.Arrays; @@ -8,7 +7,7 @@ import java.util.HashMap; import java.util.Map; public class URLRequest { - @NonNull + @Nullable private String url; @Nullable private String method; @@ -17,7 +16,7 @@ public class URLRequest { @Nullable private Map headers; - public URLRequest(@NonNull String url, @Nullable String method, @Nullable byte[] body, @Nullable Map headers) { + public URLRequest(@Nullable String url, @Nullable String method, @Nullable byte[] body, @Nullable Map headers) { this.url = url; this.method = method; this.body = body; @@ -30,10 +29,12 @@ public class URLRequest { return null; } String url = (String) map.get("url"); + if (url == null) { + url = "about:blank"; + } String method = (String) map.get("method"); byte[] body = (byte[]) map.get("body"); Map headers = (Map) map.get("headers"); - assert url != null; return new URLRequest(url, method, body, headers); } @@ -55,12 +56,12 @@ public class URLRequest { return urlRequestMap; } - @NonNull + @Nullable public String getUrl() { return url; } - public void setUrl(@NonNull String url) { + public void setUrl(@Nullable String url) { this.url = url; } @@ -98,7 +99,7 @@ public class URLRequest { URLRequest that = (URLRequest) o; - if (!url.equals(that.url)) return false; + if (url != null ? !url.equals(that.url) : that.url != null) return false; if (method != null ? !method.equals(that.method) : that.method != null) return false; if (!Arrays.equals(body, that.body)) return false; return headers != null ? headers.equals(that.headers) : that.headers == null; @@ -106,7 +107,7 @@ public class URLRequest { @Override public int hashCode() { - int result = url.hashCode(); + int result = url != null ? url.hashCode() : 0; result = 31 * result + (method != null ? method.hashCode() : 0); result = 31 * result + Arrays.hashCode(body); result = 31 * result + (headers != null ? headers.hashCode() : 0); diff --git a/example/ios/Flutter/flutter_export_environment.sh b/example/ios/Flutter/flutter_export_environment.sh index dad54015..9e98dd5e 100755 --- a/example/ios/Flutter/flutter_export_environment.sh +++ b/example/ios/Flutter/flutter_export_environment.sh @@ -3,11 +3,12 @@ export "FLUTTER_ROOT=/Users/lorenzopichilli/fvm/versions/2.10.4" export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example" export "COCOAPODS_PARALLEL_CODE_SIGN=true" -export "FLUTTER_TARGET=lib/main.dart" +export "FLUTTER_TARGET=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/lib/main.dart" export "FLUTTER_BUILD_DIR=build" export "FLUTTER_BUILD_NAME=1.0.0" export "FLUTTER_BUILD_NUMBER=1" +export "DART_DEFINES=Zmx1dHRlci5pbnNwZWN0b3Iuc3RydWN0dXJlZEVycm9ycz10cnVl,RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==" export "DART_OBFUSCATION=false" -export "TRACK_WIDGET_CREATION=false" +export "TRACK_WIDGET_CREATION=true" export "TREE_SHAKE_ICONS=false" -export "PACKAGE_CONFIG=.packages" +export "PACKAGE_CONFIG=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/.dart_tool/package_config.json" diff --git a/ios/Classes/CredentialDatabase.swift b/ios/Classes/CredentialDatabase.swift index 5bfb1e64..42c88425 100755 --- a/ios/Classes/CredentialDatabase.swift +++ b/ios/Classes/CredentialDatabase.swift @@ -7,26 +7,18 @@ import Foundation -class CredentialDatabase: NSObject, FlutterPlugin { - +class CredentialDatabase: ChannelDelegate { + static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_credential_database" static var registrar: FlutterPluginRegistrar? - static var channel: FlutterMethodChannel? static var credentialStore: URLCredentialStorage? - static func register(with registrar: FlutterPluginRegistrar) { - - } - init(registrar: FlutterPluginRegistrar) { - super.init() + super.init(channel: FlutterMethodChannel(name: CredentialDatabase.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger())) CredentialDatabase.registrar = registrar CredentialDatabase.credentialStore = URLCredentialStorage.shared - - CredentialDatabase.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappwebview_credential_database", binaryMessenger: registrar.messenger()) - registrar.addMethodCallDelegate(self, channel: CredentialDatabase.channel!) } - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { let arguments = call.arguments as? NSDictionary switch call.method { case "getAllAuthCredentials": @@ -196,9 +188,8 @@ class CredentialDatabase: NSObject, FlutterPlugin { } } - public func dispose() { - CredentialDatabase.channel?.setMethodCallHandler(nil) - CredentialDatabase.channel = nil + public override func dispose() { + super.dispose() CredentialDatabase.registrar = nil CredentialDatabase.credentialStore = nil } diff --git a/ios/Classes/HeadlessInAppWebView/HeadlessInAppWebView.swift b/ios/Classes/HeadlessInAppWebView/HeadlessInAppWebView.swift index 55b65d9a..d688f50f 100644 --- a/ios/Classes/HeadlessInAppWebView/HeadlessInAppWebView.swift +++ b/ios/Classes/HeadlessInAppWebView/HeadlessInAppWebView.swift @@ -7,47 +7,22 @@ import Foundation -public class HeadlessInAppWebView : FlutterMethodCallDelegate { +public class HeadlessInAppWebView : Disposable { + static let METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_headless_inappwebview_" var id: String - var channel: FlutterMethodChannel? + var channelDelegate: HeadlessWebViewChannelDelegate? var flutterWebView: FlutterWebViewController? public init(id: String, flutterWebView: FlutterWebViewController) { self.id = id - super.init() self.flutterWebView = flutterWebView - self.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_headless_inappwebview_" + id, + let channel = FlutterMethodChannel(name: HeadlessInAppWebView.METHOD_CHANNEL_NAME_PREFIX + id, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger()) - self.channel?.setMethodCallHandler(self.handle) - } - - public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - let arguments = call.arguments as? NSDictionary - - switch call.method { - case "dispose": - dispose() - result(true) - break - case "setSize": - let sizeMap = arguments!["size"] as? [String: Any?] - if let size = Size2D.fromMap(map: sizeMap) { - setSize(size: size) - } - result(true) - break - case "getSize": - result(getSize()?.toMap()) - break - default: - result(FlutterMethodNotImplemented) - break - } + self.channelDelegate = HeadlessWebViewChannelDelegate(headlessWebView: self, channel: channel) } public func onWebViewCreated() { - let arguments: [String: Any?] = [:] - channel?.invokeMethod("onWebViewCreated", arguments: arguments) + channelDelegate?.onWebViewCreated(); } public func prepare(params: NSDictionary) { @@ -87,8 +62,8 @@ public class HeadlessInAppWebView : FlutterMethodCallDelegate { } public func dispose() { - channel?.setMethodCallHandler(nil) - channel = nil + channelDelegate?.dispose() + channelDelegate = nil HeadlessInAppWebViewManager.webViews[id] = nil flutterWebView = nil } diff --git a/ios/Classes/HeadlessInAppWebView/HeadlessInAppWebViewManager.swift b/ios/Classes/HeadlessInAppWebView/HeadlessInAppWebViewManager.swift index 97e808a0..e884ecb2 100644 --- a/ios/Classes/HeadlessInAppWebView/HeadlessInAppWebViewManager.swift +++ b/ios/Classes/HeadlessInAppWebView/HeadlessInAppWebViewManager.swift @@ -13,23 +13,17 @@ import WebKit import Foundation import AVFoundation -public class HeadlessInAppWebViewManager: NSObject, FlutterPlugin { +public class HeadlessInAppWebViewManager: ChannelDelegate { + static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_headless_inappwebview" static var registrar: FlutterPluginRegistrar? - static var channel: FlutterMethodChannel? static var webViews: [String: HeadlessInAppWebView?] = [:] - public static func register(with registrar: FlutterPluginRegistrar) { - - } - init(registrar: FlutterPluginRegistrar) { - super.init() + super.init(channel: FlutterMethodChannel(name: HeadlessInAppWebViewManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger())) HeadlessInAppWebViewManager.registrar = registrar - HeadlessInAppWebViewManager.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_headless_inappwebview", binaryMessenger: registrar.messenger()) - registrar.addMethodCallDelegate(self, channel: HeadlessInAppWebViewManager.channel!) } - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { let arguments = call.arguments as? NSDictionary let id: String = arguments!["id"] as! String @@ -58,9 +52,8 @@ public class HeadlessInAppWebViewManager: NSObject, FlutterPlugin { flutterWebView.makeInitialLoad(params: params as NSDictionary) } - public func dispose() { - HeadlessInAppWebViewManager.channel?.setMethodCallHandler(nil) - HeadlessInAppWebViewManager.channel = nil + public override func dispose() { + super.dispose() HeadlessInAppWebViewManager.registrar = nil let headlessWebViews = HeadlessInAppWebViewManager.webViews.values headlessWebViews.forEach { (headlessWebView: HeadlessInAppWebView?) in diff --git a/ios/Classes/HeadlessInAppWebView/HeadlessWebViewChannelDelegate.swift b/ios/Classes/HeadlessInAppWebView/HeadlessWebViewChannelDelegate.swift new file mode 100644 index 00000000..e6f151c1 --- /dev/null +++ b/ios/Classes/HeadlessInAppWebView/HeadlessWebViewChannelDelegate.swift @@ -0,0 +1,59 @@ +// +// HeadlessWebViewChannelDelegate.swift +// flutter_inappwebview +// +// Created by Lorenzo Pichilli on 05/05/22. +// + +import Foundation + +public class HeadlessWebViewChannelDelegate : ChannelDelegate { + private var headlessWebView: HeadlessInAppWebView? + + public init(headlessWebView: HeadlessInAppWebView, channel: FlutterMethodChannel) { + super.init(channel: channel) + self.headlessWebView = headlessWebView + } + + public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + let arguments = call.arguments as? NSDictionary + + switch call.method { + case "dispose": + if let headlessWebView = headlessWebView { + headlessWebView.dispose() + result(true) + } else { + result(false) + } + break + case "setSize": + if let headlessWebView = headlessWebView { + let sizeMap = arguments!["size"] as? [String: Any?] + if let size = Size2D.fromMap(map: sizeMap) { + headlessWebView.setSize(size: size) + } + result(true) + } else { + result(false) + } + break + case "getSize": + result(headlessWebView?.getSize()?.toMap()) + break + default: + result(FlutterMethodNotImplemented) + break + } + } + + public func onWebViewCreated() { + let arguments: [String: Any?] = [:] + channel?.invokeMethod("onWebViewCreated", arguments: arguments) + } + + public override func dispose() { + super.dispose() + headlessWebView = nil + } + } diff --git a/ios/Classes/InAppBrowser/InAppBrowserManager.swift b/ios/Classes/InAppBrowser/InAppBrowserManager.swift index 4f89ffdf..8dd465eb 100755 --- a/ios/Classes/InAppBrowser/InAppBrowserManager.swift +++ b/ios/Classes/InAppBrowser/InAppBrowserManager.swift @@ -11,28 +11,21 @@ import WebKit import Foundation import AVFoundation -let WEBVIEW_STORYBOARD = "WebView" -let WEBVIEW_STORYBOARD_CONTROLLER_ID = "viewController" -let NAV_STORYBOARD_CONTROLLER_ID = "navController" - -public class InAppBrowserManager: NSObject, FlutterPlugin { +public class InAppBrowserManager: ChannelDelegate { + static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappbrowser" + static let WEBVIEW_STORYBOARD = "WebView" + static let WEBVIEW_STORYBOARD_CONTROLLER_ID = "viewController" + static let NAV_STORYBOARD_CONTROLLER_ID = "navController" static var registrar: FlutterPluginRegistrar? - static var channel: FlutterMethodChannel? private var previousStatusBarStyle = -1 - public static func register(with registrar: FlutterPluginRegistrar) { - - } - init(registrar: FlutterPluginRegistrar) { - super.init() + super.init(channel: FlutterMethodChannel(name: InAppBrowserManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger())) InAppBrowserManager.registrar = registrar - InAppBrowserManager.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappbrowser", binaryMessenger: registrar.messenger()) - registrar.addMethodCallDelegate(self, channel: InAppBrowserManager.channel!) } - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { let arguments = call.arguments as? NSDictionary switch call.method { @@ -100,8 +93,8 @@ public class InAppBrowserManager: NSObject, FlutterPlugin { } public func presentViewController(webViewController: InAppBrowserWebViewController) { - let storyboard = UIStoryboard(name: WEBVIEW_STORYBOARD, bundle: Bundle(for: InAppWebViewFlutterPlugin.self)) - let navController = storyboard.instantiateViewController(withIdentifier: NAV_STORYBOARD_CONTROLLER_ID) as! InAppBrowserNavigationController + let storyboard = UIStoryboard(name: InAppBrowserManager.WEBVIEW_STORYBOARD, bundle: Bundle(for: InAppWebViewFlutterPlugin.self)) + let navController = storyboard.instantiateViewController(withIdentifier: InAppBrowserManager.NAV_STORYBOARD_CONTROLLER_ID) as! InAppBrowserNavigationController webViewController.edgesForExtendedLayout = [] navController.pushViewController(webViewController, animated: false) webViewController.prepareNavigationControllerBeforeViewWillAppear() @@ -141,9 +134,8 @@ public class InAppBrowserManager: NSObject, FlutterPlugin { result(true) } - public func dispose() { - InAppBrowserManager.channel?.setMethodCallHandler(nil) - InAppBrowserManager.channel = nil + public override func dispose() { + super.dispose() InAppBrowserManager.registrar = nil } } diff --git a/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift b/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift index ecc7499c..7c840c27 100755 --- a/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift +++ b/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift @@ -65,11 +65,9 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega methodCallDelegate = InAppWebViewMethodHandler(webView: webView!) channel!.setMethodCallHandler(LeakAvoider(delegate: methodCallDelegate!).handle) - let pullToRefreshLayoutChannel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappwebview_pull_to_refresh_" + id, - binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger()) let pullToRefreshSettings = PullToRefreshSettings() let _ = pullToRefreshSettings.parse(settings: pullToRefreshInitialSettings) - let pullToRefreshControl = PullToRefreshControl(channel: pullToRefreshLayoutChannel, settings: pullToRefreshSettings) + let pullToRefreshControl = PullToRefreshControl(registrar: SwiftFlutterPlugin.instance!.registrar!, id: id, settings: pullToRefreshSettings) webView.pullToRefreshControl = pullToRefreshControl pullToRefreshControl.delegate = webView pullToRefreshControl.prepare() diff --git a/ios/Classes/ContextMenuSettings.swift b/ios/Classes/InAppWebView/ContextMenuSettings.swift similarity index 100% rename from ios/Classes/ContextMenuSettings.swift rename to ios/Classes/InAppWebView/ContextMenuSettings.swift diff --git a/ios/Classes/CustomeSchemeHandler.swift b/ios/Classes/InAppWebView/CustomSchemeHandler.swift similarity index 96% rename from ios/Classes/CustomeSchemeHandler.swift rename to ios/Classes/InAppWebView/CustomSchemeHandler.swift index a1121e33..072779af 100755 --- a/ios/Classes/CustomeSchemeHandler.swift +++ b/ios/Classes/InAppWebView/CustomSchemeHandler.swift @@ -10,7 +10,7 @@ import Foundation import WebKit @available(iOS 11.0, *) -class CustomeSchemeHandler : NSObject, WKURLSchemeHandler { +class CustomSchemeHandler : NSObject, WKURLSchemeHandler { var schemeHandlers: [Int:WKURLSchemeTask] = [:] func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) { diff --git a/ios/Classes/InAppWebView/FlutterWebViewController.swift b/ios/Classes/InAppWebView/FlutterWebViewController.swift index 0d2f0c41..8827eee2 100755 --- a/ios/Classes/InAppWebView/FlutterWebViewController.swift +++ b/ios/Classes/InAppWebView/FlutterWebViewController.swift @@ -63,11 +63,9 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView { methodCallDelegate = InAppWebViewMethodHandler(webView: webView!) channel!.setMethodCallHandler(LeakAvoider(delegate: methodCallDelegate!).handle) - let pullToRefreshLayoutChannel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappwebview_pull_to_refresh_" + String(describing: viewId), - binaryMessenger: registrar.messenger()) let pullToRefreshSettings = PullToRefreshSettings() let _ = pullToRefreshSettings.parse(settings: pullToRefreshInitialSettings) - let pullToRefreshControl = PullToRefreshControl(channel: pullToRefreshLayoutChannel, settings: pullToRefreshSettings) + let pullToRefreshControl = PullToRefreshControl(registrar: registrar, id: viewId, settings: pullToRefreshSettings) webView!.pullToRefreshControl = pullToRefreshControl pullToRefreshControl.delegate = webView! pullToRefreshControl.prepare() diff --git a/ios/Classes/InAppWebView/FlutterWebViewFactory.swift b/ios/Classes/InAppWebView/FlutterWebViewFactory.swift index 30fcce52..2e202510 100755 --- a/ios/Classes/InAppWebView/FlutterWebViewFactory.swift +++ b/ios/Classes/InAppWebView/FlutterWebViewFactory.swift @@ -9,6 +9,7 @@ import Flutter import Foundation public class FlutterWebViewFactory: NSObject, FlutterPlatformViewFactory { + static let VIEW_TYPE_ID = "com.pichillilorenzo/flutter_inappwebview" private var registrar: FlutterPluginRegistrar? init(registrar: FlutterPluginRegistrar?) { diff --git a/ios/Classes/InAppWebView/InAppWebView.swift b/ios/Classes/InAppWebView/InAppWebView.swift index 98c311bf..c030af3c 100755 --- a/ios/Classes/InAppWebView/InAppWebView.swift +++ b/ios/Classes/InAppWebView/InAppWebView.swift @@ -565,7 +565,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, if #available(iOS 11.0, *) { for scheme in settings.resourceCustomSchemes { - configuration.setURLSchemeHandler(CustomeSchemeHandler(), forURLScheme: scheme) + configuration.setURLSchemeHandler(CustomSchemeHandler(), forURLScheme: scheme) } if settings.sharedCookiesEnabled { // More info to sending cookies with WKWebView diff --git a/ios/Classes/InAppWebViewStatic.swift b/ios/Classes/InAppWebViewStatic.swift index 58e5f874..3f0dfbc5 100755 --- a/ios/Classes/InAppWebViewStatic.swift +++ b/ios/Classes/InAppWebViewStatic.swift @@ -8,24 +8,18 @@ import Foundation import WebKit -class InAppWebViewStatic: NSObject, FlutterPlugin { +class InAppWebViewStatic: ChannelDelegate { + static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_static" static var registrar: FlutterPluginRegistrar? - static var channel: FlutterMethodChannel? static var webViewForUserAgent: WKWebView? static var defaultUserAgent: String? - static func register(with registrar: FlutterPluginRegistrar) { - - } - init(registrar: FlutterPluginRegistrar) { - super.init() + super.init(channel: FlutterMethodChannel(name: InAppWebViewStatic.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger())) InAppWebViewStatic.registrar = registrar - InAppWebViewStatic.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappwebview_static", binaryMessenger: registrar.messenger()) - registrar.addMethodCallDelegate(self, channel: InAppWebViewStatic.channel!) } - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { let arguments = call.arguments as? NSDictionary switch call.method { @@ -73,9 +67,8 @@ class InAppWebViewStatic: NSObject, FlutterPlugin { } } - public func dispose() { - InAppWebViewStatic.channel?.setMethodCallHandler(nil) - InAppWebViewStatic.channel = nil + public override func dispose() { + super.dispose() InAppWebViewStatic.registrar = nil InAppWebViewStatic.webViewForUserAgent = nil InAppWebViewStatic.defaultUserAgent = nil diff --git a/ios/Classes/MyCookieManager.swift b/ios/Classes/MyCookieManager.swift index 1f892d87..04cf7626 100755 --- a/ios/Classes/MyCookieManager.swift +++ b/ios/Classes/MyCookieManager.swift @@ -9,26 +9,18 @@ import Foundation import WebKit @available(iOS 11.0, *) -class MyCookieManager: NSObject, FlutterPlugin { - +class MyCookieManager: ChannelDelegate { + static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_cookiemanager" static var registrar: FlutterPluginRegistrar? - static var channel: FlutterMethodChannel? static var httpCookieStore: WKHTTPCookieStore? - static func register(with registrar: FlutterPluginRegistrar) { - - } - init(registrar: FlutterPluginRegistrar) { - super.init() + super.init(channel: FlutterMethodChannel(name: MyCookieManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger())) MyCookieManager.registrar = registrar MyCookieManager.httpCookieStore = WKWebsiteDataStore.default().httpCookieStore - - MyCookieManager.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappwebview_cookiemanager", binaryMessenger: registrar.messenger()) - registrar.addMethodCallDelegate(self, channel: MyCookieManager.channel!) } - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { let arguments = call.arguments as? NSDictionary switch call.method { case "setCookie": @@ -298,9 +290,8 @@ class MyCookieManager: NSObject, FlutterPlugin { }) } - public func dispose() { - MyCookieManager.channel?.setMethodCallHandler(nil) - MyCookieManager.channel = nil + public override func dispose() { + super.dispose() MyCookieManager.registrar = nil MyCookieManager.httpCookieStore = nil } diff --git a/ios/Classes/MyWebStorageManager.swift b/ios/Classes/MyWebStorageManager.swift index 426f30e5..0b5eca8f 100755 --- a/ios/Classes/MyWebStorageManager.swift +++ b/ios/Classes/MyWebStorageManager.swift @@ -9,26 +9,18 @@ import Foundation import WebKit @available(iOS 9.0, *) -class MyWebStorageManager: NSObject, FlutterPlugin { - +class MyWebStorageManager: ChannelDelegate { + static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_webstoragemanager" static var registrar: FlutterPluginRegistrar? - static var channel: FlutterMethodChannel? static var websiteDataStore: WKWebsiteDataStore? - static func register(with registrar: FlutterPluginRegistrar) { - - } - init(registrar: FlutterPluginRegistrar) { - super.init() + super.init(channel: FlutterMethodChannel(name: MyWebStorageManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger())) MyWebStorageManager.registrar = registrar MyWebStorageManager.websiteDataStore = WKWebsiteDataStore.default() - - MyWebStorageManager.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappwebview_webstoragemanager", binaryMessenger: registrar.messenger()) - registrar.addMethodCallDelegate(self, channel: MyWebStorageManager.channel!) } - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { let arguments = call.arguments as? NSDictionary switch call.method { case "fetchDataRecords": @@ -108,9 +100,8 @@ class MyWebStorageManager: NSObject, FlutterPlugin { } } - public func dispose() { - MyWebStorageManager.channel?.setMethodCallHandler(nil) - MyWebStorageManager.channel = nil + public override func dispose() { + super.dispose() MyWebStorageManager.registrar = nil MyWebStorageManager.websiteDataStore = nil } diff --git a/ios/Classes/PlatformUtil.swift b/ios/Classes/PlatformUtil.swift index 0bf29b40..0f3afbec 100644 --- a/ios/Classes/PlatformUtil.swift +++ b/ios/Classes/PlatformUtil.swift @@ -7,22 +7,16 @@ import Foundation -class PlatformUtil: NSObject, FlutterPlugin { +class PlatformUtil: ChannelDelegate { + static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_platformutil" static var registrar: FlutterPluginRegistrar? - static var channel: FlutterMethodChannel? - - static func register(with registrar: FlutterPluginRegistrar) { - - } init(registrar: FlutterPluginRegistrar) { - super.init() + super.init(channel: FlutterMethodChannel(name: PlatformUtil.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger())) InAppWebViewStatic.registrar = registrar - InAppWebViewStatic.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappwebview_platformutil", binaryMessenger: registrar.messenger()) - registrar.addMethodCallDelegate(self, channel: InAppWebViewStatic.channel!) } - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { let arguments = call.arguments as? NSDictionary switch call.method { @@ -61,9 +55,8 @@ class PlatformUtil: NSObject, FlutterPlugin { return formatter.string(from: PlatformUtil.getDateFromMilliseconds(date: date)) } - public func dispose() { - PlatformUtil.channel?.setMethodCallHandler(nil) - PlatformUtil.channel = nil + public override func dispose() { + super.dispose() PlatformUtil.registrar = nil } } diff --git a/ios/Classes/PullToRefresh/PullToRefreshChannelDelegate.swift b/ios/Classes/PullToRefresh/PullToRefreshChannelDelegate.swift new file mode 100644 index 00000000..df33c16a --- /dev/null +++ b/ios/Classes/PullToRefresh/PullToRefreshChannelDelegate.swift @@ -0,0 +1,90 @@ +// +// PullToRefreshChannelDelegate.swift +// flutter_inappwebview +// +// Created by Lorenzo Pichilli on 05/05/22. +// + +import Foundation + +public class PullToRefreshChannelDelegate : ChannelDelegate { + private var pullToRefreshControl: PullToRefreshControl? + + public init(pullToRefreshControl: PullToRefreshControl , channel: FlutterMethodChannel) { + super.init(channel: channel) + self.pullToRefreshControl = pullToRefreshControl + } + + public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + let arguments = call.arguments as? NSDictionary + + switch call.method { + case "setEnabled": + if let pullToRefreshView = pullToRefreshControl { + let enabled = arguments!["enabled"] as! Bool + if enabled { + pullToRefreshView.delegate?.enablePullToRefresh() + } else { + pullToRefreshView.delegate?.disablePullToRefresh() + } + result(true) + } else { + result(false) + } + break + case "setRefreshing": + if let pullToRefreshView = pullToRefreshControl { + let refreshing = arguments!["refreshing"] as! Bool + if refreshing { + pullToRefreshView.beginRefreshing() + } else { + pullToRefreshView.endRefreshing() + } + result(true) + } else { + result(false) + } + break + case "setColor": + if let pullToRefreshView = pullToRefreshControl { + let color = arguments!["color"] as! String + pullToRefreshView.tintColor = UIColor(hexString: color) + result(true) + } else { + result(false) + } + break + case "setBackgroundColor": + if let pullToRefreshView = pullToRefreshControl { + let color = arguments!["color"] as! String + pullToRefreshView.backgroundColor = UIColor(hexString: color) + result(true) + } else { + result(false) + } + break + case "setStyledTitle": + if let pullToRefreshView = pullToRefreshControl { + let attributedTitleMap = arguments!["attributedTitle"] as! [String: Any?] + pullToRefreshView.attributedTitle = NSAttributedString.fromMap(map: attributedTitleMap) + result(true) + } else { + result(false) + } + break + default: + result(FlutterMethodNotImplemented) + break + } + } + + public func onRefresh() { + let arguments: [String: Any?] = [:] + channel?.invokeMethod("onRefresh", arguments: arguments) + } + + public override func dispose() { + super.dispose() + pullToRefreshControl = nil + } +} diff --git a/ios/Classes/PullToRefresh/PullToRefreshControl.swift b/ios/Classes/PullToRefresh/PullToRefreshControl.swift index fb808d4b..f2583988 100644 --- a/ios/Classes/PullToRefresh/PullToRefreshControl.swift +++ b/ios/Classes/PullToRefresh/PullToRefreshControl.swift @@ -8,29 +8,26 @@ import Foundation import Flutter -public class PullToRefreshControl : UIRefreshControl, FlutterPlugin { - - var channel: FlutterMethodChannel? +public class PullToRefreshControl : UIRefreshControl, Disposable { + static var METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappwebview_pull_to_refresh_"; + var channelDelegate: PullToRefreshChannelDelegate? var settings: PullToRefreshSettings? var shouldCallOnRefresh = false var delegate: PullToRefreshDelegate? - public init(channel: FlutterMethodChannel?, settings: PullToRefreshSettings?) { + public init(registrar: FlutterPluginRegistrar, id: Any, settings: PullToRefreshSettings?) { super.init() - self.channel = channel self.settings = settings + let channel = FlutterMethodChannel(name: PullToRefreshControl.METHOD_CHANNEL_NAME_PREFIX + String(describing: id), + binaryMessenger: registrar.messenger()) + self.channelDelegate = PullToRefreshChannelDelegate(pullToRefreshControl: self, channel: channel) } required init?(coder: NSCoder) { super.init(coder: coder) } - public static func register(with registrar: FlutterPluginRegistrar) { - - } - public func prepare() { - self.channel?.setMethodCallHandler(self.handle) if let options = settings { if options.enabled { delegate?.enablePullToRefresh() @@ -48,53 +45,9 @@ public class PullToRefreshControl : UIRefreshControl, FlutterPlugin { addTarget(self, action: #selector(updateShouldCallOnRefresh), for: .valueChanged) } - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - let arguments = call.arguments as? NSDictionary - - switch call.method { - case "setEnabled": - let enabled = arguments!["enabled"] as! Bool - if enabled { - delegate?.enablePullToRefresh() - } else { - delegate?.disablePullToRefresh() - } - result(true) - break - case "setRefreshing": - let refreshing = arguments!["refreshing"] as! Bool - if refreshing { - self.beginRefreshing() - } else { - self.endRefreshing() - } - result(true) - break - case "setColor": - let color = arguments!["color"] as! String - tintColor = UIColor(hexString: color) - result(true) - break - case "setBackgroundColor": - let color = arguments!["color"] as! String - backgroundColor = UIColor(hexString: color) - result(true) - break - case "setStyledTitle": - let attributedTitleMap = arguments!["attributedTitle"] as! [String: Any?] - attributedTitle = NSAttributedString.fromMap(map: attributedTitleMap) - result(true) - break - default: - result(FlutterMethodNotImplemented) - break - } - } - public func onRefresh() { shouldCallOnRefresh = false - let arguments: [String: Any?] = [:] - self.channel?.invokeMethod("onRefresh", arguments: arguments) + channelDelegate?.onRefresh() } @objc public func updateShouldCallOnRefresh() { @@ -102,7 +55,8 @@ public class PullToRefreshControl : UIRefreshControl, FlutterPlugin { } public func dispose() { - channel?.setMethodCallHandler(nil) + channelDelegate?.dispose() + channelDelegate = nil removeTarget(self, action: #selector(updateShouldCallOnRefresh), for: .valueChanged) delegate = nil } diff --git a/ios/Classes/SafariViewController/ChromeSafariBrowserManager.swift b/ios/Classes/SafariViewController/ChromeSafariBrowserManager.swift index f157f3ec..46bb65ea 100755 --- a/ios/Classes/SafariViewController/ChromeSafariBrowserManager.swift +++ b/ios/Classes/SafariViewController/ChromeSafariBrowserManager.swift @@ -12,22 +12,16 @@ import Foundation import AVFoundation import SafariServices -public class ChromeSafariBrowserManager: NSObject, FlutterPlugin { +public class ChromeSafariBrowserManager: ChannelDelegate { + static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_chromesafaribrowser" static var registrar: FlutterPluginRegistrar? - static var channel: FlutterMethodChannel? - - public static func register(with registrar: FlutterPluginRegistrar) { - - } init(registrar: FlutterPluginRegistrar) { - super.init() + super.init(channel: FlutterMethodChannel(name: ChromeSafariBrowserManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger())) ChromeSafariBrowserManager.registrar = registrar - ChromeSafariBrowserManager.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_chromesafaribrowser", binaryMessenger: registrar.messenger()) - registrar.addMethodCallDelegate(self, channel: ChromeSafariBrowserManager.channel!) } - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { let arguments = call.arguments as? NSDictionary switch call.method { @@ -92,9 +86,8 @@ public class ChromeSafariBrowserManager: NSObject, FlutterPlugin { result(FlutterError.init(code: "ChromeSafariBrowserManager", message: "SafariViewController is not available!", details: nil)) } - public func dispose() { - ChromeSafariBrowserManager.channel?.setMethodCallHandler(nil) - ChromeSafariBrowserManager.channel = nil + public override func dispose() { + super.dispose() ChromeSafariBrowserManager.registrar = nil } } diff --git a/ios/Classes/SwiftFlutterPlugin.swift b/ios/Classes/SwiftFlutterPlugin.swift index 75631fac..e5fbe685 100755 --- a/ios/Classes/SwiftFlutterPlugin.swift +++ b/ios/Classes/SwiftFlutterPlugin.swift @@ -42,7 +42,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { super.init() self.registrar = registrar - registrar.register(FlutterWebViewFactory(registrar: registrar) as FlutterPlatformViewFactory, withId: "com.pichillilorenzo/flutter_inappwebview") + registrar.register(FlutterWebViewFactory(registrar: registrar) as FlutterPlatformViewFactory, withId: FlutterWebViewFactory.VIEW_TYPE_ID) platformUtil = PlatformUtil(registrar: registrar) inAppBrowserManager = InAppBrowserManager(registrar: registrar) diff --git a/ios/Classes/Types/ChannelDelegate.swift b/ios/Classes/Types/ChannelDelegate.swift new file mode 100644 index 00000000..c451b4b9 --- /dev/null +++ b/ios/Classes/Types/ChannelDelegate.swift @@ -0,0 +1,27 @@ +// +// ChannelDelegate.swift +// flutter_inappwebview +// +// Created by Lorenzo Pichilli on 04/05/22. +// + +import Foundation + +public class ChannelDelegate : FlutterMethodCallDelegate, Disposable { + var channel: FlutterMethodChannel? + + public init(channel: FlutterMethodChannel) { + super.init() + self.channel = channel + self.channel?.setMethodCallHandler(handle) + } + + public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + + } + + public func dispose() { + channel?.setMethodCallHandler(nil) + channel = nil + } +} diff --git a/ios/Classes/Types/Disposable.swift b/ios/Classes/Types/Disposable.swift new file mode 100644 index 00000000..0a34a942 --- /dev/null +++ b/ios/Classes/Types/Disposable.swift @@ -0,0 +1,12 @@ +// +// Disposable.swift +// flutter_inappwebview +// +// Created by Lorenzo Pichilli on 04/05/22. +// + +import Foundation + +public protocol Disposable { + func dispose() -> Void +} diff --git a/ios/Classes/FlutterMethodCallDelegate.swift b/ios/Classes/Types/FlutterMethodCallDelegate.swift similarity index 100% rename from ios/Classes/FlutterMethodCallDelegate.swift rename to ios/Classes/Types/FlutterMethodCallDelegate.swift diff --git a/ios/Classes/HttpAuthenticationChallenge.swift b/ios/Classes/Types/HttpAuthenticationChallenge.swift similarity index 100% rename from ios/Classes/HttpAuthenticationChallenge.swift rename to ios/Classes/Types/HttpAuthenticationChallenge.swift diff --git a/ios/Classes/Types/URLRequest.swift b/ios/Classes/Types/URLRequest.swift index 1b41a991..701a4233 100644 --- a/ios/Classes/Types/URLRequest.swift +++ b/ios/Classes/Types/URLRequest.swift @@ -9,8 +9,11 @@ import Foundation extension URLRequest { public init(fromPluginMap: [String:Any?]) { - let url = fromPluginMap["url"] as! String - self.init(url: URL(string: url)!) + if let urlString = fromPluginMap["url"] as? String, let url = URL(string: urlString) { + self.init(url: url) + } else { + self.init(url: URL(string: "about:blank")!) + } if let method = fromPluginMap["method"] as? String { httpMethod = method diff --git a/ios/Storyboards/WebView.storyboard b/ios/Storyboards/WebView.storyboard index 8b733683..9c71b050 100755 --- a/ios/Storyboards/WebView.storyboard +++ b/ios/Storyboards/WebView.storyboard @@ -1,9 +1,9 @@ - + - + diff --git a/lib/src/types/url_request.dart b/lib/src/types/url_request.dart index 74e29c54..3d76ea6f 100644 --- a/lib/src/types/url_request.dart +++ b/lib/src/types/url_request.dart @@ -4,7 +4,7 @@ import 'url_request_network_service_type.dart'; ///A URL load request that is independent of protocol or URL scheme. class URLRequest { - ///The URL of the request. + ///The URL of the request. Setting this to `null` will load `about:blank`. Uri? url; ///The HTTP request method.