updated onLoadResource method, InAppBrowser.open url parameter has the default value: 'about:blank'
This commit is contained in:
parent
d696ed1e68
commit
b4e3e73bce
|
@ -16,18 +16,13 @@
|
|||
<component name="ChangeListManager">
|
||||
<list default="true" id="9b41f7a2-a71e-4923-91fb-249d7815b3e7" name="Default" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/android/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/android/build.gradle" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebViewClient.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebViewClient.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/Runner.xcodeproj/project.pbxproj" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Runner.xcodeproj/project.pbxproj" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/ios/Runner/WebView.storyboard" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Runner/WebView.storyboard" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/example/lib/main.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/main.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ios/Classes/InAppBrowserOptions.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/InAppBrowserOptions.swift" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ios/Classes/InAppBrowserWebViewController.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/InAppBrowserWebViewController.swift" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ios/Classes/MyURLProtocol.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/MyURLProtocol.swift" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/pubspec.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/pubspec.yaml" afterDir="false" />
|
||||
</list>
|
||||
<ignored path="$PROJECT_DIR$/.dart_tool/" />
|
||||
<ignored path="$PROJECT_DIR$/.idea/" />
|
||||
|
@ -44,11 +39,14 @@
|
|||
</component>
|
||||
<component name="FileEditorManager">
|
||||
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
|
||||
<file leaf-file-name="flutter_inappbrowser.dart" pinned="false" current-in-tab="true">
|
||||
<file leaf-file-name="flutter_inappbrowser.dart" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="358">
|
||||
<caret line="262" column="75" selection-start-line="262" selection-start-column="75" selection-end-line="262" selection-end-column="75" />
|
||||
<state relative-caret-position="315">
|
||||
<caret line="246" column="71" selection-start-line="246" selection-start-column="71" selection-end-line="246" selection-end-column="71" />
|
||||
<folding>
|
||||
<element signature="e#814#834#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
|
@ -97,11 +95,11 @@
|
|||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="main.dart" pinned="false" current-in-tab="false">
|
||||
<file leaf-file-name="main.dart" pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="200">
|
||||
<caret line="74" column="60" selection-start-line="74" selection-start-column="54" selection-end-line="74" selection-end-column="60" />
|
||||
<state relative-caret-position="537">
|
||||
<caret line="140" column="44" selection-start-line="140" selection-start-column="44" selection-end-line="140" selection-end-column="64" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
|
@ -182,12 +180,12 @@
|
|||
<option value="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowser.java" />
|
||||
<option value="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" />
|
||||
<option value="$PROJECT_DIR$/example/ios/Podfile" />
|
||||
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
||||
<option value="$PROJECT_DIR$/CHANGELOG.md" />
|
||||
<option value="$PROJECT_DIR$/README.md" />
|
||||
<option value="$PROJECT_DIR$/android/build.gradle" />
|
||||
<option value="$PROJECT_DIR$/example/lib/main.dart" />
|
||||
<option value="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" />
|
||||
<option value="$PROJECT_DIR$/pubspec.yaml" />
|
||||
<option value="$PROJECT_DIR$/example/lib/main.dart" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
|
@ -203,8 +201,19 @@
|
|||
<foldersAlwaysOnTop value="true" />
|
||||
</navigator>
|
||||
<panes>
|
||||
<pane id="PackagesPane" />
|
||||
<pane id="AndroidView" />
|
||||
<pane id="Scope">
|
||||
<subPane subId="Project Files">
|
||||
<expand>
|
||||
<path>
|
||||
<item name="Root" type="cbb8eebc:String" user="Root" />
|
||||
<item name="flutter_inappbrowser" type="cbb8eebc:String" user="flutter_inappbrowser" />
|
||||
</path>
|
||||
</expand>
|
||||
<select />
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="PackagesPane" />
|
||||
<pane id="ProjectPane">
|
||||
<subPane>
|
||||
<expand>
|
||||
|
@ -232,17 +241,6 @@
|
|||
</subPane>
|
||||
<option name="show-excluded-files" value="false" />
|
||||
</pane>
|
||||
<pane id="Scope">
|
||||
<subPane subId="Project Files">
|
||||
<expand>
|
||||
<path>
|
||||
<item name="Root" type="cbb8eebc:String" user="Root" />
|
||||
<item name="flutter_inappbrowser" type="cbb8eebc:String" user="flutter_inappbrowser" />
|
||||
</path>
|
||||
</expand>
|
||||
<select />
|
||||
</subPane>
|
||||
</pane>
|
||||
</panes>
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
|
@ -403,15 +401,16 @@
|
|||
<layout>
|
||||
<window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" />
|
||||
<window_info anchor="bottom" id="TODO" order="6" />
|
||||
<window_info anchor="bottom" id="Messages" order="12" weight="0.2370452" />
|
||||
<window_info anchor="right" id="Palette	" order="3" />
|
||||
<window_info id="Image Layers" order="2" />
|
||||
<window_info id="Build Variants" order="2" side_tool="true" />
|
||||
<window_info anchor="right" id="Capture Analysis" order="3" />
|
||||
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.50316054" side_tool="true" weight="0.32083333" />
|
||||
<window_info anchor="bottom" id="Dart Analysis" order="14" weight="0.3290735" />
|
||||
<window_info active="true" anchor="bottom" id="Run" order="2" sideWeight="0.49683943" visible="true" weight="0.39801544" />
|
||||
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.5035553" side_tool="true" weight="0.25689086" />
|
||||
<window_info anchor="bottom" id="Dart Analysis" order="14" weight="0.32855567" />
|
||||
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49644473" weight="0.39801544" />
|
||||
<window_info anchor="bottom" id="Version Control" order="9" />
|
||||
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.4973545" weight="0.25689086" />
|
||||
<window_info active="true" anchor="bottom" id="Terminal" order="10" sideWeight="0.49644473" visible="true" weight="0.25689086" />
|
||||
<window_info anchor="right" id="Flutter Outline" order="3" weight="0.32922077" />
|
||||
<window_info anchor="bottom" id="Logcat" order="11" />
|
||||
<window_info id="Captures" order="2" weight="0.32936507" />
|
||||
|
@ -424,7 +423,6 @@
|
|||
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
||||
<window_info id="Favorites" order="2" side_tool="true" />
|
||||
<window_info anchor="right" id="Flutter Inspector" order="3" weight="0.32987013" />
|
||||
<window_info anchor="bottom" id="Messages" order="12" visible="true" weight="0.2370452" />
|
||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||
<window_info anchor="right" id="Commander" order="0" weight="0.4" />
|
||||
<window_info anchor="right" id="Assistant" order="4" visible="true" weight="0.32987013" />
|
||||
|
@ -439,7 +437,6 @@
|
|||
<window_info id="Designer" order="4" />
|
||||
<window_info anchor="bottom" id="Dart Analysis" order="14" weight="0.3290735" />
|
||||
<window_info id="Build Variants" order="2" side_tool="true" />
|
||||
<window_info id="Image Layers" order="5" />
|
||||
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.4973545" weight="0.32161874" />
|
||||
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
||||
|
@ -451,21 +448,22 @@
|
|||
<window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" />
|
||||
<window_info anchor="right" id="Commander" order="0" weight="0.4" />
|
||||
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.5026455" side_tool="true" weight="0.31735888" />
|
||||
<window_info anchor="bottom" id="TODO" order="6" />
|
||||
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
||||
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.18376623" />
|
||||
<window_info anchor="right" id="Device File Explorer" order="4" side_tool="true" />
|
||||
<window_info anchor="right" id="Flutter Outline" order="3" weight="0.32936507" />
|
||||
<window_info anchor="bottom" id="Logcat" order="11" />
|
||||
<window_info anchor="bottom" id="Dependency Viewer" order="13" weight="0.32800853" />
|
||||
<window_info anchor="bottom" id="Version Control" order="9" />
|
||||
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.4973545" visible="true" weight="0.27888888" />
|
||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.18376623" />
|
||||
<window_info anchor="bottom" id="Messages" order="12" weight="0.23777778" />
|
||||
<window_info anchor="bottom" id="Message" order="0" />
|
||||
<window_info anchor="bottom" id="TODO" order="6" />
|
||||
<window_info id="Image Layers" order="5" />
|
||||
<window_info anchor="right" id="Palette	" order="5" />
|
||||
<window_info anchor="right" id="Theme Preview" order="7" />
|
||||
<window_info id="Structure" order="1" weight="0.24969475" />
|
||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||
<window_info anchor="bottom" id="Find" order="1" weight="0.3290735" />
|
||||
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
||||
</layout-to-restore>
|
||||
|
@ -667,13 +665,6 @@
|
|||
<state relative-caret-position="-10645" />
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="14" selection-start-line="2" selection-start-column="14" selection-end-line="2" selection-end-column="14" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/ios/flutter_inappbrowser.podspec">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="240">
|
||||
|
@ -682,6 +673,11 @@
|
|||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/README.md">
|
||||
<provider editor-type-id="text-editor">
|
||||
<state relative-caret-position="247">
|
||||
<caret line="19" column="15" selection-start-line="19" selection-start-column="3" selection-end-line="19" selection-end-column="15" />
|
||||
</state>
|
||||
</provider>
|
||||
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
|
||||
<state split_layout="SPLIT">
|
||||
<first_editor relative-caret-position="2820">
|
||||
|
@ -692,13 +688,13 @@
|
|||
</second_editor>
|
||||
</state>
|
||||
</provider>
|
||||
<provider editor-type-id="text-editor">
|
||||
<state relative-caret-position="247">
|
||||
<caret line="19" column="15" selection-start-line="19" selection-start-column="3" selection-end-line="19" selection-end-column="15" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
|
||||
<provider editor-type-id="text-editor">
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="69" lean-forward="true" selection-start-line="2" selection-start-column="2" selection-end-line="2" selection-end-column="73" />
|
||||
</state>
|
||||
</provider>
|
||||
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
|
||||
<state split_layout="SPLIT">
|
||||
<first_editor />
|
||||
|
@ -707,11 +703,6 @@
|
|||
</second_editor>
|
||||
</state>
|
||||
</provider>
|
||||
<provider editor-type-id="text-editor">
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="69" lean-forward="true" selection-start-line="2" selection-start-column="2" selection-end-line="2" selection-end-column="73" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/android/settings.gradle">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
|
@ -730,13 +721,6 @@
|
|||
<state />
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/android/build.gradle">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="262">
|
||||
<caret line="34" column="5" selection-start-line="34" selection-start-column="5" selection-end-line="34" selection-end-column="5" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/flutter/bin/cache/pkg/sky_engine/lib/core/string.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="173">
|
||||
|
@ -744,17 +728,34 @@
|
|||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
||||
<entry file="file://$PROJECT_DIR$/android/build.gradle">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="200">
|
||||
<caret line="74" column="60" selection-start-line="74" selection-start-column="54" selection-end-line="74" selection-end-column="60" />
|
||||
<state relative-caret-position="262">
|
||||
<caret line="34" column="5" selection-start-line="34" selection-start-column="5" selection-end-line="34" selection-end-column="5" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="30">
|
||||
<caret line="2" column="14" selection-start-line="2" selection-start-column="14" selection-end-line="2" selection-end-column="14" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="358">
|
||||
<caret line="262" column="75" selection-start-line="262" selection-start-column="75" selection-end-line="262" selection-end-column="75" />
|
||||
<state relative-caret-position="315">
|
||||
<caret line="246" column="71" selection-start-line="246" selection-start-column="71" selection-end-line="246" selection-end-column="71" />
|
||||
<folding>
|
||||
<element signature="e#814#834#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="537">
|
||||
<caret line="140" column="44" selection-start-line="140" selection-start-column="44" selection-end-line="140" selection-end-column="64" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
|
|
|
@ -1,37 +1,28 @@
|
|||
package com.pichillilorenzo.flutter_inappbrowser;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.net.http.SslError;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.webkit.CookieManager;
|
||||
import android.webkit.CookieSyncManager;
|
||||
import android.webkit.HttpAuthHandler;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.webkit.SslErrorHandler;
|
||||
import android.webkit.WebResourceRequest;
|
||||
import android.webkit.WebResourceResponse;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
|
@ -278,28 +269,55 @@ public class InAppBrowserWebViewClient extends WebViewClient {
|
|||
Request mRequest = new Request.Builder().url(url).build();
|
||||
|
||||
try {
|
||||
long loadingTime = System.currentTimeMillis();
|
||||
Response response = activity.httpClient.newCall(mRequest).execute();
|
||||
loadingTime = System.currentTimeMillis() - loadingTime;
|
||||
|
||||
String reasonPhrase = response.message();
|
||||
if (reasonPhrase.equals("")) {
|
||||
reasonPhrase = statusCodeMapping.get(response.code());
|
||||
Log.d(LOG_TAG, reasonPhrase);
|
||||
}
|
||||
reasonPhrase = (reasonPhrase.equals("") || reasonPhrase == null) ? "OK" : reasonPhrase;
|
||||
|
||||
Map<String, String> headers = new HashMap<String, String>();
|
||||
Map<String, String> headersResponse = new HashMap<String, String>();
|
||||
for (Map.Entry<String, List<String>> entry : response.headers().toMultimap().entrySet()) {
|
||||
String value = "";
|
||||
for (String val: entry.getValue()) {
|
||||
value += (value == "") ? val : "; " + val;
|
||||
}
|
||||
headers.put(entry.getKey().toLowerCase(), value);
|
||||
headersResponse.put(entry.getKey().toLowerCase(), value);
|
||||
}
|
||||
|
||||
Map<String, String> headersRequest = new HashMap<String, String>();
|
||||
for (Map.Entry<String, List<String>> entry : mRequest.headers().toMultimap().entrySet()) {
|
||||
String value = "";
|
||||
for (String val: entry.getValue()) {
|
||||
value += (value == "") ? val : "; " + val;
|
||||
}
|
||||
headersRequest.put(entry.getKey().toLowerCase(), value);
|
||||
}
|
||||
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
Map<String, Object> res = new HashMap<>();
|
||||
Map<String, Object> req = new HashMap<>();
|
||||
|
||||
obj.put("uuid", activity.uuid);
|
||||
obj.put("url", url);
|
||||
obj.put("statusCode", response.code());
|
||||
obj.put("headers", headers);
|
||||
|
||||
byte[] dataBytes = response.body().bytes();
|
||||
InputStream dataStream = new ByteArrayInputStream(dataBytes);
|
||||
|
||||
res.put("url", url);
|
||||
res.put("statusCode", response.code());
|
||||
res.put("headers", headersResponse);
|
||||
res.put("loadingTime", loadingTime);
|
||||
res.put("data", dataBytes);
|
||||
|
||||
req.put("url", url);
|
||||
req.put("headers", headersRequest);
|
||||
req.put("method", mRequest.method());
|
||||
|
||||
obj.put("response", res);
|
||||
obj.put("request", req);
|
||||
|
||||
InAppBrowserFlutterPlugin.channel.invokeMethod("onLoadResource", obj);
|
||||
|
||||
|
@ -308,8 +326,8 @@ public class InAppBrowserWebViewClient extends WebViewClient {
|
|||
response.header("content-encoding"),
|
||||
response.code(),
|
||||
reasonPhrase,
|
||||
headers,
|
||||
response.body().byteStream()
|
||||
headersResponse,
|
||||
dataStream
|
||||
);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -72,10 +72,10 @@ class MyInAppBrowser extends InAppBrowser {
|
|||
}
|
||||
|
||||
@override
|
||||
void onLoadResource(String url, int statusCode, Map<String, String> headers) {
|
||||
print("\n\n resource: $url\n\n");
|
||||
print(statusCode);
|
||||
print(headers);
|
||||
void onLoadResource(WebResourceResponse response, WebResourceRequest request) {
|
||||
print(response.loadingTime.toString() + "ms " + response.url);
|
||||
if (response.headers["content-length"] != null)
|
||||
print(response.headers["content-length"] + " length");
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -138,7 +138,7 @@ class _MyAppState extends State<MyApp> {
|
|||
body: new Center(
|
||||
child: new RaisedButton(onPressed: () {
|
||||
//chromeSafariBrowser.open("https://flutter.io/");
|
||||
inAppBrowserFallback.open("https://flutter.io/", options: {
|
||||
inAppBrowserFallback.open(url: "https://flutter.io/", options: {
|
||||
//"hidden": true,
|
||||
//"toolbarTopFixedTitle": "Fixed title",
|
||||
//"useShouldOverrideUrlLoading": true
|
||||
|
|
|
@ -131,13 +131,8 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
|
|||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
URLProtocol.wk_registerScheme("http")
|
||||
URLProtocol.wk_registerScheme("https")
|
||||
|
||||
MyURLProtocol.URLProtocolDelegate = self
|
||||
|
||||
URLProtocol.registerClass(MyURLProtocol.self)
|
||||
|
||||
MyURLProtocol.wkWebViewDelegateMap[uuid] = self
|
||||
|
||||
webView.uiDelegate = self
|
||||
webView.navigationDelegate = self
|
||||
|
@ -303,8 +298,21 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
|
|||
if ((browserOptions?.userAgent)! != "") {
|
||||
if #available(iOS 9.0, *) {
|
||||
self.webView.customUserAgent = (browserOptions?.userAgent)!
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
}
|
||||
|
||||
// set uuid in the User-Agent in order to know which webview is making internal requests and
|
||||
// to send the onLoadResource event to the correct webview
|
||||
if #available(iOS 9.0, *) {
|
||||
if (self.webView.customUserAgent != nil) {
|
||||
self.webView.customUserAgent = self.webView.customUserAgent! + " WKWebView/" + self.uuid
|
||||
}
|
||||
else {
|
||||
self.webView.evaluateJavaScript("navigator.userAgent") { [weak webView] (result, error) in
|
||||
if let webView = self.webView, let userAgent = result as? String {
|
||||
webView.customUserAgent = userAgent + " WKWebView/" + self.uuid
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -491,7 +499,6 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
|
|||
func webView(_ webView: WKWebView,
|
||||
decidePolicyFor navigationResponse: WKNavigationResponse,
|
||||
decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
|
||||
|
||||
//dump((navigationResponse.response as! HTTPURLResponse))
|
||||
//print(navigationResponse.response.mimeType)
|
||||
//print(navigationResponse.response.url)
|
||||
|
@ -569,8 +576,8 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
|
|||
navigationDelegate?.onLoadError(uuid: self.uuid, webView: webView, error: error)
|
||||
}
|
||||
|
||||
func didReceiveResponse(_ response: URLResponse, from request: URLRequest?) {
|
||||
navigationDelegate?.onLoadResource(uuid: self.uuid, webView: webView, response: response)
|
||||
func didReceiveResponse(_ response: URLResponse, fromRequest request: URLRequest?, withData data: Data, loadingTime time: Int) {
|
||||
navigationDelegate?.onLoadResource(uuid: self.uuid, webView: webView, response: response, fromRequest: request, withData: data, loadingTime: time)
|
||||
}
|
||||
|
||||
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
||||
|
|
|
@ -6,29 +6,47 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import WebKit
|
||||
|
||||
|
||||
func currentTimeInMilliSeconds() -> Int {
|
||||
let currentDate = Date()
|
||||
let since1970 = currentDate.timeIntervalSince1970
|
||||
return Int(since1970 * 1000)
|
||||
}
|
||||
|
||||
class MyURLProtocol: URLProtocol {
|
||||
|
||||
struct Constants {
|
||||
static let RequestHandledKey = "URLProtocolRequestHandled"
|
||||
}
|
||||
// struct Constants {
|
||||
// static let RequestHandledKey = "URLProtocolRequestHandled"
|
||||
// }
|
||||
|
||||
var wkWebViewUuid: String?
|
||||
var session: URLSession?
|
||||
var sessionTask: URLSessionDataTask?
|
||||
static var URLProtocolDelegate: MyURLProtocolDelegate?
|
||||
var response: URLResponse?
|
||||
var data: Data?
|
||||
static var wkWebViewDelegateMap: [String: MyURLProtocolDelegate] = [:]
|
||||
var loadingTime: Int = 0
|
||||
|
||||
override init(request: URLRequest, cachedResponse: CachedURLResponse?, client: URLProtocolClient?) {
|
||||
super.init(request: request, cachedResponse: cachedResponse, client: client)
|
||||
|
||||
if session == nil {
|
||||
self.wkWebViewUuid = MyURLProtocol.getUuid(request)
|
||||
|
||||
if session == nil && self.wkWebViewUuid != nil {
|
||||
session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
|
||||
}
|
||||
}
|
||||
|
||||
override class func canInit(with request: URLRequest) -> Bool {
|
||||
if MyURLProtocol.property(forKey: Constants.RequestHandledKey, in: request) != nil {
|
||||
|
||||
if getUuid(request) == nil {
|
||||
return false
|
||||
}
|
||||
// if MyURLProtocol.property(forKey: Constants.RequestHandledKey, in: request) != nil {
|
||||
// return false
|
||||
// }
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -38,25 +56,54 @@ class MyURLProtocol: URLProtocol {
|
|||
|
||||
override func startLoading() {
|
||||
let newRequest = ((request as NSURLRequest).mutableCopy() as? NSMutableURLRequest)!
|
||||
MyURLProtocol.setProperty(true, forKey: Constants.RequestHandledKey, in: newRequest)
|
||||
loadingTime = currentTimeInMilliSeconds()
|
||||
//MyURLProtocol.setProperty(true, forKey: Constants.RequestHandledKey, in: newRequest)
|
||||
sessionTask = session?.dataTask(with: newRequest as URLRequest)
|
||||
sessionTask?.resume()
|
||||
}
|
||||
|
||||
override func stopLoading() {
|
||||
if let uuid = self.wkWebViewUuid {
|
||||
if MyURLProtocol.wkWebViewDelegateMap[uuid] != nil && self.response != nil {
|
||||
loadingTime = currentTimeInMilliSeconds() - loadingTime
|
||||
if self.data == nil {
|
||||
self.data = Data()
|
||||
}
|
||||
MyURLProtocol.wkWebViewDelegateMap[uuid]!.didReceiveResponse(self.response!, fromRequest: request, withData: self.data!, loadingTime: loadingTime)
|
||||
}
|
||||
}
|
||||
|
||||
sessionTask?.cancel()
|
||||
}
|
||||
|
||||
class func getUuid(_ request: URLRequest?) -> String? {
|
||||
let userAgent: String? = request?.allHTTPHeaderFields?["User-Agent"]
|
||||
var uuid: String? = nil
|
||||
if userAgent != nil {
|
||||
if userAgent!.contains("WKWebView/") {
|
||||
let userAgentSplitted = userAgent!.split(separator: " ")
|
||||
uuid = String(userAgentSplitted[userAgentSplitted.count-1]).replacingOccurrences(of: "WKWebView/", with: "")
|
||||
}
|
||||
}
|
||||
return uuid
|
||||
}
|
||||
}
|
||||
|
||||
extension MyURLProtocol: URLSessionDataDelegate {
|
||||
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
|
||||
if self.data == nil {
|
||||
self.data = data
|
||||
}
|
||||
else {
|
||||
self.data!.append(data)
|
||||
}
|
||||
client?.urlProtocol(self, didLoad: data)
|
||||
}
|
||||
|
||||
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
|
||||
let policy = URLCache.StoragePolicy(rawValue: request.cachePolicy.rawValue) ?? .notAllowed
|
||||
self.response = response
|
||||
client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: policy)
|
||||
MyURLProtocol.URLProtocolDelegate?.didReceiveResponse(response, from: dataTask.currentRequest)
|
||||
completionHandler(.allow)
|
||||
}
|
||||
|
||||
|
@ -98,5 +145,5 @@ extension MyURLProtocol: URLSessionDataDelegate {
|
|||
}
|
||||
|
||||
protocol MyURLProtocolDelegate {
|
||||
func didReceiveResponse(_ response: URLResponse, from request: URLRequest?)
|
||||
func didReceiveResponse(_ response: URLResponse, fromRequest request: URLRequest?, withData data: Data, loadingTime time: Int)
|
||||
}
|
||||
|
|
|
@ -46,6 +46,9 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||
}
|
||||
|
||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||
URLProtocol.wk_registerScheme("http")
|
||||
URLProtocol.wk_registerScheme("https")
|
||||
URLProtocol.registerClass(MyURLProtocol.self)
|
||||
let channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappbrowser", binaryMessenger: registrar.messenger())
|
||||
let instance = SwiftFlutterPlugin(with: registrar)
|
||||
registrar.addMethodCallDelegate(instance, channel: channel)
|
||||
|
@ -489,16 +492,28 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
func onLoadResource(uuid: String, webView: WKWebView, response: URLResponse) {
|
||||
func onLoadResource(uuid: String, webView: WKWebView, response: URLResponse, fromRequest request: URLRequest?, withData data: Data, loadingTime time: Int) {
|
||||
if self.webViewControllers[uuid] != nil {
|
||||
var headers = (response as! HTTPURLResponse).allHeaderFields as! [String: String]
|
||||
headers.lowercaseKeys()
|
||||
var headersResponse = (response as! HTTPURLResponse).allHeaderFields as! [String: String]
|
||||
headersResponse.lowercaseKeys()
|
||||
|
||||
var headersRequest = request!.allHTTPHeaderFields! as [String: String]
|
||||
headersRequest.lowercaseKeys()
|
||||
|
||||
let arguments: [String : Any] = [
|
||||
"uuid": uuid,
|
||||
"url": response.url?.absoluteString ?? "",
|
||||
"statusCode": (response as! HTTPURLResponse).statusCode,
|
||||
"headers": headers
|
||||
"response": [
|
||||
"url": response.url!.absoluteString,
|
||||
"statusCode": (response as! HTTPURLResponse).statusCode,
|
||||
"headers": headersResponse,
|
||||
"loadingTime": time,
|
||||
"data": data
|
||||
],
|
||||
"request": [
|
||||
"url": request!.url!.absoluteString,
|
||||
"headers": headersRequest,
|
||||
"method": request!.httpMethod!
|
||||
]
|
||||
]
|
||||
channel.invokeMethod("onLoadResource", arguments: arguments)
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
@ -34,6 +35,28 @@ enum ConsoleMessageLevel {
|
|||
DEBUG, ERROR, LOG, TIP, WARNING
|
||||
}
|
||||
|
||||
class WebResourceRequest {
|
||||
|
||||
String url;
|
||||
Map<String, String> headers;
|
||||
String method;
|
||||
|
||||
WebResourceRequest(this.url, this.headers, this.method);
|
||||
|
||||
}
|
||||
|
||||
class WebResourceResponse {
|
||||
|
||||
String url;
|
||||
Map<String, String> headers;
|
||||
int statusCode;
|
||||
int loadingTime;
|
||||
Uint8List data;
|
||||
|
||||
WebResourceResponse(this.url, this.headers, this.statusCode, this.loadingTime, this.data);
|
||||
|
||||
}
|
||||
|
||||
///Public class representing a JavaScript console message from WebCore.
|
||||
///This could be a issued by a call to one of the console logging functions (e.g. console.log('...')) or a JavaScript error on the page.
|
||||
///
|
||||
|
@ -107,10 +130,27 @@ class InAppBrowser {
|
|||
shouldOverrideUrlLoading(url);
|
||||
break;
|
||||
case "onLoadResource":
|
||||
String url = call.arguments["url"];
|
||||
int statusCode = call.arguments["statusCode"];
|
||||
Map<dynamic, dynamic> headers = call.arguments["headers"];
|
||||
onLoadResource(url, statusCode, headers.cast<String, String>());
|
||||
Map<dynamic, dynamic> rawResponse = call.arguments["response"];
|
||||
rawResponse = rawResponse.cast<String, dynamic>();
|
||||
Map<dynamic, dynamic> rawRequest = call.arguments["request"];
|
||||
rawRequest = rawRequest.cast<String, dynamic>();
|
||||
|
||||
String urlResponse = rawResponse["url"];
|
||||
Map<dynamic, dynamic> headersResponse = rawResponse["headers"];
|
||||
headersResponse = headersResponse.cast<String, String>();
|
||||
int statusCode = rawResponse["statusCode"];
|
||||
int loadingTime = rawResponse["loadingTime"];
|
||||
Uint8List data = rawResponse["data"];
|
||||
|
||||
String urlRequest = rawRequest["url"];
|
||||
Map<dynamic, dynamic> headersRequest = rawRequest["headers"];
|
||||
headersRequest = headersResponse.cast<String, String>();
|
||||
String method = rawRequest["method"];
|
||||
|
||||
var response = new WebResourceResponse(urlResponse, headersResponse, statusCode, loadingTime, data);
|
||||
var request = new WebResourceRequest(urlRequest, headersRequest, method);
|
||||
|
||||
onLoadResource(response, request);
|
||||
break;
|
||||
case "onConsoleMessage":
|
||||
String sourceURL = call.arguments["sourceURL"];
|
||||
|
@ -187,7 +227,7 @@ class InAppBrowser {
|
|||
/// - __allowsInlineMediaPlayback__: Set to `true` to allow HTML5 media playback to appear inline within the screen layout, using browser-supplied controls rather than native controls. For this to work, add the `webkit-playsinline` attribute to any `<video>` elements. The default value is `false`.
|
||||
/// - __allowsPictureInPictureMediaPlayback__: Set to `true` to allow HTML5 videos play picture-in-picture. The default value is `true`.
|
||||
/// - __spinner__: Set to `false` to hide the spinner when the WebView is loading a page. The default value is `true`.
|
||||
Future<void> open(String url, {Map<String, String> headers = const {}, String target = "_self", Map<String, dynamic> options = const {}}) async {
|
||||
Future<void> open({String url = "about:blank", Map<String, String> headers = const {}, String target = "_self", Map<String, dynamic> options = const {}}) async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('uuid', () => uuid);
|
||||
args.putIfAbsent('url', () => url);
|
||||
|
@ -328,8 +368,8 @@ class InAppBrowser {
|
|||
|
||||
}
|
||||
|
||||
///Event fires when the [InAppBrowser] webview will load the resource specified by the given [url].
|
||||
void onLoadResource(String url, int statusCode, Map<String, String> headers) {
|
||||
///Event fires when the [InAppBrowser] webview will load the resource specified by the given [WebResourceRequest].
|
||||
void onLoadResource(WebResourceResponse response, WebResourceRequest request) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: flutter_inappbrowser
|
||||
description: A Flutter plugin that allows you to open an in-app browser window. (inspired by the popular cordova-plugin-inappbrowser).
|
||||
version: 0.2.1
|
||||
version: 0.3.0
|
||||
author: Lorenzo Pichilli <pichillilorenzo@gmail.com>
|
||||
homepage: https://github.com/pichillilorenzo/flutter_inappbrowser
|
||||
|
||||
|
|
Loading…
Reference in New Issue