add
This commit is contained in:
8
Assets/3rd/unity-webview/Plugins/Android.meta
Normal file
8
Assets/3rd/unity-webview/Plugins/Android.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14692a49bcef749e0aa000d312acf3e5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
20
Assets/3rd/unity-webview/Plugins/Android/AndroidManifest.xml
Normal file
20
Assets/3rd/unity-webview/Plugins/Android/AndroidManifest.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tianrun.crm" xmlns:tools="http://schemas.android.com/tools" android:installLocation="preferExternal">
|
||||
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
|
||||
<!-- Android9.0对未加密的流量不在信任,添加了新的限制。usesCleartextTraffic=true -->
|
||||
<application android:theme="@style/UnityThemeSelector"
|
||||
android:icon="@mipmap/app_icon"
|
||||
android:label="@string/app_name"
|
||||
android:usesCleartextTraffic="true" >
|
||||
<activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="@string/app_name" android:screenOrientation="portrait" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" android:hardwareAccelerated="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
|
||||
</activity>
|
||||
</application>
|
||||
<uses-feature android:glEsVersion="0x00020000" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
</manifest>
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aade8c4f60eaf4f7fa5ad14dbd41d304
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/3rd/unity-webview/Plugins/Android/WebViewPlugin.jar
Normal file
BIN
Assets/3rd/unity-webview/Plugins/Android/WebViewPlugin.jar
Normal file
Binary file not shown.
@@ -0,0 +1,32 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 460c54fac240444c885c048022445d54
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/3rd/unity-webview/Plugins/Editor.meta
Normal file
8
Assets/3rd/unity-webview/Plugins/Editor.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f773ae6ed2a64622a62b105c9d42ed1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,210 @@
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using UnityEditor.Android;
|
||||
using UnityEditor.Callbacks;
|
||||
#if UNITY_IOS
|
||||
using UnityEditor.iOS.Xcode;
|
||||
#endif
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
public class UnityWebViewPostprocessBuild : IPostGenerateGradleAndroidProject
|
||||
#else
|
||||
public class UnityWebViewPostprocessBuild
|
||||
#endif
|
||||
{
|
||||
//// for android/unity 2018.1 or newer
|
||||
//// cf. https://forum.unity.com/threads/android-hardwareaccelerated-is-forced-false-in-all-activities.532786/
|
||||
//// cf. https://github.com/Over17/UnityAndroidManifestCallback
|
||||
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
public void OnPostGenerateGradleAndroidProject(string basePath) {
|
||||
var changed = false;
|
||||
var androidManifest = new AndroidManifest(GetManifestPath(basePath));
|
||||
changed = (androidManifest.SetHardwareAccelerated(true) || changed);
|
||||
#if UNITYWEBVIEW_ANDROID_ENABLE_CAMERA
|
||||
changed = (androidManifest.AddCamera() || changed);
|
||||
#endif
|
||||
#if UNITYWEBVIEW_ANDROID_ENABLE_MICROPHONE
|
||||
changed = (androidManifest.AddMicrophone() || changed);
|
||||
#endif
|
||||
if (changed) {
|
||||
androidManifest.Save();
|
||||
Debug.Log("unitywebview: adjusted AndroidManifest.xml.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public int callbackOrder {
|
||||
get {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetManifestPath(string basePath) {
|
||||
var pathBuilder = new StringBuilder(basePath);
|
||||
pathBuilder.Append(Path.DirectorySeparatorChar).Append("src");
|
||||
pathBuilder.Append(Path.DirectorySeparatorChar).Append("main");
|
||||
pathBuilder.Append(Path.DirectorySeparatorChar).Append("AndroidManifest.xml");
|
||||
return pathBuilder.ToString();
|
||||
}
|
||||
|
||||
//// for others
|
||||
|
||||
[PostProcessBuild(100)]
|
||||
public static void OnPostprocessBuild(BuildTarget buildTarget, string path) {
|
||||
#if !UNITY_2018_1_OR_NEWER
|
||||
if (buildTarget == BuildTarget.Android) {
|
||||
string manifest = Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml");
|
||||
if (!File.Exists(manifest)) {
|
||||
string manifest0 = Path.Combine(Application.dataPath, "../Temp/StagingArea/AndroidManifest-main.xml");
|
||||
if (!File.Exists(manifest0)) {
|
||||
Debug.LogError("unitywebview: cannot find both Assets/Plugins/Android/AndroidManifest.xml and Temp/StagingArea/AndroidManifest-main.xml. please build the app to generate Assets/Plugins/Android/AndroidManifest.xml and then rebuild it again.");
|
||||
return;
|
||||
} else {
|
||||
File.Copy(manifest0, manifest);
|
||||
}
|
||||
}
|
||||
var changed = false;
|
||||
var androidManifest = new AndroidManifest(manifest);
|
||||
changed = (androidManifest.SetHardwareAccelerated(true) || changed);
|
||||
#if UNITYWEBVIEW_ANDROID_ENABLE_CAMERA
|
||||
changed = (androidManifest.AddCamera() || changed);
|
||||
#endif
|
||||
#if UNITYWEBVIEW_ANDROID_ENABLE_MICROPHONE
|
||||
changed = (androidManifest.AddMicrophone() || changed);
|
||||
#endif
|
||||
#if UNITY_5_6_0 || UNITY_5_6_1
|
||||
changed = (androidManifest.SetActivityName("net.gree.unitywebview.CUnityPlayerActivity") || changed);
|
||||
#endif
|
||||
if (changed) {
|
||||
androidManifest.Save();
|
||||
Debug.LogError("unitywebview: adjusted AndroidManifest.xml. Please rebuild the app.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UNITY_IOS
|
||||
if (buildTarget == BuildTarget.iOS) {
|
||||
string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj";
|
||||
PBXProject proj = new PBXProject();
|
||||
proj.ReadFromString(File.ReadAllText(projPath));
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
proj.AddFrameworkToProject(proj.GetUnityFrameworkTargetGuid(), "WebKit.framework", false);
|
||||
#else
|
||||
proj.AddFrameworkToProject(proj.TargetGuidByName("Unity-iPhone"), "WebKit.framework", false);
|
||||
#endif
|
||||
File.WriteAllText(projPath, proj.WriteToString());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
internal class AndroidXmlDocument : XmlDocument {
|
||||
private string m_Path;
|
||||
protected XmlNamespaceManager nsMgr;
|
||||
public readonly string AndroidXmlNamespace = "http://schemas.android.com/apk/res/android";
|
||||
|
||||
public AndroidXmlDocument(string path) {
|
||||
m_Path = path;
|
||||
using (var reader = new XmlTextReader(m_Path)) {
|
||||
reader.Read();
|
||||
Load(reader);
|
||||
}
|
||||
nsMgr = new XmlNamespaceManager(NameTable);
|
||||
nsMgr.AddNamespace("android", AndroidXmlNamespace);
|
||||
}
|
||||
|
||||
public string Save() {
|
||||
return SaveAs(m_Path);
|
||||
}
|
||||
|
||||
public string SaveAs(string path) {
|
||||
using (var writer = new XmlTextWriter(path, new UTF8Encoding(false))) {
|
||||
writer.Formatting = Formatting.Indented;
|
||||
Save(writer);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
internal class AndroidManifest : AndroidXmlDocument {
|
||||
private readonly XmlElement ManifestElement;
|
||||
private readonly XmlElement ApplicationElement;
|
||||
|
||||
public AndroidManifest(string path) : base(path) {
|
||||
ManifestElement = SelectSingleNode("/manifest") as XmlElement;
|
||||
ApplicationElement = SelectSingleNode("/manifest/application") as XmlElement;
|
||||
}
|
||||
|
||||
private XmlAttribute CreateAndroidAttribute(string key, string value) {
|
||||
XmlAttribute attr = CreateAttribute("android", key, AndroidXmlNamespace);
|
||||
attr.Value = value;
|
||||
return attr;
|
||||
}
|
||||
|
||||
internal XmlNode GetActivityWithLaunchIntent() {
|
||||
return
|
||||
SelectSingleNode(
|
||||
"/manifest/application/activity[intent-filter/action/@android:name='android.intent.action.MAIN' and "
|
||||
+ "intent-filter/category/@android:name='android.intent.category.LAUNCHER']",
|
||||
nsMgr);
|
||||
}
|
||||
|
||||
internal bool SetHardwareAccelerated(bool enabled) {
|
||||
bool changed = false;
|
||||
var activity = GetActivityWithLaunchIntent() as XmlElement;
|
||||
if (activity.GetAttribute("hardwareAccelerated", AndroidXmlNamespace) != ((enabled) ? "true" : "false")) {
|
||||
activity.SetAttribute("hardwareAccelerated", AndroidXmlNamespace, (enabled) ? "true" : "false");
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
internal bool SetActivityName(string name) {
|
||||
bool changed = false;
|
||||
var activity = GetActivityWithLaunchIntent() as XmlElement;
|
||||
if (activity.GetAttribute("name", AndroidXmlNamespace) != name) {
|
||||
activity.SetAttribute("name", AndroidXmlNamespace, name);
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
internal bool AddCamera() {
|
||||
bool changed = false;
|
||||
if (SelectNodes("/manifest/uses-permission[@android:name='android.permission.CAMERA']", nsMgr).Count == 0) {
|
||||
var elem = CreateElement("uses-permission");
|
||||
elem.Attributes.Append(CreateAndroidAttribute("name", "android.permission.CAMERA"));
|
||||
ManifestElement.AppendChild(elem);
|
||||
changed = true;
|
||||
}
|
||||
if (SelectNodes("/manifest/uses-feature[@android:name='android.hardware.camera']", nsMgr).Count == 0) {
|
||||
var elem = CreateElement("uses-feature");
|
||||
elem.Attributes.Append(CreateAndroidAttribute("name", "android.hardware.camera"));
|
||||
ManifestElement.AppendChild(elem);
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
internal bool AddMicrophone() {
|
||||
bool changed = false;
|
||||
if (SelectNodes("/manifest/uses-permission[@android:name='android.permission.MICROPHONE']", nsMgr).Count == 0) {
|
||||
var elem = CreateElement("uses-permission");
|
||||
elem.Attributes.Append(CreateAndroidAttribute("name", "android.permission.MICROPHONE"));
|
||||
ManifestElement.AppendChild(elem);
|
||||
changed = true;
|
||||
}
|
||||
if (SelectNodes("/manifest/uses-feature[@android:name='android.hardware.microphone']", nsMgr).Count == 0) {
|
||||
var elem = CreateElement("uses-feature");
|
||||
elem.Attributes.Append(CreateAndroidAttribute("name", "android.hardware.microphone"));
|
||||
ManifestElement.AppendChild(elem);
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ba92d81cb1934840ab32949cebd6feb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
57
Assets/3rd/unity-webview/Plugins/WebView.bundle.meta
Normal file
57
Assets/3rd/unity-webview/Plugins/WebView.bundle.meta
Normal file
@@ -0,0 +1,57 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60e7bf38137eb4950b2f02b7d57c1ad3
|
||||
folderAsset: yes
|
||||
PluginImporter:
|
||||
serializedVersion: 1
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
isPreloaded: 0
|
||||
platformData:
|
||||
Android:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
Any:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
Editor:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: OSX
|
||||
Linux:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
Linux64:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86_64
|
||||
OSXIntel:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
OSXIntel64:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
OSXUniversal:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
Win:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
Win64:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
iOS:
|
||||
enabled: 0
|
||||
settings:
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1aef798ecf2b945a894fb4bb17b10f53
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>19E287</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>WebView</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>net.gree.unitywebview.WebView</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>WebView</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>11E608c</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>GM</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>19E258</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.15</string>
|
||||
<key>DTXcode</key>
|
||||
<string>1150</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>11E608c</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.7</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d8bb24d011b447b58e9ba755365cb0e
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 931d50791ac65423ead7757249c09c92
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/3rd/unity-webview/Plugins/WebView.bundle/Contents/MacOS/WebView
Executable file
BIN
Assets/3rd/unity-webview/Plugins/WebView.bundle/Contents/MacOS/WebView
Executable file
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee5ba59c0146b49a88f62aa0e9c1ab88
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13927301eb6884a57938bc30c8518343
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d405197ed59f4015860b82a0f9f5717
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96212f6c2b8a64b70a213184b0ef5316
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,132 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>files</key>
|
||||
<dict>
|
||||
<key>Resources/InfoPlist.strings</key>
|
||||
<data>
|
||||
MiLKDDnrUKr4EmuvhS5VQwxHGK8=
|
||||
</data>
|
||||
</dict>
|
||||
<key>files2</key>
|
||||
<dict>
|
||||
<key>Resources/InfoPlist.strings</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
MiLKDDnrUKr4EmuvhS5VQwxHGK8=
|
||||
</data>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
Oc8u4Ht7Mz58F50L9NeYpbcq9qTlhPUeZCcDu/pPyCg=
|
||||
</data>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>rules</key>
|
||||
<dict>
|
||||
<key>^Resources/</key>
|
||||
<true/>
|
||||
<key>^Resources/.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^Resources/.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^Resources/Base\.lproj/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>1010</real>
|
||||
</dict>
|
||||
<key>^version.plist$</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>rules2</key>
|
||||
<dict>
|
||||
<key>.*\.dSYM($|/)</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>11</real>
|
||||
</dict>
|
||||
<key>^(.*/)?\.DS_Store$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>2000</real>
|
||||
</dict>
|
||||
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
|
||||
<dict>
|
||||
<key>nested</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>10</real>
|
||||
</dict>
|
||||
<key>^.*</key>
|
||||
<true/>
|
||||
<key>^Info\.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^PkgInfo$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^Resources/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^Resources/.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^Resources/.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^Resources/Base\.lproj/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>1010</real>
|
||||
</dict>
|
||||
<key>^[^/]+$</key>
|
||||
<dict>
|
||||
<key>nested</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>10</real>
|
||||
</dict>
|
||||
<key>^embedded\.provisionprofile$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^version\.plist$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f9afbbf70a5bb4304a15cf99106eac7f
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1075
Assets/3rd/unity-webview/Plugins/WebViewObject.cs
Normal file
1075
Assets/3rd/unity-webview/Plugins/WebViewObject.cs
Normal file
File diff suppressed because it is too large
Load Diff
11
Assets/3rd/unity-webview/Plugins/WebViewObject.cs.meta
Normal file
11
Assets/3rd/unity-webview/Plugins/WebViewObject.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6270f7e90e694506ac84549c5102045
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,57 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ad99e2446f6f450185b777a22f98f2a
|
||||
folderAsset: yes
|
||||
PluginImporter:
|
||||
serializedVersion: 1
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
isPreloaded: 0
|
||||
platformData:
|
||||
Android:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
Any:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
Editor:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: OSX
|
||||
Linux:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
Linux64:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86_64
|
||||
OSXIntel:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
OSXIntel64:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
OSXUniversal:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
Win:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
Win64:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
iOS:
|
||||
enabled: 0
|
||||
settings:
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4708c4e62d7d946ad9594c9b2a568ba6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>19E287</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>WebViewSeparated</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>net.gree.unitywebview.WebViewSeparated</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>WebViewSeparated</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>11E608c</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>GM</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>19E258</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.15</string>
|
||||
<key>DTXcode</key>
|
||||
<string>1150</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>11E608c</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.10</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 339b5b600628440f79bc7f2cac88de47
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ef432c79f1a545ca80a30cc605983fe
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7bb549cd3a3d142d49618c2fb5ebb251
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22878833472ad46488474031652bc78a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60b1c105abb004192bf943c9edf22ddb
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0b2ac7f199e494be2b61c35c44c5fd4d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,132 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>files</key>
|
||||
<dict>
|
||||
<key>Resources/InfoPlist.strings</key>
|
||||
<data>
|
||||
MiLKDDnrUKr4EmuvhS5VQwxHGK8=
|
||||
</data>
|
||||
</dict>
|
||||
<key>files2</key>
|
||||
<dict>
|
||||
<key>Resources/InfoPlist.strings</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
MiLKDDnrUKr4EmuvhS5VQwxHGK8=
|
||||
</data>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
Oc8u4Ht7Mz58F50L9NeYpbcq9qTlhPUeZCcDu/pPyCg=
|
||||
</data>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>rules</key>
|
||||
<dict>
|
||||
<key>^Resources/</key>
|
||||
<true/>
|
||||
<key>^Resources/.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^Resources/.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^Resources/Base\.lproj/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>1010</real>
|
||||
</dict>
|
||||
<key>^version.plist$</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>rules2</key>
|
||||
<dict>
|
||||
<key>.*\.dSYM($|/)</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>11</real>
|
||||
</dict>
|
||||
<key>^(.*/)?\.DS_Store$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>2000</real>
|
||||
</dict>
|
||||
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
|
||||
<dict>
|
||||
<key>nested</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>10</real>
|
||||
</dict>
|
||||
<key>^.*</key>
|
||||
<true/>
|
||||
<key>^Info\.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^PkgInfo$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^Resources/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^Resources/.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^Resources/.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^Resources/Base\.lproj/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>1010</real>
|
||||
</dict>
|
||||
<key>^[^/]+$</key>
|
||||
<dict>
|
||||
<key>nested</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>10</real>
|
||||
</dict>
|
||||
<key>^embedded\.provisionprofile$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^version\.plist$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83e294a735af0441b997ce35b3c269c1
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/3rd/unity-webview/Plugins/iOS.meta
Normal file
8
Assets/3rd/unity-webview/Plugins/iOS.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfade063a75c24c2180a24391f905771
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
871
Assets/3rd/unity-webview/Plugins/iOS/WebView.mm
Normal file
871
Assets/3rd/unity-webview/Plugins/iOS/WebView.mm
Normal file
@@ -0,0 +1,871 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Keijiro Takahashi
|
||||
* Copyright (C) 2012 GREE, Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#if !(__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0)
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
// NOTE: we need extern without "C" before unity 4.5
|
||||
//extern UIViewController *UnityGetGLViewController();
|
||||
extern "C" UIViewController *UnityGetGLViewController();
|
||||
extern "C" void UnitySendMessage(const char *, const char *, const char *);
|
||||
|
||||
@protocol WebViewProtocol <NSObject>
|
||||
@property (nonatomic, getter=isOpaque) BOOL opaque;
|
||||
@property (nullable, nonatomic, copy) UIColor *backgroundColor UI_APPEARANCE_SELECTOR;
|
||||
@property (nonatomic, getter=isHidden) BOOL hidden;
|
||||
@property (nonatomic) CGRect frame;
|
||||
@property (nullable, nonatomic, weak) id <WKNavigationDelegate> navigationDelegate;
|
||||
@property (nullable, nonatomic, weak) id <WKUIDelegate> UIDelegate;
|
||||
@property (nullable, nonatomic, readonly, copy) NSURL *URL;
|
||||
- (void)load:(NSURLRequest *)request;
|
||||
- (void)loadHTML:(NSString *)html baseURL:(NSURL *)baseUrl;
|
||||
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ __nullable)(__nullable id, NSError * __nullable error))completionHandler;
|
||||
@property (nonatomic, readonly) BOOL canGoBack;
|
||||
@property (nonatomic, readonly) BOOL canGoForward;
|
||||
- (void)goBack;
|
||||
- (void)goForward;
|
||||
- (void)stopLoading;
|
||||
- (void)setScrollBounce:(BOOL)enable;
|
||||
@end
|
||||
|
||||
@interface WKWebView(WebViewProtocolConformed) <WebViewProtocol>
|
||||
@end
|
||||
|
||||
@implementation WKWebView(WebViewProtocolConformed)
|
||||
|
||||
- (void)load:(NSURLRequest *)request
|
||||
{
|
||||
WKWebView *webView = (WKWebView *)self;
|
||||
NSURL *url = [request URL];
|
||||
if ([url.absoluteString hasPrefix:@"file:"]) {
|
||||
NSURL *top = [NSURL URLWithString:[[url absoluteString] stringByDeletingLastPathComponent]];
|
||||
[webView loadFileURL:url allowingReadAccessToURL:top];
|
||||
} else {
|
||||
[webView loadRequest:request];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSURLRequest *)constructionCustomHeader:(NSURLRequest *)originalRequest with:(NSDictionary *)headerDictionary
|
||||
{
|
||||
NSMutableURLRequest *convertedRequest = originalRequest.mutableCopy;
|
||||
for (NSString *key in [headerDictionary allKeys]) {
|
||||
[convertedRequest setValue:headerDictionary[key] forHTTPHeaderField:key];
|
||||
}
|
||||
return (NSURLRequest *)[convertedRequest copy];
|
||||
}
|
||||
|
||||
- (void)loadHTML:(NSString *)html baseURL:(NSURL *)baseUrl
|
||||
{
|
||||
WKWebView *webView = (WKWebView *)self;
|
||||
[webView loadHTMLString:html baseURL:baseUrl];
|
||||
}
|
||||
|
||||
- (void)setScrollBounce:(BOOL)enable
|
||||
{
|
||||
WKWebView *webView = (WKWebView *)self;
|
||||
webView.scrollView.bounces = enable;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface CWebViewPlugin : NSObject<WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler>
|
||||
{
|
||||
UIView <WebViewProtocol> *webView;
|
||||
NSString *gameObjectName;
|
||||
NSMutableDictionary *customRequestHeader;
|
||||
BOOL alertDialogEnabled;
|
||||
NSRegularExpression *allowRegex;
|
||||
NSRegularExpression *denyRegex;
|
||||
NSRegularExpression *hookRegex;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation CWebViewPlugin
|
||||
|
||||
static WKProcessPool *_sharedProcessPool;
|
||||
static NSMutableArray *_instances = [[NSMutableArray alloc] init];
|
||||
|
||||
- (id)initWithGameObjectName:(const char *)gameObjectName_ transparent:(BOOL)transparent ua:(const char *)ua enableWKWebView:(BOOL)enableWKWebView
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
gameObjectName = [NSString stringWithUTF8String:gameObjectName_];
|
||||
customRequestHeader = [[NSMutableDictionary alloc] init];
|
||||
alertDialogEnabled = true;
|
||||
allowRegex = nil;
|
||||
denyRegex = nil;
|
||||
hookRegex = nil;
|
||||
if (ua != NULL && strcmp(ua, "") != 0) {
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
registerDefaults:@{ @"UserAgent": [[NSString alloc] initWithUTF8String:ua] }];
|
||||
}
|
||||
UIView *view = UnityGetGLViewController().view;
|
||||
if (enableWKWebView && [WKWebView class]) {
|
||||
if (_sharedProcessPool == NULL) {
|
||||
_sharedProcessPool = [[WKProcessPool alloc] init];
|
||||
}
|
||||
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
|
||||
WKUserContentController *controller = [[WKUserContentController alloc] init];
|
||||
[controller addScriptMessageHandler:self name:@"unityControl"];
|
||||
configuration.userContentController = controller;
|
||||
configuration.allowsInlineMediaPlayback = true;
|
||||
if (@available(iOS 10.0, *)) {
|
||||
configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
|
||||
} else {
|
||||
if (@available(iOS 9.0, *)) {
|
||||
configuration.requiresUserActionForMediaPlayback = NO;
|
||||
} else {
|
||||
configuration.mediaPlaybackRequiresUserAction = NO;
|
||||
}
|
||||
}
|
||||
configuration.websiteDataStore = [WKWebsiteDataStore defaultDataStore];
|
||||
configuration.processPool = _sharedProcessPool;
|
||||
webView = [[WKWebView alloc] initWithFrame:view.frame configuration:configuration];
|
||||
webView.UIDelegate = self;
|
||||
webView.navigationDelegate = self;
|
||||
} else {
|
||||
webView = nil;
|
||||
return self;
|
||||
}
|
||||
if (transparent) {
|
||||
webView.opaque = NO;
|
||||
webView.backgroundColor = [UIColor clearColor];
|
||||
}
|
||||
webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
webView.hidden = YES;
|
||||
|
||||
[webView addObserver:self forKeyPath: @"loading" options: NSKeyValueObservingOptionNew context:nil];
|
||||
|
||||
[view addSubview:webView];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dispose
|
||||
{
|
||||
if (webView != nil) {
|
||||
UIView <WebViewProtocol> *webView0 = webView;
|
||||
webView = nil;
|
||||
if ([webView0 isKindOfClass:[WKWebView class]]) {
|
||||
webView0.UIDelegate = nil;
|
||||
webView0.navigationDelegate = nil;
|
||||
}
|
||||
[webView0 stopLoading];
|
||||
[webView0 removeFromSuperview];
|
||||
[webView0 removeObserver:self forKeyPath:@"loading"];
|
||||
}
|
||||
hookRegex = nil;
|
||||
denyRegex = nil;
|
||||
allowRegex = nil;
|
||||
customRequestHeader = nil;
|
||||
gameObjectName = nil;
|
||||
}
|
||||
|
||||
+ (void)clearCookies
|
||||
{
|
||||
// cf. https://dev.classmethod.jp/smartphone/remove-webview-cookies/
|
||||
NSString *libraryPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES).firstObject;
|
||||
NSString *cookiesPath = [libraryPath stringByAppendingPathComponent:@"Cookies"];
|
||||
NSString *webKitPath = [libraryPath stringByAppendingPathComponent:@"WebKit"];
|
||||
[[NSFileManager defaultManager] removeItemAtPath:cookiesPath error:nil];
|
||||
[[NSFileManager defaultManager] removeItemAtPath:webKitPath error:nil];
|
||||
|
||||
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
|
||||
if (cookieStorage == nil) {
|
||||
// cf. https://stackoverflow.com/questions/33876295/nshttpcookiestorage-sharedhttpcookiestorage-comes-up-empty-in-10-11
|
||||
cookieStorage = [NSHTTPCookieStorage sharedCookieStorageForGroupContainerIdentifier:@"Cookies"];
|
||||
}
|
||||
[[cookieStorage cookies] enumerateObjectsUsingBlock:^(NSHTTPCookie *cookie, NSUInteger idx, BOOL *stop) {
|
||||
[cookieStorage deleteCookie:cookie];
|
||||
}];
|
||||
|
||||
NSOperatingSystemVersion version = { 9, 0, 0 };
|
||||
if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:version]) {
|
||||
NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
|
||||
NSDate *date = [NSDate dateWithTimeIntervalSince1970:0];
|
||||
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes
|
||||
modifiedSince:date
|
||||
completionHandler:^{}];
|
||||
}
|
||||
}
|
||||
|
||||
+ saveCookies
|
||||
{
|
||||
// cf. https://stackoverflow.com/questions/33156567/getting-all-cookies-from-wkwebview/49744695#49744695
|
||||
_sharedProcessPool = [[WKProcessPool alloc] init];
|
||||
[_instances enumerateObjectsUsingBlock:^(CWebViewPlugin *obj, NSUInteger idx, BOOL *stop) {
|
||||
if ([obj->webView isKindOfClass:[WKWebView class]]) {
|
||||
WKWebView *webView = (WKWebView *)obj->webView;
|
||||
webView.configuration.processPool = _sharedProcessPool;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
+ (const char *)getCookies:(const char *)url
|
||||
{
|
||||
// cf. https://stackoverflow.com/questions/33156567/getting-all-cookies-from-wkwebview/49744695#49744695
|
||||
_sharedProcessPool = [[WKProcessPool alloc] init];
|
||||
[_instances enumerateObjectsUsingBlock:^(CWebViewPlugin *obj, NSUInteger idx, BOOL *stop) {
|
||||
if ([obj->webView isKindOfClass:[WKWebView class]]) {
|
||||
WKWebView *webView = (WKWebView *)obj->webView;
|
||||
webView.configuration.processPool = _sharedProcessPool;
|
||||
}
|
||||
}];
|
||||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||||
formatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
|
||||
[formatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss zzz"];
|
||||
NSMutableString *result = [NSMutableString string];
|
||||
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
|
||||
if (cookieStorage == nil) {
|
||||
// cf. https://stackoverflow.com/questions/33876295/nshttpcookiestorage-sharedhttpcookiestorage-comes-up-empty-in-10-11
|
||||
cookieStorage = [NSHTTPCookieStorage sharedCookieStorageForGroupContainerIdentifier:@"Cookies"];
|
||||
}
|
||||
[[cookieStorage cookiesForURL:[NSURL URLWithString:[[NSString alloc] initWithUTF8String:url]]]
|
||||
enumerateObjectsUsingBlock:^(NSHTTPCookie *cookie, NSUInteger idx, BOOL *stop) {
|
||||
[result appendString:[NSString stringWithFormat:@"%@=%@", cookie.name, cookie.value]];
|
||||
if ([cookie.domain length] > 0) {
|
||||
[result appendString:[NSString stringWithFormat:@"; "]];
|
||||
[result appendString:[NSString stringWithFormat:@"Domain=%@", cookie.domain]];
|
||||
}
|
||||
if ([cookie.path length] > 0) {
|
||||
[result appendString:[NSString stringWithFormat:@"; "]];
|
||||
[result appendString:[NSString stringWithFormat:@"Path=%@", cookie.path]];
|
||||
}
|
||||
if (cookie.expiresDate != nil) {
|
||||
[result appendString:[NSString stringWithFormat:@"; "]];
|
||||
[result appendString:[NSString stringWithFormat:@"Expires=%@", [formatter stringFromDate:cookie.expiresDate]]];
|
||||
}
|
||||
[result appendString:[NSString stringWithFormat:@"; "]];
|
||||
[result appendString:[NSString stringWithFormat:@"Version=%zd", cookie.version]];
|
||||
[result appendString:[NSString stringWithFormat:@"\n"]];
|
||||
}];
|
||||
const char *s = [result UTF8String];
|
||||
char *r = (char *)malloc(strlen(s) + 1);
|
||||
strcpy(r, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
- (void)userContentController:(WKUserContentController *)userContentController
|
||||
didReceiveScriptMessage:(WKScriptMessage *)message {
|
||||
|
||||
// Log out the message received
|
||||
NSLog(@"Received event %@", message.body);
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallFromJS",
|
||||
[[NSString stringWithFormat:@"%@", message.body] UTF8String]);
|
||||
|
||||
/*
|
||||
// Then pull something from the device using the message body
|
||||
NSString *version = [[UIDevice currentDevice] valueForKey:message.body];
|
||||
|
||||
// Execute some JavaScript using the result?
|
||||
NSString *exec_template = @"set_headline(\"received: %@\");";
|
||||
NSString *exec = [NSString stringWithFormat:exec_template, version];
|
||||
[webView evaluateJavaScript:exec completionHandler:nil];
|
||||
*/
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary *)change
|
||||
context:(void *)context {
|
||||
if (webView == nil)
|
||||
return;
|
||||
|
||||
if ([keyPath isEqualToString:@"loading"] && [[change objectForKey:NSKeyValueChangeNewKey] intValue] == 0
|
||||
&& [webView URL] != nil) {
|
||||
UnitySendMessage(
|
||||
[gameObjectName UTF8String],
|
||||
"CallOnLoaded",
|
||||
[[[webView URL] absoluteString] UTF8String]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
|
||||
{
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallOnError", [[error description] UTF8String]);
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error
|
||||
{
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallOnError", [[error description] UTF8String]);
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)wkWebView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
|
||||
{
|
||||
if (webView == nil) {
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
}
|
||||
NSURL *nsurl = [navigationAction.request URL];
|
||||
NSString *url = [nsurl absoluteString];
|
||||
BOOL pass = YES;
|
||||
if (allowRegex != nil && [allowRegex firstMatchInString:url options:0 range:NSMakeRange(0, url.length)]) {
|
||||
pass = YES;
|
||||
} else if (denyRegex != nil && [denyRegex firstMatchInString:url options:0 range:NSMakeRange(0, url.length)]) {
|
||||
pass = NO;
|
||||
}
|
||||
if (!pass) {
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
}
|
||||
if ([url rangeOfString:@"//itunes.apple.com/"].location != NSNotFound) {
|
||||
[[UIApplication sharedApplication] openURL:nsurl];
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
} else if ([url hasPrefix:@"unity:"]) {
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallFromJS", [[url substringFromIndex:6] UTF8String]);
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
} else if (hookRegex != nil && [hookRegex firstMatchInString:url options:0 range:NSMakeRange(0, url.length)]) {
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallOnHooked", [url UTF8String]);
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
} else if (![url hasPrefix:@"about:blank"] // for loadHTML(), cf. #365
|
||||
&& ![url hasPrefix:@"file:"]
|
||||
&& ![url hasPrefix:@"http:"]
|
||||
&& ![url hasPrefix:@"https:"]) {
|
||||
if([[UIApplication sharedApplication] canOpenURL:nsurl]) {
|
||||
[[UIApplication sharedApplication] openURL:nsurl];
|
||||
}
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
} else if (navigationAction.navigationType == WKNavigationTypeLinkActivated
|
||||
&& (!navigationAction.targetFrame || !navigationAction.targetFrame.isMainFrame)) {
|
||||
// cf. for target="_blank", cf. http://qiita.com/ShingoFukuyama/items/b3a1441025a36ab7659c
|
||||
[webView load:navigationAction.request];
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
} else {
|
||||
if (navigationAction.targetFrame != nil && navigationAction.targetFrame.isMainFrame) {
|
||||
// If the custom header is not attached, give it and make a request again.
|
||||
if (![self isSetupedCustomHeader:[navigationAction request]]) {
|
||||
NSLog(@"navi ... %@", navigationAction);
|
||||
[wkWebView loadRequest:[self constructionCustomHeader:navigationAction.request]];
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallOnStarted", [url UTF8String]);
|
||||
decisionHandler(WKNavigationActionPolicyAllow);
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
|
||||
|
||||
if ([navigationResponse.response isKindOfClass:[NSHTTPURLResponse class]]) {
|
||||
|
||||
NSHTTPURLResponse * response = (NSHTTPURLResponse *)navigationResponse.response;
|
||||
if (response.statusCode >= 400) {
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallOnHttpError", [[NSString stringWithFormat:@"%d", response.statusCode] UTF8String]);
|
||||
}
|
||||
|
||||
}
|
||||
decisionHandler(WKNavigationResponsePolicyAllow);
|
||||
}
|
||||
|
||||
// alert
|
||||
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
|
||||
{
|
||||
if (!alertDialogEnabled) {
|
||||
completionHandler();
|
||||
return;
|
||||
}
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@""
|
||||
message:message
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addAction: [UIAlertAction actionWithTitle:@"OK"
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction *action) {
|
||||
completionHandler();
|
||||
}]];
|
||||
[UnityGetGLViewController() presentViewController:alertController animated:YES completion:^{}];
|
||||
}
|
||||
|
||||
// confirm
|
||||
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler
|
||||
{
|
||||
if (!alertDialogEnabled) {
|
||||
completionHandler(NO);
|
||||
return;
|
||||
}
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@""
|
||||
message:message
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"OK"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {
|
||||
completionHandler(YES);
|
||||
}]];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel"
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction *action) {
|
||||
completionHandler(NO);
|
||||
}]];
|
||||
[UnityGetGLViewController() presentViewController:alertController animated:YES completion:^{}];
|
||||
}
|
||||
|
||||
// prompt
|
||||
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *))completionHandler
|
||||
{
|
||||
if (!alertDialogEnabled) {
|
||||
completionHandler(nil);
|
||||
return;
|
||||
}
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@""
|
||||
message:prompt
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
textField.text = defaultText;
|
||||
}];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"OK"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {
|
||||
NSString *input = ((UITextField *)alertController.textFields.firstObject).text;
|
||||
completionHandler(input);
|
||||
}]];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel"
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction *action) {
|
||||
completionHandler(nil);
|
||||
}]];
|
||||
[UnityGetGLViewController() presentViewController:alertController animated:YES completion:^{}];
|
||||
}
|
||||
|
||||
- (BOOL)isSetupedCustomHeader:(NSURLRequest *)targetRequest
|
||||
{
|
||||
// Check for additional custom header.
|
||||
for (NSString *key in [customRequestHeader allKeys])
|
||||
{
|
||||
if (![[[targetRequest allHTTPHeaderFields] objectForKey:key] isEqualToString:[customRequestHeader objectForKey:key]]) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSURLRequest *)constructionCustomHeader:(NSURLRequest *)originalRequest
|
||||
{
|
||||
NSMutableURLRequest *convertedRequest = originalRequest.mutableCopy;
|
||||
for (NSString *key in [customRequestHeader allKeys]) {
|
||||
[convertedRequest setValue:customRequestHeader[key] forHTTPHeaderField:key];
|
||||
}
|
||||
return (NSURLRequest *)[convertedRequest copy];
|
||||
}
|
||||
|
||||
- (void)setMargins:(float)left top:(float)top right:(float)right bottom:(float)bottom relative:(BOOL)relative
|
||||
{
|
||||
if (webView == nil)
|
||||
return;
|
||||
UIView *view = UnityGetGLViewController().view;
|
||||
CGRect frame = webView.frame;
|
||||
CGRect screen = view.bounds;
|
||||
if (relative) {
|
||||
frame.size.width = screen.size.width * (1.0f - left - right);
|
||||
frame.size.height = screen.size.height * (1.0f - top - bottom);
|
||||
frame.origin.x = screen.size.width * left;
|
||||
frame.origin.y = screen.size.height * top;
|
||||
} else {
|
||||
CGFloat scale = 1.0f / [self getScale:view];
|
||||
frame.size.width = screen.size.width - scale * (left + right) ;
|
||||
frame.size.height = screen.size.height - scale * (top + bottom) ;
|
||||
frame.origin.x = scale * left ;
|
||||
frame.origin.y = scale * top ;
|
||||
}
|
||||
webView.frame = frame;
|
||||
}
|
||||
|
||||
- (CGFloat)getScale:(UIView *)view
|
||||
{
|
||||
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
|
||||
return view.window.screen.nativeScale;
|
||||
return view.contentScaleFactor;
|
||||
}
|
||||
|
||||
- (void)setVisibility:(BOOL)visibility
|
||||
{
|
||||
if (webView == nil)
|
||||
return;
|
||||
webView.hidden = visibility ? NO : YES;
|
||||
}
|
||||
|
||||
- (void)setAlertDialogEnabled:(BOOL)enabled
|
||||
{
|
||||
alertDialogEnabled = enabled;
|
||||
}
|
||||
|
||||
- (void)setScrollBounceEnabled:(BOOL)enabled
|
||||
{
|
||||
[webView setScrollBounce:enabled];
|
||||
}
|
||||
|
||||
- (BOOL)setURLPattern:(const char *)allowPattern and:(const char *)denyPattern and:(const char *)hookPattern
|
||||
{
|
||||
NSError *err = nil;
|
||||
NSRegularExpression *allow = nil;
|
||||
NSRegularExpression *deny = nil;
|
||||
NSRegularExpression *hook = nil;
|
||||
if (allowPattern == nil || *allowPattern == '\0') {
|
||||
allow = nil;
|
||||
} else {
|
||||
allow
|
||||
= [NSRegularExpression
|
||||
regularExpressionWithPattern:[NSString stringWithUTF8String:allowPattern]
|
||||
options:0
|
||||
error:&err];
|
||||
if (err != nil) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
if (denyPattern == nil || *denyPattern == '\0') {
|
||||
deny = nil;
|
||||
} else {
|
||||
deny
|
||||
= [NSRegularExpression
|
||||
regularExpressionWithPattern:[NSString stringWithUTF8String:denyPattern]
|
||||
options:0
|
||||
error:&err];
|
||||
if (err != nil) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
if (hookPattern == nil || *hookPattern == '\0') {
|
||||
hook = nil;
|
||||
} else {
|
||||
hook
|
||||
= [NSRegularExpression
|
||||
regularExpressionWithPattern:[NSString stringWithUTF8String:hookPattern]
|
||||
options:0
|
||||
error:&err];
|
||||
if (err != nil) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
allowRegex = allow;
|
||||
denyRegex = deny;
|
||||
hookRegex = hook;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)loadURL:(const char *)url
|
||||
{
|
||||
if (webView == nil)
|
||||
return;
|
||||
NSString *urlStr = [NSString stringWithUTF8String:url];
|
||||
NSURL *nsurl = [NSURL URLWithString:urlStr];
|
||||
NSURLRequest *request = [NSURLRequest requestWithURL:nsurl];
|
||||
[webView load:request];
|
||||
}
|
||||
|
||||
- (void)loadHTML:(const char *)html baseURL:(const char *)baseUrl
|
||||
{
|
||||
if (webView == nil)
|
||||
return;
|
||||
NSString *htmlStr = [NSString stringWithUTF8String:html];
|
||||
NSString *baseStr = [NSString stringWithUTF8String:baseUrl];
|
||||
NSURL *baseNSUrl = [NSURL URLWithString:baseStr];
|
||||
[webView loadHTML:htmlStr baseURL:baseNSUrl];
|
||||
}
|
||||
|
||||
- (void)evaluateJS:(const char *)js
|
||||
{
|
||||
if (webView == nil)
|
||||
return;
|
||||
NSString *jsStr = [NSString stringWithUTF8String:js];
|
||||
[webView evaluateJavaScript:jsStr completionHandler:^(NSString *result, NSError *error) {}];
|
||||
}
|
||||
|
||||
- (int)progress
|
||||
{
|
||||
if (webView == nil)
|
||||
return 0;
|
||||
if ([webView isKindOfClass:[WKWebView class]]) {
|
||||
return (int)([(WKWebView *)webView estimatedProgress] * 100);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)canGoBack
|
||||
{
|
||||
if (webView == nil)
|
||||
return false;
|
||||
return [webView canGoBack];
|
||||
}
|
||||
|
||||
- (BOOL)canGoForward
|
||||
{
|
||||
if (webView == nil)
|
||||
return false;
|
||||
return [webView canGoForward];
|
||||
}
|
||||
|
||||
- (void)goBack
|
||||
{
|
||||
if (webView == nil)
|
||||
return;
|
||||
[webView goBack];
|
||||
}
|
||||
|
||||
- (void)goForward
|
||||
{
|
||||
if (webView == nil)
|
||||
return;
|
||||
[webView goForward];
|
||||
}
|
||||
|
||||
- (void)addCustomRequestHeader:(const char *)headerKey value:(const char *)headerValue
|
||||
{
|
||||
NSString *keyString = [NSString stringWithUTF8String:headerKey];
|
||||
NSString *valueString = [NSString stringWithUTF8String:headerValue];
|
||||
|
||||
[customRequestHeader setObject:valueString forKey:keyString];
|
||||
}
|
||||
|
||||
- (void)removeCustomRequestHeader:(const char *)headerKey
|
||||
{
|
||||
NSString *keyString = [NSString stringWithUTF8String:headerKey];
|
||||
|
||||
if ([[customRequestHeader allKeys]containsObject:keyString]) {
|
||||
[customRequestHeader removeObjectForKey:keyString];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)clearCustomRequestHeader
|
||||
{
|
||||
[customRequestHeader removeAllObjects];
|
||||
}
|
||||
|
||||
- (const char *)getCustomRequestHeaderValue:(const char *)headerKey
|
||||
{
|
||||
NSString *keyString = [NSString stringWithUTF8String:headerKey];
|
||||
NSString *result = [customRequestHeader objectForKey:keyString];
|
||||
if (!result) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *s = [result UTF8String];
|
||||
char *r = (char *)malloc(strlen(s) + 1);
|
||||
strcpy(r, s);
|
||||
return r;
|
||||
}
|
||||
@end
|
||||
|
||||
extern "C" {
|
||||
void *_CWebViewPlugin_Init(const char *gameObjectName, BOOL transparent, const char *ua, BOOL enableWKWebView);
|
||||
void _CWebViewPlugin_Destroy(void *instance);
|
||||
void _CWebViewPlugin_SetMargins(
|
||||
void *instance, float left, float top, float right, float bottom, BOOL relative);
|
||||
void _CWebViewPlugin_SetVisibility(void *instance, BOOL visibility);
|
||||
void _CWebViewPlugin_SetAlertDialogEnabled(void *instance, BOOL visibility);
|
||||
void _CWebViewPlugin_SetScrollBounceEnabled(void *instance, BOOL enabled);
|
||||
BOOL _CWebViewPlugin_SetURLPattern(void *instance, const char *allowPattern, const char *denyPattern, const char *hookPattern);
|
||||
void _CWebViewPlugin_LoadURL(void *instance, const char *url);
|
||||
void _CWebViewPlugin_LoadHTML(void *instance, const char *html, const char *baseUrl);
|
||||
void _CWebViewPlugin_EvaluateJS(void *instance, const char *url);
|
||||
int _CWebViewPlugin_Progress(void *instance);
|
||||
BOOL _CWebViewPlugin_CanGoBack(void *instance);
|
||||
BOOL _CWebViewPlugin_CanGoForward(void *instance);
|
||||
void _CWebViewPlugin_GoBack(void *instance);
|
||||
void _CWebViewPlugin_GoForward(void *instance);
|
||||
void _CWebViewPlugin_AddCustomHeader(void *instance, const char *headerKey, const char *headerValue);
|
||||
void _CWebViewPlugin_RemoveCustomHeader(void *instance, const char *headerKey);
|
||||
void _CWebViewPlugin_ClearCustomHeader(void *instance);
|
||||
void _CWebViewPlugin_ClearCookies();
|
||||
void _CWebViewPlugin_SaveCookies();
|
||||
const char *_CWebViewPlugin_GetCookies(const char *url);
|
||||
const char *_CWebViewPlugin_GetCustomHeaderValue(void *instance, const char *headerKey);
|
||||
}
|
||||
|
||||
void *_CWebViewPlugin_Init(const char *gameObjectName, BOOL transparent, const char *ua, BOOL enableWKWebView)
|
||||
{
|
||||
if (! (enableWKWebView && [WKWebView class]))
|
||||
return nil;
|
||||
CWebViewPlugin *webViewPlugin = [[CWebViewPlugin alloc] initWithGameObjectName:gameObjectName transparent:transparent ua:ua enableWKWebView:enableWKWebView];
|
||||
[_instances addObject:webViewPlugin];
|
||||
return (__bridge_retained void *)webViewPlugin;
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_Destroy(void *instance)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge_transfer CWebViewPlugin *)instance;
|
||||
[_instances removeObject:webViewPlugin];
|
||||
[webViewPlugin dispose];
|
||||
webViewPlugin = nil;
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_SetMargins(
|
||||
void *instance, float left, float top, float right, float bottom, BOOL relative)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin setMargins:left top:top right:right bottom:bottom relative:relative];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_SetVisibility(void *instance, BOOL visibility)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin setVisibility:visibility];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_SetAlertDialogEnabled(void *instance, BOOL enabled)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin setAlertDialogEnabled:enabled];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_SetScrollBounceEnabled(void *instance, BOOL enabled)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin setScrollBounceEnabled:enabled];
|
||||
}
|
||||
|
||||
BOOL _CWebViewPlugin_SetURLPattern(void *instance, const char *allowPattern, const char *denyPattern, const char *hookPattern)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return NO;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
return [webViewPlugin setURLPattern:allowPattern and:denyPattern and:hookPattern];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_LoadURL(void *instance, const char *url)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin loadURL:url];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_LoadHTML(void *instance, const char *html, const char *baseUrl)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin loadHTML:html baseURL:baseUrl];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_EvaluateJS(void *instance, const char *js)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin evaluateJS:js];
|
||||
}
|
||||
|
||||
int _CWebViewPlugin_Progress(void *instance)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return 0;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
return [webViewPlugin progress];
|
||||
}
|
||||
|
||||
BOOL _CWebViewPlugin_CanGoBack(void *instance)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return false;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
return [webViewPlugin canGoBack];
|
||||
}
|
||||
|
||||
BOOL _CWebViewPlugin_CanGoForward(void *instance)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return false;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
return [webViewPlugin canGoForward];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_GoBack(void *instance)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin goBack];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_GoForward(void *instance)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin goForward];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_AddCustomHeader(void *instance, const char *headerKey, const char *headerValue)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin addCustomRequestHeader:headerKey value:headerValue];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_RemoveCustomHeader(void *instance, const char *headerKey)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin removeCustomRequestHeader:headerKey];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_ClearCustomHeader(void *instance)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin clearCustomRequestHeader];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_ClearCookies()
|
||||
{
|
||||
[CWebViewPlugin clearCookies];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_SaveCookies()
|
||||
{
|
||||
[CWebViewPlugin saveCookies];
|
||||
}
|
||||
|
||||
const char *_CWebViewPlugin_GetCookies(const char *url)
|
||||
{
|
||||
return [CWebViewPlugin getCookies:url];
|
||||
}
|
||||
|
||||
const char *_CWebViewPlugin_GetCustomHeaderValue(void *instance, const char *headerKey)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return NULL;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
return [webViewPlugin getCustomRequestHeaderValue:headerKey];
|
||||
}
|
||||
|
||||
#endif // !(__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0)
|
||||
33
Assets/3rd/unity-webview/Plugins/iOS/WebView.mm.meta
Normal file
33
Assets/3rd/unity-webview/Plugins/iOS/WebView.mm.meta
Normal file
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca4c86a0d4dff4c079000acbe3695ac4
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
970
Assets/3rd/unity-webview/Plugins/iOS/WebViewWithUIWebView.mm
Normal file
970
Assets/3rd/unity-webview/Plugins/iOS/WebViewWithUIWebView.mm
Normal file
@@ -0,0 +1,970 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Keijiro Takahashi
|
||||
* Copyright (C) 2012 GREE, Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
// NOTE: we need extern without "C" before unity 4.5
|
||||
//extern UIViewController *UnityGetGLViewController();
|
||||
extern "C" UIViewController *UnityGetGLViewController();
|
||||
extern "C" void UnitySendMessage(const char *, const char *, const char *);
|
||||
|
||||
@protocol WebViewProtocol <NSObject>
|
||||
@property (nonatomic, getter=isOpaque) BOOL opaque;
|
||||
@property (nullable, nonatomic, copy) UIColor *backgroundColor UI_APPEARANCE_SELECTOR;
|
||||
@property (nonatomic, getter=isHidden) BOOL hidden;
|
||||
@property (nonatomic) CGRect frame;
|
||||
@property (nullable, nonatomic, assign) id <UIWebViewDelegate> delegate;
|
||||
@property (nullable, nonatomic, weak) id <WKNavigationDelegate> navigationDelegate;
|
||||
@property (nullable, nonatomic, weak) id <WKUIDelegate> UIDelegate;
|
||||
@property (nullable, nonatomic, readonly, copy) NSURL *URL;
|
||||
- (void)load:(NSURLRequest *)request;
|
||||
- (void)loadHTML:(NSString *)html baseURL:(NSURL *)baseUrl;
|
||||
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ __nullable)(__nullable id, NSError * __nullable error))completionHandler;
|
||||
@property (nonatomic, readonly) BOOL canGoBack;
|
||||
@property (nonatomic, readonly) BOOL canGoForward;
|
||||
- (void)goBack;
|
||||
- (void)goForward;
|
||||
- (void)stopLoading;
|
||||
- (void)setScrollBounce:(BOOL)enable;
|
||||
@end
|
||||
|
||||
@interface WKWebView(WebViewProtocolConformed) <WebViewProtocol>
|
||||
@end
|
||||
|
||||
@implementation WKWebView(WebViewProtocolConformed)
|
||||
|
||||
@dynamic delegate;
|
||||
|
||||
- (void)load:(NSURLRequest *)request
|
||||
{
|
||||
WKWebView *webView = (WKWebView *)self;
|
||||
NSURL *url = [request URL];
|
||||
if ([url.absoluteString hasPrefix:@"file:"]) {
|
||||
NSURL *top = [NSURL URLWithString:[[url absoluteString] stringByDeletingLastPathComponent]];
|
||||
[webView loadFileURL:url allowingReadAccessToURL:top];
|
||||
} else {
|
||||
[webView loadRequest:request];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSURLRequest *)constructionCustomHeader:(NSURLRequest *)originalRequest with:(NSDictionary *)headerDictionary
|
||||
{
|
||||
NSMutableURLRequest *convertedRequest = originalRequest.mutableCopy;
|
||||
for (NSString *key in [headerDictionary allKeys]) {
|
||||
[convertedRequest setValue:headerDictionary[key] forHTTPHeaderField:key];
|
||||
}
|
||||
return (NSURLRequest *)[convertedRequest copy];
|
||||
}
|
||||
|
||||
- (void)loadHTML:(NSString *)html baseURL:(NSURL *)baseUrl
|
||||
{
|
||||
WKWebView *webView = (WKWebView *)self;
|
||||
[webView loadHTMLString:html baseURL:baseUrl];
|
||||
}
|
||||
|
||||
- (void)setScrollBounce:(BOOL)enable
|
||||
{
|
||||
WKWebView *webView = (WKWebView *)self;
|
||||
webView.scrollView.bounces = enable;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface UIWebView(WebViewProtocolConformed) <WebViewProtocol>
|
||||
@end
|
||||
|
||||
@implementation UIWebView(WebViewProtocolConformed)
|
||||
|
||||
@dynamic navigationDelegate;
|
||||
@dynamic UIDelegate;
|
||||
|
||||
- (NSURL *)URL
|
||||
{
|
||||
return [NSURL URLWithString:[self stringByEvaluatingJavaScriptFromString:@"document.URL"]];
|
||||
}
|
||||
|
||||
- (void)load:(NSURLRequest *)request
|
||||
{
|
||||
UIWebView *webView = (UIWebView *)self;
|
||||
[webView loadRequest:request];
|
||||
}
|
||||
|
||||
- (void)loadHTML:(NSString *)html baseURL:(NSURL *)baseUrl
|
||||
{
|
||||
UIWebView *webView = (UIWebView *)self;
|
||||
[webView loadHTMLString:html baseURL:baseUrl];
|
||||
}
|
||||
|
||||
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ __nullable)(__nullable id, NSError * __nullable error))completionHandler
|
||||
{
|
||||
NSString *result = [self stringByEvaluatingJavaScriptFromString:javaScriptString];
|
||||
if (completionHandler) {
|
||||
completionHandler(result, nil);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setScrollBounce:(BOOL)enable
|
||||
{
|
||||
UIWebView *webView = (UIWebView *)self;
|
||||
webView.scrollView.bounces = enable;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface CWebViewPlugin : NSObject<UIWebViewDelegate, WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler>
|
||||
{
|
||||
UIView <WebViewProtocol> *webView;
|
||||
NSString *gameObjectName;
|
||||
NSMutableDictionary *customRequestHeader;
|
||||
BOOL alertDialogEnabled;
|
||||
NSRegularExpression *allowRegex;
|
||||
NSRegularExpression *denyRegex;
|
||||
NSRegularExpression *hookRegex;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation CWebViewPlugin
|
||||
|
||||
static WKProcessPool *_sharedProcessPool;
|
||||
static NSMutableArray *_instances = [[NSMutableArray alloc] init];
|
||||
|
||||
- (id)initWithGameObjectName:(const char *)gameObjectName_ transparent:(BOOL)transparent ua:(const char *)ua enableWKWebView:(BOOL)enableWKWebView
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
gameObjectName = [NSString stringWithUTF8String:gameObjectName_];
|
||||
customRequestHeader = [[NSMutableDictionary alloc] init];
|
||||
alertDialogEnabled = true;
|
||||
allowRegex = nil;
|
||||
denyRegex = nil;
|
||||
hookRegex = nil;
|
||||
if (ua != NULL && strcmp(ua, "") != 0) {
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
registerDefaults:@{ @"UserAgent": [[NSString alloc] initWithUTF8String:ua] }];
|
||||
}
|
||||
UIView *view = UnityGetGLViewController().view;
|
||||
if (enableWKWebView && [WKWebView class]) {
|
||||
if (_sharedProcessPool == NULL) {
|
||||
_sharedProcessPool = [[WKProcessPool alloc] init];
|
||||
}
|
||||
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
|
||||
WKUserContentController *controller = [[WKUserContentController alloc] init];
|
||||
[controller addScriptMessageHandler:self name:@"unityControl"];
|
||||
configuration.userContentController = controller;
|
||||
configuration.allowsInlineMediaPlayback = true;
|
||||
if (@available(iOS 10.0, *)) {
|
||||
configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
|
||||
} else {
|
||||
if (@available(iOS 9.0, *)) {
|
||||
configuration.requiresUserActionForMediaPlayback = NO;
|
||||
} else {
|
||||
configuration.mediaPlaybackRequiresUserAction = NO;
|
||||
}
|
||||
}
|
||||
configuration.websiteDataStore = [WKWebsiteDataStore defaultDataStore];
|
||||
configuration.processPool = _sharedProcessPool;
|
||||
webView = [[WKWebView alloc] initWithFrame:view.frame configuration:configuration];
|
||||
webView.UIDelegate = self;
|
||||
webView.navigationDelegate = self;
|
||||
} else {
|
||||
UIWebView *uiwebview = [[UIWebView alloc] initWithFrame:view.frame];
|
||||
uiwebview.allowsInlineMediaPlayback = YES;
|
||||
uiwebview.mediaPlaybackRequiresUserAction = NO;
|
||||
webView = uiwebview;
|
||||
webView.delegate = self;
|
||||
}
|
||||
if (transparent) {
|
||||
webView.opaque = NO;
|
||||
webView.backgroundColor = [UIColor clearColor];
|
||||
}
|
||||
webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
webView.hidden = YES;
|
||||
|
||||
[webView addObserver:self forKeyPath: @"loading" options: NSKeyValueObservingOptionNew context:nil];
|
||||
|
||||
[view addSubview:webView];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dispose
|
||||
{
|
||||
if (webView != nil) {
|
||||
UIView <WebViewProtocol> *webView0 = webView;
|
||||
webView = nil;
|
||||
if ([webView0 isKindOfClass:[WKWebView class]]) {
|
||||
webView0.UIDelegate = nil;
|
||||
webView0.navigationDelegate = nil;
|
||||
} else {
|
||||
webView0.delegate = nil;
|
||||
}
|
||||
[webView0 stopLoading];
|
||||
[webView0 removeFromSuperview];
|
||||
[webView0 removeObserver:self forKeyPath:@"loading"];
|
||||
}
|
||||
hookRegex = nil;
|
||||
denyRegex = nil;
|
||||
allowRegex = nil;
|
||||
customRequestHeader = nil;
|
||||
gameObjectName = nil;
|
||||
}
|
||||
|
||||
+ (void)clearCookies
|
||||
{
|
||||
// cf. https://dev.classmethod.jp/smartphone/remove-webview-cookies/
|
||||
NSString *libraryPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES).firstObject;
|
||||
NSString *cookiesPath = [libraryPath stringByAppendingPathComponent:@"Cookies"];
|
||||
NSString *webKitPath = [libraryPath stringByAppendingPathComponent:@"WebKit"];
|
||||
[[NSFileManager defaultManager] removeItemAtPath:cookiesPath error:nil];
|
||||
[[NSFileManager defaultManager] removeItemAtPath:webKitPath error:nil];
|
||||
|
||||
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
|
||||
if (cookieStorage == nil) {
|
||||
// cf. https://stackoverflow.com/questions/33876295/nshttpcookiestorage-sharedhttpcookiestorage-comes-up-empty-in-10-11
|
||||
cookieStorage = [NSHTTPCookieStorage sharedCookieStorageForGroupContainerIdentifier:@"Cookies"];
|
||||
}
|
||||
[[cookieStorage cookies] enumerateObjectsUsingBlock:^(NSHTTPCookie *cookie, NSUInteger idx, BOOL *stop) {
|
||||
[cookieStorage deleteCookie:cookie];
|
||||
}];
|
||||
|
||||
NSOperatingSystemVersion version = { 9, 0, 0 };
|
||||
if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:version]) {
|
||||
NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
|
||||
NSDate *date = [NSDate dateWithTimeIntervalSince1970:0];
|
||||
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes
|
||||
modifiedSince:date
|
||||
completionHandler:^{}];
|
||||
}
|
||||
}
|
||||
|
||||
+ saveCookies
|
||||
{
|
||||
// cf. https://stackoverflow.com/questions/33156567/getting-all-cookies-from-wkwebview/49744695#49744695
|
||||
_sharedProcessPool = [[WKProcessPool alloc] init];
|
||||
[_instances enumerateObjectsUsingBlock:^(CWebViewPlugin *obj, NSUInteger idx, BOOL *stop) {
|
||||
if ([obj->webView isKindOfClass:[WKWebView class]]) {
|
||||
WKWebView *webView = (WKWebView *)obj->webView;
|
||||
webView.configuration.processPool = _sharedProcessPool;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
+ (const char *)getCookies:(const char *)url
|
||||
{
|
||||
// cf. https://stackoverflow.com/questions/33156567/getting-all-cookies-from-wkwebview/49744695#49744695
|
||||
_sharedProcessPool = [[WKProcessPool alloc] init];
|
||||
[_instances enumerateObjectsUsingBlock:^(CWebViewPlugin *obj, NSUInteger idx, BOOL *stop) {
|
||||
if ([obj->webView isKindOfClass:[WKWebView class]]) {
|
||||
WKWebView *webView = (WKWebView *)obj->webView;
|
||||
webView.configuration.processPool = _sharedProcessPool;
|
||||
}
|
||||
}];
|
||||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||||
formatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
|
||||
[formatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss zzz"];
|
||||
NSMutableString *result = [NSMutableString string];
|
||||
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
|
||||
if (cookieStorage == nil) {
|
||||
// cf. https://stackoverflow.com/questions/33876295/nshttpcookiestorage-sharedhttpcookiestorage-comes-up-empty-in-10-11
|
||||
cookieStorage = [NSHTTPCookieStorage sharedCookieStorageForGroupContainerIdentifier:@"Cookies"];
|
||||
}
|
||||
[[cookieStorage cookiesForURL:[NSURL URLWithString:[[NSString alloc] initWithUTF8String:url]]]
|
||||
enumerateObjectsUsingBlock:^(NSHTTPCookie *cookie, NSUInteger idx, BOOL *stop) {
|
||||
[result appendString:[NSString stringWithFormat:@"%@=%@", cookie.name, cookie.value]];
|
||||
if ([cookie.domain length] > 0) {
|
||||
[result appendString:[NSString stringWithFormat:@"; "]];
|
||||
[result appendString:[NSString stringWithFormat:@"Domain=%@", cookie.domain]];
|
||||
}
|
||||
if ([cookie.path length] > 0) {
|
||||
[result appendString:[NSString stringWithFormat:@"; "]];
|
||||
[result appendString:[NSString stringWithFormat:@"Path=%@", cookie.path]];
|
||||
}
|
||||
if (cookie.expiresDate != nil) {
|
||||
[result appendString:[NSString stringWithFormat:@"; "]];
|
||||
[result appendString:[NSString stringWithFormat:@"Expires=%@", [formatter stringFromDate:cookie.expiresDate]]];
|
||||
}
|
||||
[result appendString:[NSString stringWithFormat:@"; "]];
|
||||
[result appendString:[NSString stringWithFormat:@"Version=%zd", cookie.version]];
|
||||
[result appendString:[NSString stringWithFormat:@"\n"]];
|
||||
}];
|
||||
const char *s = [result UTF8String];
|
||||
char *r = (char *)malloc(strlen(s) + 1);
|
||||
strcpy(r, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
- (void)userContentController:(WKUserContentController *)userContentController
|
||||
didReceiveScriptMessage:(WKScriptMessage *)message {
|
||||
|
||||
// Log out the message received
|
||||
NSLog(@"Received event %@", message.body);
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallFromJS",
|
||||
[[NSString stringWithFormat:@"%@", message.body] UTF8String]);
|
||||
|
||||
/*
|
||||
// Then pull something from the device using the message body
|
||||
NSString *version = [[UIDevice currentDevice] valueForKey:message.body];
|
||||
|
||||
// Execute some JavaScript using the result?
|
||||
NSString *exec_template = @"set_headline(\"received: %@\");";
|
||||
NSString *exec = [NSString stringWithFormat:exec_template, version];
|
||||
[webView evaluateJavaScript:exec completionHandler:nil];
|
||||
*/
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary *)change
|
||||
context:(void *)context {
|
||||
if (webView == nil)
|
||||
return;
|
||||
|
||||
if ([keyPath isEqualToString:@"loading"] && [[change objectForKey:NSKeyValueChangeNewKey] intValue] == 0
|
||||
&& [webView URL] != nil) {
|
||||
UnitySendMessage(
|
||||
[gameObjectName UTF8String],
|
||||
"CallOnLoaded",
|
||||
[[[webView URL] absoluteString] UTF8String]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(UIWebView *)uiWebView didFailLoadWithError:(NSError *)error
|
||||
{
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallOnError", [[error description] UTF8String]);
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
|
||||
{
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallOnError", [[error description] UTF8String]);
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error
|
||||
{
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallOnError", [[error description] UTF8String]);
|
||||
}
|
||||
|
||||
- (void)webViewDidFinishLoad:(UIWebView *)uiWebView {
|
||||
if (webView == nil)
|
||||
return;
|
||||
// cf. http://stackoverflow.com/questions/10996028/uiwebview-when-did-a-page-really-finish-loading/15916853#15916853
|
||||
if ([[uiWebView stringByEvaluatingJavaScriptFromString:@"document.readyState"] isEqualToString:@"complete"]
|
||||
&& [webView URL] != nil) {
|
||||
UnitySendMessage(
|
||||
[gameObjectName UTF8String],
|
||||
"CallOnLoaded",
|
||||
[[[webView URL] absoluteString] UTF8String]);
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)webView:(UIWebView *)uiWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
|
||||
{
|
||||
if (webView == nil)
|
||||
return YES;
|
||||
|
||||
NSString *url = [[request URL] absoluteString];
|
||||
BOOL pass = YES;
|
||||
if (allowRegex != nil && [allowRegex firstMatchInString:url options:0 range:NSMakeRange(0, url.length)]) {
|
||||
pass = YES;
|
||||
} else if (denyRegex != nil && [denyRegex firstMatchInString:url options:0 range:NSMakeRange(0, url.length)]) {
|
||||
pass = NO;
|
||||
}
|
||||
if (!pass) {
|
||||
return NO;
|
||||
}
|
||||
if ([url rangeOfString:@"//itunes.apple.com/"].location != NSNotFound) {
|
||||
[[UIApplication sharedApplication] openURL:nsurl];
|
||||
return NO;
|
||||
} else if ([url hasPrefix:@"unity:"]) {
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallFromJS", [[url substringFromIndex:6] UTF8String]);
|
||||
return NO;
|
||||
} else if (hookRegex != nil && [hookRegex firstMatchInString:url options:0 range:NSMakeRange(0, url.length)]) {
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallOnHooked", [url UTF8String]);
|
||||
return NO;
|
||||
} else {
|
||||
if (![self isSetupedCustomHeader:request]) {
|
||||
[uiWebView loadRequest:[self constructionCustomHeader:request]];
|
||||
return NO;
|
||||
}
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallOnStarted", [url UTF8String]);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)wkWebView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
|
||||
{
|
||||
if (webView == nil) {
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
}
|
||||
NSURL *nsurl = [navigationAction.request URL];
|
||||
NSString *url = [nsurl absoluteString];
|
||||
BOOL pass = YES;
|
||||
if (allowRegex != nil && [allowRegex firstMatchInString:url options:0 range:NSMakeRange(0, url.length)]) {
|
||||
pass = YES;
|
||||
} else if (denyRegex != nil && [denyRegex firstMatchInString:url options:0 range:NSMakeRange(0, url.length)]) {
|
||||
pass = NO;
|
||||
}
|
||||
if (!pass) {
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
}
|
||||
if ([url rangeOfString:@"//itunes.apple.com/"].location != NSNotFound) {
|
||||
[[UIApplication sharedApplication] openURL:nsurl];
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
} else if ([url hasPrefix:@"unity:"]) {
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallFromJS", [[url substringFromIndex:6] UTF8String]);
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
} else if (hookRegex != nil && [hookRegex firstMatchInString:url options:0 range:NSMakeRange(0, url.length)]) {
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallOnHooked", [url UTF8String]);
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
} else if (![url hasPrefix:@"about:blank"] // for loadHTML(), cf. #365
|
||||
&& ![url hasPrefix:@"file:"]
|
||||
&& ![url hasPrefix:@"http:"]
|
||||
&& ![url hasPrefix:@"https:"]) {
|
||||
if([[UIApplication sharedApplication] canOpenURL:nsurl]) {
|
||||
[[UIApplication sharedApplication] openURL:nsurl];
|
||||
}
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
} else if (navigationAction.navigationType == WKNavigationTypeLinkActivated
|
||||
&& (!navigationAction.targetFrame || !navigationAction.targetFrame.isMainFrame)) {
|
||||
// cf. for target="_blank", cf. http://qiita.com/ShingoFukuyama/items/b3a1441025a36ab7659c
|
||||
[webView load:navigationAction.request];
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
} else {
|
||||
if (navigationAction.targetFrame != nil && navigationAction.targetFrame.isMainFrame) {
|
||||
// If the custom header is not attached, give it and make a request again.
|
||||
if (![self isSetupedCustomHeader:[navigationAction request]]) {
|
||||
NSLog(@"navi ... %@", navigationAction);
|
||||
[wkWebView loadRequest:[self constructionCustomHeader:navigationAction.request]];
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallOnStarted", [url UTF8String]);
|
||||
decisionHandler(WKNavigationActionPolicyAllow);
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
|
||||
|
||||
if ([navigationResponse.response isKindOfClass:[NSHTTPURLResponse class]]) {
|
||||
|
||||
NSHTTPURLResponse * response = (NSHTTPURLResponse *)navigationResponse.response;
|
||||
if (response.statusCode >= 400) {
|
||||
UnitySendMessage([gameObjectName UTF8String], "CallOnHttpError", [[NSString stringWithFormat:@"%d", response.statusCode] UTF8String]);
|
||||
}
|
||||
|
||||
}
|
||||
decisionHandler(WKNavigationResponsePolicyAllow);
|
||||
}
|
||||
|
||||
// alert
|
||||
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
|
||||
{
|
||||
if (!alertDialogEnabled) {
|
||||
completionHandler();
|
||||
return;
|
||||
}
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@""
|
||||
message:message
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addAction: [UIAlertAction actionWithTitle:@"OK"
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction *action) {
|
||||
completionHandler();
|
||||
}]];
|
||||
[UnityGetGLViewController() presentViewController:alertController animated:YES completion:^{}];
|
||||
}
|
||||
|
||||
// confirm
|
||||
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler
|
||||
{
|
||||
if (!alertDialogEnabled) {
|
||||
completionHandler(NO);
|
||||
return;
|
||||
}
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@""
|
||||
message:message
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"OK"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {
|
||||
completionHandler(YES);
|
||||
}]];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel"
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction *action) {
|
||||
completionHandler(NO);
|
||||
}]];
|
||||
[UnityGetGLViewController() presentViewController:alertController animated:YES completion:^{}];
|
||||
}
|
||||
|
||||
// prompt
|
||||
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *))completionHandler
|
||||
{
|
||||
if (!alertDialogEnabled) {
|
||||
completionHandler(nil);
|
||||
return;
|
||||
}
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@""
|
||||
message:prompt
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
textField.text = defaultText;
|
||||
}];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"OK"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {
|
||||
NSString *input = ((UITextField *)alertController.textFields.firstObject).text;
|
||||
completionHandler(input);
|
||||
}]];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel"
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction *action) {
|
||||
completionHandler(nil);
|
||||
}]];
|
||||
[UnityGetGLViewController() presentViewController:alertController animated:YES completion:^{}];
|
||||
}
|
||||
|
||||
- (BOOL)isSetupedCustomHeader:(NSURLRequest *)targetRequest
|
||||
{
|
||||
// Check for additional custom header.
|
||||
for (NSString *key in [customRequestHeader allKeys])
|
||||
{
|
||||
if (![[[targetRequest allHTTPHeaderFields] objectForKey:key] isEqualToString:[customRequestHeader objectForKey:key]]) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSURLRequest *)constructionCustomHeader:(NSURLRequest *)originalRequest
|
||||
{
|
||||
NSMutableURLRequest *convertedRequest = originalRequest.mutableCopy;
|
||||
for (NSString *key in [customRequestHeader allKeys]) {
|
||||
[convertedRequest setValue:customRequestHeader[key] forHTTPHeaderField:key];
|
||||
}
|
||||
return (NSURLRequest *)[convertedRequest copy];
|
||||
}
|
||||
|
||||
- (void)setMargins:(float)left top:(float)top right:(float)right bottom:(float)bottom relative:(BOOL)relative
|
||||
{
|
||||
if (webView == nil)
|
||||
return;
|
||||
UIView *view = UnityGetGLViewController().view;
|
||||
CGRect frame = webView.frame;
|
||||
CGRect screen = view.bounds;
|
||||
if (relative) {
|
||||
frame.size.width = screen.size.width * (1.0f - left - right);
|
||||
frame.size.height = screen.size.height * (1.0f - top - bottom);
|
||||
frame.origin.x = screen.size.width * left;
|
||||
frame.origin.y = screen.size.height * top;
|
||||
} else {
|
||||
CGFloat scale = 1.0f / [self getScale:view];
|
||||
frame.size.width = screen.size.width - scale * (left + right) ;
|
||||
frame.size.height = screen.size.height - scale * (top + bottom) ;
|
||||
frame.origin.x = scale * left ;
|
||||
frame.origin.y = scale * top ;
|
||||
}
|
||||
webView.frame = frame;
|
||||
}
|
||||
|
||||
- (CGFloat)getScale:(UIView *)view
|
||||
{
|
||||
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
|
||||
return view.window.screen.nativeScale;
|
||||
return view.contentScaleFactor;
|
||||
}
|
||||
|
||||
- (void)setVisibility:(BOOL)visibility
|
||||
{
|
||||
if (webView == nil)
|
||||
return;
|
||||
webView.hidden = visibility ? NO : YES;
|
||||
}
|
||||
|
||||
- (void)setAlertDialogEnabled:(BOOL)enabled
|
||||
{
|
||||
alertDialogEnabled = enabled;
|
||||
}
|
||||
|
||||
- (void)setScrollBounceEnabled:(BOOL)enabled
|
||||
{
|
||||
[webView setScrollBounce:enabled];
|
||||
}
|
||||
|
||||
- (BOOL)setURLPattern:(const char *)allowPattern and:(const char *)denyPattern and:(const char *)hookPattern
|
||||
{
|
||||
NSError *err = nil;
|
||||
NSRegularExpression *allow = nil;
|
||||
NSRegularExpression *deny = nil;
|
||||
NSRegularExpression *hook = nil;
|
||||
if (allowPattern == nil || *allowPattern == '\0') {
|
||||
allow = nil;
|
||||
} else {
|
||||
allow
|
||||
= [NSRegularExpression
|
||||
regularExpressionWithPattern:[NSString stringWithUTF8String:allowPattern]
|
||||
options:0
|
||||
error:&err];
|
||||
if (err != nil) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
if (denyPattern == nil || *denyPattern == '\0') {
|
||||
deny = nil;
|
||||
} else {
|
||||
deny
|
||||
= [NSRegularExpression
|
||||
regularExpressionWithPattern:[NSString stringWithUTF8String:denyPattern]
|
||||
options:0
|
||||
error:&err];
|
||||
if (err != nil) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
if (hookPattern == nil || *hookPattern == '\0') {
|
||||
hook = nil;
|
||||
} else {
|
||||
hook
|
||||
= [NSRegularExpression
|
||||
regularExpressionWithPattern:[NSString stringWithUTF8String:hookPattern]
|
||||
options:0
|
||||
error:&err];
|
||||
if (err != nil) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
allowRegex = allow;
|
||||
denyRegex = deny;
|
||||
hookRegex = hook;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)loadURL:(const char *)url
|
||||
{
|
||||
if (webView == nil)
|
||||
return;
|
||||
NSString *urlStr = [NSString stringWithUTF8String:url];
|
||||
NSURL *nsurl = [NSURL URLWithString:urlStr];
|
||||
NSURLRequest *request = [NSURLRequest requestWithURL:nsurl];
|
||||
[webView load:request];
|
||||
}
|
||||
|
||||
- (void)loadHTML:(const char *)html baseURL:(const char *)baseUrl
|
||||
{
|
||||
if (webView == nil)
|
||||
return;
|
||||
NSString *htmlStr = [NSString stringWithUTF8String:html];
|
||||
NSString *baseStr = [NSString stringWithUTF8String:baseUrl];
|
||||
NSURL *baseNSUrl = [NSURL URLWithString:baseStr];
|
||||
[webView loadHTML:htmlStr baseURL:baseNSUrl];
|
||||
}
|
||||
|
||||
- (void)evaluateJS:(const char *)js
|
||||
{
|
||||
if (webView == nil)
|
||||
return;
|
||||
NSString *jsStr = [NSString stringWithUTF8String:js];
|
||||
[webView evaluateJavaScript:jsStr completionHandler:^(NSString *result, NSError *error) {}];
|
||||
}
|
||||
|
||||
- (int)progress
|
||||
{
|
||||
if (webView == nil)
|
||||
return 0;
|
||||
if ([webView isKindOfClass:[WKWebView class]]) {
|
||||
return (int)([(WKWebView *)webView estimatedProgress] * 100);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)canGoBack
|
||||
{
|
||||
if (webView == nil)
|
||||
return false;
|
||||
return [webView canGoBack];
|
||||
}
|
||||
|
||||
- (BOOL)canGoForward
|
||||
{
|
||||
if (webView == nil)
|
||||
return false;
|
||||
return [webView canGoForward];
|
||||
}
|
||||
|
||||
- (void)goBack
|
||||
{
|
||||
if (webView == nil)
|
||||
return;
|
||||
[webView goBack];
|
||||
}
|
||||
|
||||
- (void)goForward
|
||||
{
|
||||
if (webView == nil)
|
||||
return;
|
||||
[webView goForward];
|
||||
}
|
||||
|
||||
- (void)addCustomRequestHeader:(const char *)headerKey value:(const char *)headerValue
|
||||
{
|
||||
NSString *keyString = [NSString stringWithUTF8String:headerKey];
|
||||
NSString *valueString = [NSString stringWithUTF8String:headerValue];
|
||||
|
||||
[customRequestHeader setObject:valueString forKey:keyString];
|
||||
}
|
||||
|
||||
- (void)removeCustomRequestHeader:(const char *)headerKey
|
||||
{
|
||||
NSString *keyString = [NSString stringWithUTF8String:headerKey];
|
||||
|
||||
if ([[customRequestHeader allKeys]containsObject:keyString]) {
|
||||
[customRequestHeader removeObjectForKey:keyString];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)clearCustomRequestHeader
|
||||
{
|
||||
[customRequestHeader removeAllObjects];
|
||||
}
|
||||
|
||||
- (const char *)getCustomRequestHeaderValue:(const char *)headerKey
|
||||
{
|
||||
NSString *keyString = [NSString stringWithUTF8String:headerKey];
|
||||
NSString *result = [customRequestHeader objectForKey:keyString];
|
||||
if (!result) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *s = [result UTF8String];
|
||||
char *r = (char *)malloc(strlen(s) + 1);
|
||||
strcpy(r, s);
|
||||
return r;
|
||||
}
|
||||
@end
|
||||
|
||||
extern "C" {
|
||||
void *_CWebViewPlugin_Init(const char *gameObjectName, BOOL transparent, const char *ua, BOOL enableWKWebView);
|
||||
void _CWebViewPlugin_Destroy(void *instance);
|
||||
void _CWebViewPlugin_SetMargins(
|
||||
void *instance, float left, float top, float right, float bottom, BOOL relative);
|
||||
void _CWebViewPlugin_SetVisibility(void *instance, BOOL visibility);
|
||||
void _CWebViewPlugin_SetAlertDialogEnabled(void *instance, BOOL visibility);
|
||||
void _CWebViewPlugin_SetScrollBounceEnabled(void *instance, BOOL enabled);
|
||||
BOOL _CWebViewPlugin_SetURLPattern(void *instance, const char *allowPattern, const char *denyPattern, const char *hookPattern);
|
||||
void _CWebViewPlugin_LoadURL(void *instance, const char *url);
|
||||
void _CWebViewPlugin_LoadHTML(void *instance, const char *html, const char *baseUrl);
|
||||
void _CWebViewPlugin_EvaluateJS(void *instance, const char *url);
|
||||
int _CWebViewPlugin_Progress(void *instance);
|
||||
BOOL _CWebViewPlugin_CanGoBack(void *instance);
|
||||
BOOL _CWebViewPlugin_CanGoForward(void *instance);
|
||||
void _CWebViewPlugin_GoBack(void *instance);
|
||||
void _CWebViewPlugin_GoForward(void *instance);
|
||||
void _CWebViewPlugin_AddCustomHeader(void *instance, const char *headerKey, const char *headerValue);
|
||||
void _CWebViewPlugin_RemoveCustomHeader(void *instance, const char *headerKey);
|
||||
void _CWebViewPlugin_ClearCustomHeader(void *instance);
|
||||
void _CWebViewPlugin_ClearCookies();
|
||||
void _CWebViewPlugin_SaveCookies();
|
||||
const char *_CWebViewPlugin_GetCookies(const char *url);
|
||||
const char *_CWebViewPlugin_GetCustomHeaderValue(void *instance, const char *headerKey);
|
||||
}
|
||||
|
||||
void *_CWebViewPlugin_Init(const char *gameObjectName, BOOL transparent, const char *ua, BOOL enableWKWebView)
|
||||
{
|
||||
CWebViewPlugin *webViewPlugin = [[CWebViewPlugin alloc] initWithGameObjectName:gameObjectName transparent:transparent ua:ua enableWKWebView:enableWKWebView];
|
||||
[_instances addObject:webViewPlugin];
|
||||
return (__bridge_retained void *)webViewPlugin;
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_Destroy(void *instance)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge_transfer CWebViewPlugin *)instance;
|
||||
[_instances removeObject:webViewPlugin];
|
||||
[webViewPlugin dispose];
|
||||
webViewPlugin = nil;
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_SetMargins(
|
||||
void *instance, float left, float top, float right, float bottom, BOOL relative)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin setMargins:left top:top right:right bottom:bottom relative:relative];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_SetVisibility(void *instance, BOOL visibility)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin setVisibility:visibility];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_SetAlertDialogEnabled(void *instance, BOOL enabled)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin setAlertDialogEnabled:enabled];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_SetScrollBounceEnabled(void *instance, BOOL enabled)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin setScrollBounceEnabled:enabled];
|
||||
}
|
||||
|
||||
BOOL _CWebViewPlugin_SetURLPattern(void *instance, const char *allowPattern, const char *denyPattern, const char *hookPattern)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return NO;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
return [webViewPlugin setURLPattern:allowPattern and:denyPattern and:hookPattern];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_LoadURL(void *instance, const char *url)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin loadURL:url];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_LoadHTML(void *instance, const char *html, const char *baseUrl)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin loadHTML:html baseURL:baseUrl];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_EvaluateJS(void *instance, const char *js)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin evaluateJS:js];
|
||||
}
|
||||
|
||||
int _CWebViewPlugin_Progress(void *instance)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return 0;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
return [webViewPlugin progress];
|
||||
}
|
||||
|
||||
BOOL _CWebViewPlugin_CanGoBack(void *instance)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return false;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
return [webViewPlugin canGoBack];
|
||||
}
|
||||
|
||||
BOOL _CWebViewPlugin_CanGoForward(void *instance)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return false;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
return [webViewPlugin canGoForward];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_GoBack(void *instance)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin goBack];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_GoForward(void *instance)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin goForward];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_AddCustomHeader(void *instance, const char *headerKey, const char *headerValue)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin addCustomRequestHeader:headerKey value:headerValue];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_RemoveCustomHeader(void *instance, const char *headerKey)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin removeCustomRequestHeader:headerKey];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_ClearCustomHeader(void *instance)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
[webViewPlugin clearCustomRequestHeader];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_ClearCookies()
|
||||
{
|
||||
[CWebViewPlugin clearCookies];
|
||||
}
|
||||
|
||||
void _CWebViewPlugin_SaveCookies()
|
||||
{
|
||||
[CWebViewPlugin saveCookies];
|
||||
}
|
||||
|
||||
const char *_CWebViewPlugin_GetCookies(const char *url)
|
||||
{
|
||||
return [CWebViewPlugin getCookies:url];
|
||||
}
|
||||
|
||||
const char *_CWebViewPlugin_GetCustomHeaderValue(void *instance, const char *headerKey)
|
||||
{
|
||||
if (instance == NULL)
|
||||
return NULL;
|
||||
CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance;
|
||||
return [webViewPlugin getCustomRequestHeaderValue:headerKey];
|
||||
}
|
||||
|
||||
#endif // __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fa8be30468d14ed99b685697effd624
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,25 @@
|
||||
mergeInto(LibraryManager.library, {
|
||||
_gree_unity_webview_init: function(name) {
|
||||
unityWebView.init(Pointer_stringify(name));
|
||||
},
|
||||
|
||||
_gree_unity_webview_setMargins: function (name, left, top, right, bottom) {
|
||||
unityWebView.setMargins(Pointer_stringify(name), left, top, right, bottom);
|
||||
},
|
||||
|
||||
_gree_unity_webview_setVisibility: function(name, visible) {
|
||||
unityWebView.setVisibility(Pointer_stringify(name), visible);
|
||||
},
|
||||
|
||||
_gree_unity_webview_loadURL: function(name, url) {
|
||||
unityWebView.loadURL(Pointer_stringify(name), Pointer_stringify(url));
|
||||
},
|
||||
|
||||
_gree_unity_webview_evaluateJS: function(name, js) {
|
||||
unityWebView.evaluateJS(Pointer_stringify(name), Pointer_stringify(js));
|
||||
},
|
||||
|
||||
_gree_unity_webview_destroy: function(name) {
|
||||
unityWebView.destroy(Pointer_stringify(name));
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8febae32308f463c9cd78b700cbe03d
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Facebook: WebGL
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
WebGL: WebGL
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user