diff --git a/CHANGELOG.md b/CHANGELOG.md index 20038965..7aaa09ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.3.9+1 + +- Fixed error methods on iOS + # 0.3.9 - Fixed error methods on iOS diff --git a/android/src/main/java/com/flutter_webview_plugin/FlutterWebviewPlugin.java b/android/src/main/java/com/flutter_webview_plugin/FlutterWebviewPlugin.java index cc47009b..6cc198da 100644 --- a/android/src/main/java/com/flutter_webview_plugin/FlutterWebviewPlugin.java +++ b/android/src/main/java/com/flutter_webview_plugin/FlutterWebviewPlugin.java @@ -6,6 +6,7 @@ import android.content.Intent; import android.graphics.Point; import android.view.Display; +import android.webkit.WebStorage; import android.widget.FrameLayout; import android.webkit.CookieManager; import android.webkit.ValueCallback; @@ -90,12 +91,21 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { case "canGoForward": canGoForward(result); break; + case "cleanCache": + cleanCache(result); + break; default: result.notImplemented(); break; } } + private void cleanCache(MethodChannel.Result result) { + webViewManager.cleanCache(); + WebStorage.getInstance().deleteAllData(); + result.success(null); + } + void openUrl(MethodCall call, MethodChannel.Result result) { boolean hidden = call.argument("hidden"); String url = call.argument("url"); diff --git a/android/src/main/java/com/flutter_webview_plugin/WebviewManager.java b/android/src/main/java/com/flutter_webview_plugin/WebviewManager.java index 081aaef3..34124c7b 100644 --- a/android/src/main/java/com/flutter_webview_plugin/WebviewManager.java +++ b/android/src/main/java/com/flutter_webview_plugin/WebviewManager.java @@ -509,6 +509,13 @@ boolean canGoForward() { return webView.canGoForward(); } + /** + * Clears cache + */ + void cleanCache(){ + webView.clearCache(true); + } + void hide(MethodCall call, MethodChannel.Result result) { if (webView != null) { webView.setVisibility(View.GONE); diff --git a/ios/Classes/FlutterWebviewPlugin.m b/ios/Classes/FlutterWebviewPlugin.m index 3c5aee45..951b0c38 100644 --- a/ios/Classes/FlutterWebviewPlugin.m +++ b/ios/Classes/FlutterWebviewPlugin.m @@ -1,5 +1,5 @@ #import "FlutterWebviewPlugin.h" -#import "JavaScriptChannelHandler.h" +#import "WebviewJavaScriptChannelHandler.h" static NSString *const CHANNEL_NAME = @"flutter_webview_plugin"; @@ -20,7 +20,7 @@ + (void)registerWithRegistrar:(NSObject*)registrar { UIViewController *viewController = [UIApplication sharedApplication].delegate.window.rootViewController; FlutterWebviewPlugin* instance = [[FlutterWebviewPlugin alloc] initWithViewController:viewController]; - + [registrar addMethodCallDelegate:instance channel:channel]; } @@ -35,7 +35,7 @@ - (instancetype)initWithViewController:(UIViewController *)viewController { - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { if ([@"launch" isEqualToString:call.method]) { if (!self.webview) - [self initWebview:call]; + [self initWebview:call withResult:result]; else [self navigate:call]; result(nil); @@ -62,8 +62,7 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { [self stopLoading]; result(nil); } else if ([@"cleanCookies" isEqualToString:call.method]) { - [self cleanCookies]; - result(nil); + [self cleanCookies:result]; } else if ([@"back" isEqualToString:call.method]) { [self back]; result(nil); @@ -77,12 +76,14 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { [self onCanGoBack:call result:result]; } else if ([@"canGoForward" isEqualToString:call.method]) { [self onCanGoForward:call result:result]; + } else if ([@"cleanCache" isEqualToString:call.method]) { + [self cleanCache:result]; } else { result(FlutterMethodNotImplemented); } } -- (void)initWebview:(FlutterMethodCall*)call { +- (void)initWebview:(FlutterMethodCall*)call withResult:(FlutterResult)result { NSNumber *clearCache = call.arguments[@"clearCache"]; NSNumber *clearCookies = call.arguments[@"clearCookies"]; NSNumber *hidden = call.arguments[@"hidden"]; @@ -105,6 +106,8 @@ - (void)initWebview:(FlutterMethodCall*)call { if (clearCache != (id)[NSNull null] && [clearCache boolValue]) { [[NSURLCache sharedURLCache] removeAllCachedResponses]; + [self cleanCache:result]; + } if (clearCookies != (id)[NSNull null] && [clearCookies boolValue]) { @@ -113,6 +116,9 @@ - (void)initWebview:(FlutterMethodCall*)call { { [storage deleteCookie:cookie]; } + + [self cleanCookies:result]; + } if (userAgent != (id)[NSNull null]) { @@ -256,12 +262,45 @@ - (void)reloadUrl:(FlutterMethodCall*)call { } } -- (void)cleanCookies { +- (void)cleanCookies:(FlutterResult)result { if(self.webview != nil) { - NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; - for (NSHTTPCookie *cookie in [storage cookies]) - { - [storage deleteCookie:cookie]; + [[NSURLSession sharedSession] resetWithCompletionHandler:^{ + }]; + if (@available(iOS 9.0, *)) { + NSSet *websiteDataTypes = [NSSet setWithObject:WKWebsiteDataTypeCookies]; + WKWebsiteDataStore *dataStore = [WKWebsiteDataStore defaultDataStore]; + + void (^deleteAndNotify)(NSArray *) = + ^(NSArray *cookies) { + [dataStore removeDataOfTypes:websiteDataTypes + forDataRecords:cookies + completionHandler:^{ + result(nil); + }]; + }; + + [dataStore fetchDataRecordsOfTypes:websiteDataTypes completionHandler:deleteAndNotify]; + } else { + // support for iOS8 tracked in https://github.com/flutter/flutter/issues/27624. + NSLog(@"Clearing cookies is not supported for Flutter WebViews prior to iOS 9."); + } + } +} + +- (void)cleanCache:(FlutterResult)result { + if (self.webview != nil) { + if (@available(iOS 9.0, *)) { + NSSet* cacheDataTypes = [WKWebsiteDataStore allWebsiteDataTypes]; + WKWebsiteDataStore* dataStore = [WKWebsiteDataStore defaultDataStore]; + NSDate* dateFrom = [NSDate dateWithTimeIntervalSince1970:0]; + [dataStore removeDataOfTypes:cacheDataTypes + modifiedSince:dateFrom + completionHandler:^{ + result(nil); + }]; + } else { + // support for iOS8 tracked in https://github.com/flutter/flutter/issues/27624. + NSLog(@"Clearing cache is not supported for Flutter WebViews prior to iOS 9."); } } } @@ -311,7 +350,7 @@ - (void)reload { - (bool)checkInvalidUrl:(NSURL*)url { NSString* urlString = url != nil ? [url absoluteString] : nil; - if (_invalidUrlRegex != [NSNull null] && urlString != nil) { + if (![_invalidUrlRegex isEqual:[NSNull null]] && urlString != nil) { NSError* error = NULL; NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:_invalidUrlRegex @@ -331,10 +370,10 @@ - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigati decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { BOOL isInvalid = [self checkInvalidUrl: navigationAction.request.URL]; - + id data = @{@"url": navigationAction.request.URL.absoluteString, @"type": isInvalid ? @"abortLoad" : @"shouldStart", - @"navigationType": [NSNumber numberWithInt:navigationAction.navigationType]}; + @"navigationType": [NSNumber numberWithInteger:navigationAction.navigationType]}; [channel invokeMethod:@"onState" arguments:data]; if (navigationAction.navigationType == WKNavigationTypeBackForward) { @@ -401,8 +440,8 @@ - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNaviga - (void)registerJavaScriptChannels:(NSSet*)channelNames controller:(WKUserContentController*)userContentController { for (NSString* channelName in channelNames) { - FLTJavaScriptChannel* _channel = - [[FLTJavaScriptChannel alloc] initWithMethodChannel: channel + FLTCommunityJavaScriptChannel* _channel = + [[FLTCommunityJavaScriptChannel alloc] initWithMethodChannel: channel javaScriptChannelName:channelName]; [userContentController addScriptMessageHandler:_channel name:channelName]; NSString* wrapperSource = [NSString diff --git a/ios/Classes/JavaScriptChannelHandler.h b/ios/Classes/WebviewJavaScriptChannelHandler.h similarity index 84% rename from ios/Classes/JavaScriptChannelHandler.h rename to ios/Classes/WebviewJavaScriptChannelHandler.h index 1e0a9f2f..1b13cddc 100755 --- a/ios/Classes/JavaScriptChannelHandler.h +++ b/ios/Classes/WebviewJavaScriptChannelHandler.h @@ -7,7 +7,7 @@ NS_ASSUME_NONNULL_BEGIN -@interface FLTJavaScriptChannel : NSObject +@interface FLTCommunityJavaScriptChannel : NSObject - (instancetype)initWithMethodChannel:(FlutterMethodChannel*)methodChannel javaScriptChannelName:(NSString*)javaScriptChannelName; diff --git a/ios/Classes/JavaScriptChannelHandler.m b/ios/Classes/WebviewJavaScriptChannelHandler.m similarity index 93% rename from ios/Classes/JavaScriptChannelHandler.m rename to ios/Classes/WebviewJavaScriptChannelHandler.m index 5bafd8c7..573e1752 100755 --- a/ios/Classes/JavaScriptChannelHandler.m +++ b/ios/Classes/WebviewJavaScriptChannelHandler.m @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "JavaScriptChannelHandler.h" +#import "WebviewJavaScriptChannelHandler.h" -@implementation FLTJavaScriptChannel { +@implementation FLTCommunityJavaScriptChannel { FlutterMethodChannel* _methodChannel; NSString* _javaScriptChannelName; } diff --git a/lib/src/base.dart b/lib/src/base.dart index a7edace6..d83292ed 100644 --- a/lib/src/base.dart +++ b/lib/src/base.dart @@ -254,6 +254,9 @@ class FlutterWebviewPlugin { // Shows the webview Future show() async => await _channel.invokeMethod('show'); + // Clears browser cache + Future clearCache() async => await _channel.invokeMethod('cleanCache'); + // Reload webview with a url Future reloadUrl(String url, {Map headers}) async { final args = {'url': url}; diff --git a/pubspec.yaml b/pubspec.yaml index 0fd0d2aa..63282e12 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,7 +7,7 @@ authors: - Simon Lightfoot - Rafal Wachol homepage: https://github.com/dart-flitter/flutter_webview_plugin -version: 0.3.9 +version: 0.3.9+1 maintainer: Rafal Wachol (@RafalWachol) environment: