fixed iOS nil exception on URLRequest url property, update some iOS classes to use ChannelDelegate class and Disposable protocol, added some more null checks on Android
This commit is contained in:
parent
92abeea57f
commit
88e89bd102
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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<Map>() {
|
||||
@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<Long>() {
|
||||
@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<Long>() {
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
@ -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";
|
||||
|
||||
|
@ -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<Integer, List<Runnable>> 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<Runnable> callbacks = actionDictionary.get(requestCode);
|
||||
for (Runnable runnable : callbacks) {
|
||||
runnable.run();
|
||||
callbacks.remove(runnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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";
|
||||
|
||||
|
@ -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";
|
||||
|
||||
|
@ -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<Map<String, Object>> allCredentials = new ArrayList<>();
|
||||
List<URLProtectionSpace> protectionSpaces = credentialDatabase.protectionSpaceDao.getAll();
|
||||
for (URLProtectionSpace protectionSpace : protectionSpaces) {
|
||||
List<Map<String, Object>> credentials = new ArrayList<>();
|
||||
for (URLCredential credential : credentialDatabase.credentialDao.getAllByProtectionSpaceId(protectionSpace.getId())) {
|
||||
credentials.add(credential.toMap());
|
||||
if (credentialDatabase != null) {
|
||||
List<URLProtectionSpace> protectionSpaces = credentialDatabase.protectionSpaceDao.getAll();
|
||||
for (URLProtectionSpace protectionSpace : protectionSpaces) {
|
||||
List<Map<String, Object>> credentials = new ArrayList<>();
|
||||
for (URLCredential credential : credentialDatabase.credentialDao.getAllByProtectionSpaceId(protectionSpace.getId())) {
|
||||
credentials.add(credential.toMap());
|
||||
}
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
obj.put("protectionSpace", protectionSpace.toMap());
|
||||
obj.put("credentials", credentials);
|
||||
allCredentials.add(obj);
|
||||
}
|
||||
Map<String, Object> 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<Map<String, Object>> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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";
|
||||
|
||||
|
@ -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";
|
||||
|
||||
|
@ -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";
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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<String, String> headers;
|
||||
|
||||
public URLRequest(@NonNull String url, @Nullable String method, @Nullable byte[] body, @Nullable Map<String, String> headers) {
|
||||
public URLRequest(@Nullable String url, @Nullable String method, @Nullable byte[] body, @Nullable Map<String, String> 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<String, String> headers = (Map<String, String>) 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);
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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) {
|
@ -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()
|
||||
|
@ -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?) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
90
ios/Classes/PullToRefresh/PullToRefreshChannelDelegate.swift
Normal file
90
ios/Classes/PullToRefresh/PullToRefreshChannelDelegate.swift
Normal file
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
27
ios/Classes/Types/ChannelDelegate.swift
Normal file
27
ios/Classes/Types/ChannelDelegate.swift
Normal file
@ -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
|
||||
}
|
||||
}
|
12
ios/Classes/Types/Disposable.swift
Normal file
12
ios/Classes/Types/Disposable.swift
Normal file
@ -0,0 +1,12 @@
|
||||
//
|
||||
// Disposable.swift
|
||||
// flutter_inappwebview
|
||||
//
|
||||
// Created by Lorenzo Pichilli on 04/05/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public protocol Disposable {
|
||||
func dispose() -> Void
|
||||
}
|
@ -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
|
||||
|
@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina5_5" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment version="2048" identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user