Commit be4c7891 authored by JingChao's avatar JingChao

wkweview

parent 79bd7ff3
Pipeline #5002 canceled with stages
......@@ -20,11 +20,9 @@
<allow-navigation href="ionic://localhost/*" />
<allow-navigation href="gap://ready/*"/>
<allow-navigation href="tel:*" />
<allow-navigation href="http://wechat.hand-china.com/*" />
<allow-navigation href="http://180.104.121.66:8088/*" />
<allow-navigation href="https://docs.jiguang.cn/*" />
<allow-navigation href="https://www.rongcloud.cn/*" />
<allow-navigation href="https://www.pgyer.com/*" />
<access launch-external="yes" origin="tel:*" />
<access launch-external="yes" origin="sms:*" />
<preference name="ScrollEnabled" value="false" />
......
......@@ -11,6 +11,7 @@ module.exports = merge(prodEnv, {
basePath: '"http://180.104.121.66:8088/r/api/interface?sysName=XCMG_UAT&apiName="',
rootPath: '"http://180.104.121.66:8088/r/api"',
filePath: '"http://180.104.121.66:8088/r/api/app/fileViewSvc?sysName=XCMG_UAT&apiName=file_view&"',
fileUploadSvcPath:'"http://180.104.121.66:8088/r/api/app/fileUploadSvc?sysName=XCMG_UAT&apiName="',
ocrPath: '"http://180.104.121.66:8088/r/api"',
appId: '"com.xcmg.app.dev"',
currentVersion: '"1.8.6"',
......
{
"name": "cordova-plugin-hls-cloudroom",
"version": "1.0.0",
"description": "视频面签Cordova plugin定制化",
"cordova": {
"id": "cordova-plugin-hls-cloudroom",
"platforms": [
"android",
"ios"
]
},
"keywords": [
"ecosystem:cordova",
"cordova-android",
"cordova-ios"
],
"author": "Cordova中国技术交流组 群号:343034350",
"license": "Apache 2.0"
}
<?xml version='1.0' encoding='utf-8'?>
<plugin id="cordova-plugin-hls-cloudroom" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0">
<!-- metadata -->
<name>cordova-plugin-hls-cloudroom</name>
<description>视频面签Cordova plugin定制化</description>
<license>Apache 2.0</license>
<!-- javascript -->
<js-module name="CloudRoomService" src="www/hls.cordova.cloudroom.CloudRoomService.js">
<clobbers target="hls.cordova.cloudroom.CloudRoomService" />
</js-module>
<!-- android -->
<platform name="android">
<!-- config -->
<config-file target="res/xml/config.xml" parent="/*">
<feature name="CloudRoomService">
<param name="android-package" value="com.hls.cordova.cloudroom.CloudRoomService"/>
</feature>
</config-file>
<!-- source -->
<source-file src="src/android/CloudRoomService.java" target-dir="src/com/hls/cordova/cloudroom" />
</platform>
<!-- ios -->
<platform name="ios">
<!-- config -->
<config-file target="config.xml" parent="/*">
<feature name="CloudRoomService">
<param name="ios-package" value="CloudRoomService"/>
</feature>
</config-file>
<!-- source -->
<header-file src="src/ios/CloudRoomService.h" />
<source-file src="src/ios/CloudRoomService.m" />
</platform>
</plugin>
package com.hls.cordova.cloudroom;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.app.demo.Business;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class CloudRoomService extends CordovaPlugin {
private CallbackContext mCallbackContext;
private JSONObject obj;
private Business business;
private static final String TAG = "CloudRoomService";
// methods
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
this.mCallbackContext = callbackContext;
// Log.e(TAG, "execute: " + action + "," + webView);
String userId = "king";
JSONObject info = new JSONObject();
// if (args.length() > 0) {
// String a = args.getString(0);
// a = a.replace("\\", "");
// if (a.equals("null")) {
// obj = null;
// } else {
// obj = new JSONObject(a);
// }
// }
// 登录
if (action.equals("loginCloudRoom")) {
// if (obj.has("name")) {
// userId = obj.getString("name"); //接收js传过来的参数name password serverURL等
// }
if (business == null) {
business = new Business(webView.getContext());
}
business.doLogin(userId, callbackContext);
info.put("success", "1");
this.echo(info);
return true;
}else if (action.equals("helpYourSelf")) {
if(business == null){
Toast.makeText(webView.getContext(), "请先登录", Toast.LENGTH_SHORT).show();
}
business.helpYourSelf(callbackContext);
info.put("success", "1");
this.echo(info);
return true;
}
// default
return false;
}
private void echo(final JSONObject data) {
mCallbackContext.success(data);
}
private void echo(final String data) {
mCallbackContext.success(data);
}
}
\ No newline at end of file
#import <Foundation/Foundation.h>
#import <Cordova/CDVPlugin.h>
@interface CloudRoomService : CDVPlugin
@end
//
// CloudRoomService.h
// CloudroomDemo
//
// Created by youming on 2019/11/11.
//
#import "CloudRoomService.h"
#import "RecordHelper.h"
#import "YSProgressController.h"
#import "YouSelfController.h"
@interface CloudRoomService()<CloudroomHttpFileMgrCallBack, CloudroomVideoMgrCallBack>
/**
Cordova回调ID
*/
@property (nonatomic, copy) NSString *callbackId;
@property (nonatomic, strong) MeetInfo *meetInfo; /**< 会议信息 */
@end
@implementation CloudRoomService
#pragma mark - 登录
- (void)loginCloudRoom:(CDVInvokedUrlCommand *)command
{
[self.commandDelegate runInBackground:^{
dispatch_async(dispatch_get_main_queue(), ^{
//传递的数据参数
self.callbackId=command.callbackId;
// NSDictionary *cmdDict = (NSDictionary *)command.arguments.firstObject;
// NSLog(@"%@",cmdDict[@"msg"]);
CloudroomVideoMgr *cloudroomVideoMgr = [CloudroomVideoMgr shareInstance];
[cloudroomVideoMgr setMgrCallback:self];
RecordHelper *recordHelper = [RecordHelper shareInstance];
[recordHelper readInfo];
NSString *nickname=@"king";
if ([NSString stringCheckEmptyOrNil:nickname]) {
[HUDUtil hudShow:@"昵称不能为空!" delay:3 animated:YES];
return;
}
// 账号
NSString *account = recordHelper.account;
// 密码通过 MD5 以后(小写十六位)
NSString *pswd = recordHelper.pswd;
// 服务器地址
NSString *server = recordHelper.server;
if ([NSString stringCheckEmptyOrNil:server]) {
[HUDUtil hudShow:@"服务器地址不能为空!" delay:3 animated:YES];
return;
}
if ([NSString stringCheckEmptyOrNil:account]) {
[HUDUtil hudShow:@"账号不能为空!" delay:3 animated:YES];
return;
}
if ([NSString stringCheckEmptyOrNil:pswd]) {
[HUDUtil hudShow:@"密码不能为空!" delay:3 animated:YES];
return;
}
NSString *md5Pswd = [NSString md5:recordHelper.pswd];
RLog(@"server:%@ nickname:%@ account:%@ pswd:%@", server, nickname, account, md5Pswd);
//CloudroomVideoMgr *cloudroomVideoMgr = [CloudroomVideoMgr shareInstance];
LoginDat *loginData = [[LoginDat alloc] init];
[loginData setNickName:nickname];
[loginData setAuthAcnt:account];
[loginData setAuthPswd:md5Pswd];
[loginData setPrivAcnt:nickname];
[recordHelper writeAccount:account pswd:pswd server:server];
[recordHelper writeNickname:nickname];
// 域名转IP
/*
NSString *ip_Port;
if ([serverIP containsString:@":"]) {
NSArray <NSString *> *strs = [serverIP componentsSeparatedByString:@":"];
if ([strs count] > 1) {
NSString *hostToIP = [self _getIPFromHostName:[strs firstObject]];
ip_Port = [NSString stringWithFormat:@"%@:%@", hostToIP, strs[1]];
}
else {
ip_Port = [self _getIPFromHostName:[strs firstObject]];
}
}
else {
ip_Port = [self _getIPFromHostName:serverIP];
}
NSLog(@"IP+Port:%@", ip_Port);
*/
// 设置服务器地址
[[CloudroomVideoSDK shareInstance] setServerAddr:server];
[HUDUtil hudShowProgress:@"正在登录..." animated:YES];
// 开始上传日志
// [[CloudroomVideoSDK shareInstance] startLogReport:nickname server:@"logserver.cloudroom.com:12005"];
//
// [[CloudroomVideoSDK shareInstance] writeLog:SDK_LOG_LEVEL_INFO message:@"登录操作"];
// 发送"登录"命令
NSString *cookie = [NSString stringWithFormat:@"%f",CFAbsoluteTimeGetCurrent()];
[cloudroomVideoMgr login:loginData cookie:cookie];
});
}];
}
#pragma mark - 选择自助
- (void)helpYourSelf:(CDVInvokedUrlCommand *)command
{
[self.commandDelegate runInBackground:^{
dispatch_async(dispatch_get_main_queue(), ^{
self.callbackId=command.callbackId;
CloudroomHttpFileMgr *cloudroomHttpFileMgr = [CloudroomHttpFileMgr shareInstance];
[cloudroomHttpFileMgr setHttpFileMgrCallback:self];
CloudroomVideoMgr *cloudroomVideoMgr = [CloudroomVideoMgr shareInstance];
[cloudroomVideoMgr setMgrCallback:self];
RecordHelper *recordHelper = [RecordHelper shareInstance];
NSString *subject = [NSString stringWithFormat:@"%@的会议", [recordHelper nickname]];
NSString *cookie = [NSString stringWithFormat:@"%f", CFAbsoluteTimeGetCurrent()];
[[CloudroomVideoMgr shareInstance] createMeeting:subject createPswd:NO cookie:cookie];
// UIStoryboard *customer = [UIStoryboard storyboardWithName:@"Record" bundle:nil];
// YSProgressController *ysProgressVC = [customer instantiateViewControllerWithIdentifier:@"YSProgressController"];
// //[ysProgressVC setQueID:_queID];
// //[ysProgressVC setQueName:_queName];
// [ysProgressVC setQueID:780];
// [ysProgressVC setQueName:@"1"];
// ysProgressVC.modalPresentationStyle=UIModalPresentationFullScreen;
// if (ysProgressVC) {
// [self.viewController presentViewController:ysProgressVC animated:YES completion:nil];
// }
});
}];
}
//#pragma mark - 开始录制
//- (void)startRecord:(CDVInvokedUrlCommand *)command
//{
// [self.commandDelegate runInBackground:^{
// weakify(self)
// NSParameterAssert(self.meetInfo);
// dispatch_async(dispatch_get_main_queue(), ^{
// strongify(self)
// UIStoryboard *record = [UIStoryboard storyboardWithName:@"Record" bundle:nil];
// YouSelfController *yourselfVC = [record instantiateViewControllerWithIdentifier:@"YouSelfController"];
// [yourselfVC setMeetInfo:sSelf.meetInfo];
// yourselfVC.modalPresentationStyle=UIModalPresentationFullScreen;
// if (yourselfVC) {
// [self.viewController presentViewController:yourselfVC animated:YES completion:nil];
// }
// });
//
// }];
//
//}
#pragma mark - CloudroomVideoMgrCallBack---登录代理方法
- (void)loginSuccess:(NSString *)usrID cookie:(NSString *)cookie
{
[HUDUtil hudHiddenProgress:YES];
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:nil];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
}
- (void)loginFail:(CRVIDEOSDK_ERR_DEF)sdkErr cookie:(NSString *)cookie
{
[HUDUtil hudHiddenProgress:YES];
NSString *errorMsg=@"登录失败提示信息!";
// FIXME:概率性登录卡死不回调 added by king 20161216
if (sdkErr == CRVIDEOSDK_NOSERVER_RSP) {
errorMsg=@"服务器无响应!";
}
else if (sdkErr == CRVIDEOSDK_LOGINSTATE_ERROR) {
errorMsg= @"登陆状态不对!" ;
[[CloudroomVideoMgr shareInstance] logout];
}
else if (sdkErr == CRVIDEOSDK_ANCTPSWD_ERR) {
errorMsg= @"帐号密码不正确!" ;
}
else {
errorMsg= @"登录失败!";
}
[HUDUtil hudShow:errorMsg delay:3 animated:YES];
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:nil];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
}
#pragma mark - CloudroomVideoMgrCallBack
- (void)createMeetingSuccess:(MeetInfo *)meetInfo cookie:(NSString *)cookie
{
weakify(self)
self.meetInfo = meetInfo;
// NSParameterAssert(self.meetInfo);
dispatch_async(dispatch_get_main_queue(), ^{
strongify(self)
UIStoryboard *record = [UIStoryboard storyboardWithName:@"Record" bundle:nil];
YouSelfController *yourselfVC = [record instantiateViewControllerWithIdentifier:@"YouSelfController"];
[yourselfVC setMeetInfo:sSelf.meetInfo];
yourselfVC.modalPresentationStyle=UIModalPresentationFullScreen;
if (yourselfVC) {
[self.viewController presentViewController:yourselfVC animated:YES completion:^{
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:nil];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];}];
}
});
}
- (void)createMeetingFail:(CRVIDEOSDK_ERR_DEF)sdkErr cookie:(NSString *)cookie
{
[HUDUtil hudShow:@"创建会议失败" delay:3 animated:YES];
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:nil];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
}
// 掉线/被踢通知
- (void)lineOff:(CRVIDEOSDK_ERR_DEF)sdkErr
{
if (sdkErr == CRVIDEOSDK_USER_BEEN_KICKOUT) { // 被踢
[HUDUtil hudShow:@"您已被踢下线!" delay:3 animated:YES];
}
else { // 掉线
[HUDUtil hudShow:@"您已掉线!" delay:3 animated:YES];
}
}
- (void)dealloc
{
[[CloudroomHttpFileMgr shareInstance] stopMgr];
[[CloudroomVideoMeeting shareInstance] exitMeeting];
}
@end
cordova.define("cordova-plugin-hls-cloudroom.CloudRoomService", function(require, exports, module) {
var exec = require('cordova/exec');
function CloudRoomService(){};
CloudRoomService.prototype.loginCloudRoom=function(data,successCallback,errorCallback){
exec(successCallback,errorCallback,'CloudRoomService', 'loginCloudRoom', [data]);
}
CloudRoomService.prototype.helpYourSelf=function(data,successCallback,errorCallback){
exec(successCallback,errorCallback,'CloudRoomService', 'helpYourSelf', [data])
}
var cloudRoomPlugin=new CloudRoomService();
module.exports=cloudRoomPlugin;
});
......@@ -38,10 +38,12 @@
<platform name="android">
<config-file target="config.xml" parent="/*">
<allow-navigation href="http://localhost:8080/*"/>
<allow-navigation href="http://localhost/*"/>
<allow-navigation href="https://localhost/*"/>
<allow-navigation href="ionic://*"/>
<preference name="webView" value="com.ionicframework.cordova.webview.IonicWebViewEngine"/>
<feature name="IonicWebView">
<param name="android-package" value="com.ionicframework.cordova.webview.IonicWebView"/>
<param name="android-package" value="com.ionicframework.cordova.webview.IonicWebView"/>
</feature>
</config-file>
<source-file src="src/android/com/ionicframework/cordova/webview/IonicWebViewEngine.java" target-dir="src/com/ionicframework/cordova/webview"/>
......@@ -49,8 +51,11 @@
<source-file src="src/android/com/ionicframework/cordova/webview/AndroidProtocolHandler.java" target-dir="src/com/ionicframework/cordova/webview"/>
<source-file src="src/android/com/ionicframework/cordova/webview/UriMatcher.java" target-dir="src/com/ionicframework/cordova/webview"/>
<source-file src="src/android/com/ionicframework/cordova/webview/WebViewLocalServer.java" target-dir="src/com/ionicframework/cordova/webview"/>
<preference name="ANDROID_SUPPORT_ANNOTATIONS_VERSION" default="27.+"/>
<framework src="com.android.support:support-annotations:$ANDROID_SUPPORT_ANNOTATIONS_VERSION"/>
</platform>
<!-- ios -->
<!-- ios -->
<platform name="ios">
<js-module src="src/www/ios/ios-wkwebview-exec.js" name="ios-wkwebview-exec">
......@@ -58,12 +63,12 @@
</js-module>
<config-file target="config.xml" parent="/*">
<allow-navigation href="http://localhost:8080/*"/>
<allow-navigation href="http://127.0.0.1:8080/*"/>
<feature name="IonicWebView">
<param name="ios-package" value="CDVWKWebViewEngine"/>
</feature>
<preference name="CordovaWebViewEngine" value="CDVWKWebViewEngine"/>
<allow-navigation href="ionic://*"/>
<preference name="deployment-target" value="11.0"/>
<feature name="IonicWebView">
<param name="ios-package" value="CDVWKWebViewEngine"/>
</feature>
<preference name="CordovaWebViewEngine" value="CDVWKWebViewEngine"/>
</config-file>
<framework src="WebKit.framework" weak="true"/>
......@@ -74,43 +79,9 @@
<source-file src="src/ios/CDVWKWebViewUIDelegate.m"/>
<header-file src="src/ios/CDVWKProcessPoolFactory.h"/>
<source-file src="src/ios/CDVWKProcessPoolFactory.m"/>
<header-file src="src/ios/IONAssetHandler.h"/>
<source-file src="src/ios/IONAssetHandler.m"/>
<asset src="src/ios/wk-plugin.js" target="wk-plugin.js"/>
<!--GCDWebServer headers-->
<header-file src="src/ios/GCDWebServer/Core/GCDWebServer.h"/>
<header-file src="src/ios/GCDWebServer/Core/GCDWebServerConnection.h"/>
<header-file src="src/ios/GCDWebServer/Core/GCDWebServerFunctions.h"/>
<header-file src="src/ios/GCDWebServer/Core/GCDWebServerHTTPStatusCodes.h"/>
<header-file src="src/ios/GCDWebServer/Core/GCDWebServerPrivate.h"/>
<header-file src="src/ios/GCDWebServer/Core/GCDWebServerRequest.h"/>
<header-file src="src/ios/GCDWebServer/Core/GCDWebServerResponse.h"/>
<header-file src="src/ios/GCDWebServer/Requests/GCDWebServerDataRequest.h"/>
<header-file src="src/ios/GCDWebServer/Requests/GCDWebServerFileRequest.h"/>
<header-file src="src/ios/GCDWebServer/Requests/GCDWebServerMultiPartFormRequest.h"/>
<header-file src="src/ios/GCDWebServer/Requests/GCDWebServerURLEncodedFormRequest.h"/>
<header-file src="src/ios/GCDWebServer/Responses/GCDWebServerDataResponse.h"/>
<header-file src="src/ios/GCDWebServer/Responses/GCDWebServerErrorResponse.h"/>
<header-file src="src/ios/GCDWebServer/Responses/GCDWebServerFileResponse.h"/>
<header-file src="src/ios/GCDWebServer/Responses/GCDWebServerStreamedResponse.h"/>
<!--GCDWebServer source-->
<source-file src="src/ios/GCDWebServer/Core/GCDWebServer.m"/>
<source-file src="src/ios/GCDWebServer/Core/GCDWebServerConnection.m"/>
<source-file src="src/ios/GCDWebServer/Core/GCDWebServerFunctions.m"/>
<source-file src="src/ios/GCDWebServer/Core/GCDWebServerRequest.m"/>
<source-file src="src/ios/GCDWebServer/Core/GCDWebServerResponse.m"/>
<source-file src="src/ios/GCDWebServer/Requests/GCDWebServerDataRequest.m"/>
<source-file src="src/ios/GCDWebServer/Requests/GCDWebServerFileRequest.m"/>
<source-file src="src/ios/GCDWebServer/Requests/GCDWebServerMultiPartFormRequest.m"/>
<source-file src="src/ios/GCDWebServer/Requests/GCDWebServerURLEncodedFormRequest.m"/>
<source-file src="src/ios/GCDWebServer/Responses/GCDWebServerDataResponse.m"/>
<source-file src="src/ios/GCDWebServer/Responses/GCDWebServerErrorResponse.m"/>
<source-file src="src/ios/GCDWebServer/Responses/GCDWebServerFileResponse.m"/>
<source-file src="src/ios/GCDWebServer/Responses/GCDWebServerStreamedResponse.m"/>
<!--GCDWebServer dependencies-->
<framework src="libz.tbd"/>
</platform>
<issue>https://github.com/ionic-team/cordova-plugin-ionic-webview/issues</issue>
<author>Ionic Team</author>
......
......@@ -26,18 +26,8 @@ public class AndroidProtocolHandler {
this.context = context;
}
public InputStream openAsset(String path, String assetPath) throws IOException {
if (path.startsWith(assetPath + "/_file_")) {
if (path.contains("content://")) {
String contentPath = path.replace(assetPath + "/_file_/", "content://");
return context.getContentResolver().openInputStream(Uri.parse(contentPath));
} else {
String filePath = path.replace(assetPath + "/_file_/", "");
return new FileInputStream(new File(filePath));
}
} else {
return context.getAssets().open(path, AssetManager.ACCESS_STREAMING);
}
public InputStream openAsset(String path) throws IOException {
return context.getAssets().open(path, AssetManager.ACCESS_STREAMING);
}
public InputStream openResource(Uri uri) {
......@@ -78,10 +68,28 @@ public class AndroidProtocolHandler {
}
public InputStream openFile(String filePath) throws IOException {
File localFile = new File(filePath);
String realPath = filePath.replace(WebViewLocalServer.fileStart, "");
File localFile = new File(realPath);
return new FileInputStream(localFile);
}
public InputStream openContentUrl(Uri uri) throws IOException {
Integer port = uri.getPort();
String realPath;
if (port == -1) {
realPath = uri.toString().replace(uri.getScheme() + "://" + uri.getHost() + WebViewLocalServer.contentStart, "content:/");
} else {
realPath = uri.toString().replace(uri.getScheme() + "://" + uri.getHost() + ":" + port + WebViewLocalServer.contentStart, "content:/");
}
InputStream stream = null;
try {
stream = context.getContentResolver().openInputStream(Uri.parse(realPath));
} catch (SecurityException e) {
Log.e(TAG, "Unable to open content URL: " + uri, e);
}
return stream;
}
private static int getFieldId(Context context, String assetType, String assetName)
throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
Class<?> d = context.getClassLoader()
......
package com.ionicframework.cordova.webview;
import android.app.Activity;
import android.content.SharedPreferences;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
......@@ -7,6 +10,9 @@ import org.json.JSONException;
public class IonicWebView extends CordovaPlugin {
public static final String WEBVIEW_PREFS_NAME = "WebViewSettings";
public static final String CDV_SERVER_PATH = "serverBasePath";
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if (action.equals("setServerBasePath")) {
......@@ -14,12 +20,19 @@ public class IonicWebView extends CordovaPlugin {
cordova.getActivity().runOnUiThread(new Runnable() {
public void run() {
((IonicWebViewEngine)webView.getEngine()).setServerBasePath(path);
webView.loadUrl(webView.getUrl());
}
});
return true;
} else if (action.equals("getServerBasePath")) {
callbackContext.success(((IonicWebViewEngine)webView.getEngine()).getServerBasePath());
return true;
} else if (action.equals("persistServerBasePath")) {
String path = ((IonicWebViewEngine)webView.getEngine()).getServerBasePath();
SharedPreferences prefs = cordova.getActivity().getApplicationContext().getSharedPreferences(WEBVIEW_PREFS_NAME, Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(CDV_SERVER_PATH, path);
editor.apply();
return true;
}
return false;
}
......
package com.ionicframework.cordova.webview;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import org.apache.cordova.ConfigXmlParser;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPreferences;
import org.apache.cordova.CordovaResourceApi;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaWebViewEngine;
import org.apache.cordova.NativeToJsMessageQueue;
import org.apache.cordova.PluginManager;
import org.apache.cordova.engine.SystemWebViewClient;
......@@ -25,8 +31,13 @@ public class IonicWebViewEngine extends SystemWebViewEngine {
private WebViewLocalServer localServer;
private String CDV_LOCAL_SERVER;
private String scheme;
private static final String LAST_BINARY_VERSION_CODE = "lastBinaryVersionCode";
private static final String LAST_BINARY_VERSION_NAME = "lastBinaryVersionName";
/** Used when created via reflection. */
/**
* Used when created via reflection.
*/
public IonicWebViewEngine(Context context, CordovaPreferences preferences) {
super(new SystemWebView(context), preferences);
Log.d(TAG, "Ionic Web View Engine Starting Right Up 1...");
......@@ -49,19 +60,58 @@ public class IonicWebViewEngine extends SystemWebViewEngine {
ConfigXmlParser parser = new ConfigXmlParser();
parser.parse(cordova.getActivity());
String port = preferences.getString("WKPort", "8080");
CDV_LOCAL_SERVER = "http://localhost:" + port;
String hostname = preferences.getString("Hostname", "localhost");
scheme = preferences.getString("Scheme", "http");
CDV_LOCAL_SERVER = scheme + "://" + hostname;
localServer = new WebViewLocalServer(cordova.getActivity(), "localhost:" + port, true, parser);
WebViewLocalServer.AssetHostingDetails ahd = localServer.hostAssets("www");
localServer = new WebViewLocalServer(cordova.getActivity(), hostname, true, parser, scheme);
localServer.hostAssets("www");
webView.setWebViewClient(new ServerClient(this, parser));
super.init(parentWebView, cordova, client, resourceApi, pluginManager, nativeToJsMessageQueue);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
final WebSettings settings = webView.getSettings();
int mode = preferences.getInteger("MixedContentMode", 0);
settings.setMixedContentMode(mode);
}
SharedPreferences prefs = cordova.getActivity().getApplicationContext().getSharedPreferences(IonicWebView.WEBVIEW_PREFS_NAME, Activity.MODE_PRIVATE);
String path = prefs.getString(IonicWebView.CDV_SERVER_PATH, null);
if (!isDeployDisabled() && !isNewBinary() && path != null && !path.isEmpty()) {
setServerBasePath(path);
}
}
private boolean isNewBinary() {
String versionCode = "";
String versionName = "";
SharedPreferences prefs = cordova.getActivity().getApplicationContext().getSharedPreferences(IonicWebView.WEBVIEW_PREFS_NAME, Activity.MODE_PRIVATE);
String lastVersionCode = prefs.getString(LAST_BINARY_VERSION_CODE, null);
String lastVersionName = prefs.getString(LAST_BINARY_VERSION_NAME, null);
try {
PackageInfo pInfo = this.cordova.getActivity().getPackageManager().getPackageInfo(this.cordova.getActivity().getPackageName(), 0);
versionCode = Integer.toString(pInfo.versionCode);
versionName = pInfo.versionName;
} catch(Exception ex) {
Log.e(TAG, "Unable to get package info", ex);
}
if (!versionCode.equals(lastVersionCode) || !versionName.equals(lastVersionName)) {
SharedPreferences.Editor editor = prefs.edit();
editor.putString(LAST_BINARY_VERSION_CODE, versionCode);
editor.putString(LAST_BINARY_VERSION_NAME, versionName);
editor.putString(IonicWebView.CDV_SERVER_PATH, "");
editor.apply();
return true;
}
return false;
}
private class ServerClient extends SystemWebViewClient
{
private boolean isDeployDisabled() {
return preferences.getBoolean("DisableDeploy", false);
}
private class ServerClient extends SystemWebViewClient {
private ConfigXmlParser parser;
public ServerClient(SystemWebViewEngine parentEngine, ConfigXmlParser parser) {
......@@ -69,17 +119,30 @@ public class IonicWebViewEngine extends SystemWebViewEngine {
this.parser = parser;
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
return localServer.shouldInterceptRequest(request);
return localServer.shouldInterceptRequest(request.getUrl(), request);
}
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
return localServer.shouldInterceptRequest(Uri.parse(url), null);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if (url.equals(parser.getLaunchUrl())) {
String launchUrl = parser.getLaunchUrl();
if (!launchUrl.contains(WebViewLocalServer.httpsScheme) && !launchUrl.contains(WebViewLocalServer.httpScheme) && url.equals(launchUrl)) {
view.stopLoading();
view.loadUrl(CDV_LOCAL_SERVER);
// When using a custom scheme the app won't load if server start url doesn't end in /
String startUrl = CDV_LOCAL_SERVER;
if (!scheme.equalsIgnoreCase(WebViewLocalServer.httpsScheme) && !scheme.equalsIgnoreCase(WebViewLocalServer.httpScheme)) {
startUrl += "/";
}
view.loadUrl(startUrl);
}
}
......@@ -87,17 +150,17 @@ public class IonicWebViewEngine extends SystemWebViewEngine {
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
view.loadUrl("javascript:(function() { " +
"window.WEBVIEW_SERVER_URL = '" + CDV_LOCAL_SERVER + "'" +
"window.WEBVIEW_SERVER_URL = '" + CDV_LOCAL_SERVER + "';" +
"})()");
}
}
public void setServerBasePath(String path){
public void setServerBasePath(String path) {
localServer.hostFiles(path);
webView.loadUrl(CDV_LOCAL_SERVER);
}
public String getServerBasePath() {
return this.localServer.getBasePath();
}
}
......@@ -25,7 +25,6 @@
@property (nonatomic, strong, readonly) id <WKUIDelegate> uiDelegate;
@property (nonatomic, strong) NSString * basePath;
-(void)setServerPath:(NSString *) path;
-(void)setServerBasePath:(CDVInvokedUrlCommand*)command;
-(void)getServerBasePath:(CDVInvokedUrlCommand*)command;
......
This diff is collapsed.
/*
Copyright (c) 2012-2015, Pierre-Olivier Latour
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* The name of Pierre-Olivier Latour may not be used to endorse
or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "GCDWebServer.h"
NS_ASSUME_NONNULL_BEGIN
@class GCDWebServerHandler;
/**
* The GCDWebServerConnection class is instantiated by GCDWebServer to handle
* each new HTTP connection. Each instance stays alive until the connection is
* closed.
*
* You cannot use this class directly, but it is made public so you can
* subclass it to override some hooks. Use the GCDWebServerOption_ConnectionClass
* option for GCDWebServer to install your custom subclass.
*
* @warning The GCDWebServerConnection retains the GCDWebServer until the
* connection is closed.
*/
@interface GCDWebServerConnection : NSObject
/**
* Returns the GCDWebServer that owns the connection.
*/
@property(nonatomic, readonly) GCDWebServer* server;
/**
* Returns YES if the connection is using IPv6.
*/
@property(nonatomic, readonly, getter=isUsingIPv6) BOOL usingIPv6;
/**
* Returns the address of the local peer (i.e. server) of the connection
* as a raw "struct sockaddr".
*/
@property(nonatomic, readonly) NSData* localAddressData;
/**
* Returns the address of the local peer (i.e. server) of the connection
* as a string.
*/
@property(nonatomic, readonly) NSString* localAddressString;
/**
* Returns the address of the remote peer (i.e. client) of the connection
* as a raw "struct sockaddr".
*/
@property(nonatomic, readonly) NSData* remoteAddressData;
/**
* Returns the address of the remote peer (i.e. client) of the connection
* as a string.
*/
@property(nonatomic, readonly) NSString* remoteAddressString;
/**
* Returns the total number of bytes received from the remote peer (i.e. client)
* so far.
*/
@property(nonatomic, readonly) NSUInteger totalBytesRead;
/**
* Returns the total number of bytes sent to the remote peer (i.e. client) so far.
*/
@property(nonatomic, readonly) NSUInteger totalBytesWritten;
@end
/**
* Hooks to customize the behavior of GCDWebServer HTTP connections.
*
* @warning These methods can be called on any GCD thread.
* Be sure to also call "super" when overriding them.
*/
@interface GCDWebServerConnection (Subclassing)
/**
* This method is called when the connection is opened.
*
* Return NO to reject the connection e.g. after validating the local
* or remote address.
*/
- (BOOL)open;
/**
* This method is called whenever data has been received
* from the remote peer (i.e. client).
*
* @warning Do not attempt to modify this data.
*/
- (void)didReadBytes:(const void*)bytes length:(NSUInteger)length;
/**
* This method is called whenever data has been sent
* to the remote peer (i.e. client).
*
* @warning Do not attempt to modify this data.
*/
- (void)didWriteBytes:(const void*)bytes length:(NSUInteger)length;
/**
* This method is called after the HTTP headers have been received to
* allow replacing the request URL by another one.
*
* The default implementation returns the original URL.
*/
- (NSURL*)rewriteRequestURL:(NSURL*)url withMethod:(NSString*)method headers:(NSDictionary*)headers;
/**
* Assuming a valid HTTP request was received, this method is called before
* the request is processed.
*
* Return a non-nil GCDWebServerResponse to bypass the request processing entirely.
*
* The default implementation checks for HTTP authentication if applicable
* and returns a barebone 401 status code response if authentication failed.
*/
- (nullable GCDWebServerResponse*)preflightRequest:(GCDWebServerRequest*)request;
/**
* Assuming a valid HTTP request was received and -preflightRequest: returned nil,
* this method is called to process the request by executing the handler's
* process block.
*/
- (void)processRequest:(GCDWebServerRequest*)request completion:(GCDWebServerCompletionBlock)completion;
/**
* Assuming a valid HTTP request was received and either -preflightRequest:
* or -processRequest:completion: returned a non-nil GCDWebServerResponse,
* this method is called to override the response.
*
* You can either modify the current response and return it, or return a
* completely new one.
*
* The default implementation replaces any response matching the "ETag" or
* "Last-Modified-Date" header of the request by a barebone "Not-Modified" (304)
* one.
*/
- (GCDWebServerResponse*)overrideResponse:(GCDWebServerResponse*)response forRequest:(GCDWebServerRequest*)request;
/**
* This method is called if any error happens while validing or processing
* the request or if no GCDWebServerResponse was generated during processing.
*
* @warning If the request was invalid (e.g. the HTTP headers were malformed),
* the "request" argument will be nil.
*/
- (void)abortRequest:(nullable GCDWebServerRequest*)request withStatusCode:(NSInteger)statusCode;
/**
* Called when the connection is closed.
*/
- (void)close;
@end
NS_ASSUME_NONNULL_END
/*
Copyright (c) 2012-2015, Pierre-Olivier Latour
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* The name of Pierre-Olivier Latour may not be used to endorse
or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
#ifdef __cplusplus
extern "C" {
#endif
/**
* Converts a file extension to the corresponding MIME type.
* If there is no match, "application/octet-stream" is returned.
*
* Overrides allow to customize the built-in mapping from extensions to MIME
* types. Keys of the dictionary must be lowercased file extensions without
* the period, and the values must be the corresponding MIME types.
*/
NSString* GCDWebServerGetMimeTypeForExtension(NSString* extension, NSDictionary* _Nullable overrides);
/**
* Add percent-escapes to a string so it can be used in a URL.
* The legal characters ":@/?&=+" are also escaped to ensure compatibility
* with URL encoded forms and URL queries.
*/
NSString* _Nullable GCDWebServerEscapeURLString(NSString* string);
/**
* Unescapes a URL percent-encoded string.
*/
NSString* _Nullable GCDWebServerUnescapeURLString(NSString* string);
/**
* Extracts the unescaped names and values from an
* "application/x-www-form-urlencoded" form.
* http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1
*/
NSDictionary* GCDWebServerParseURLEncodedForm(NSString* form);
/**
* On OS X, returns the IPv4 or IPv6 address as a string of the primary
* connected service or nil if not available.
*
* On iOS, returns the IPv4 or IPv6 address as a string of the WiFi
* interface if connected or nil otherwise.
*/
NSString* _Nullable GCDWebServerGetPrimaryIPAddress(BOOL useIPv6);
/**
* Converts a date into a string using RFC822 formatting.
* https://tools.ietf.org/html/rfc822#section-5
* https://tools.ietf.org/html/rfc1123#section-5.2.14
*/
NSString* GCDWebServerFormatRFC822(NSDate* date);
/**
* Converts a RFC822 formatted string into a date.
* https://tools.ietf.org/html/rfc822#section-5
* https://tools.ietf.org/html/rfc1123#section-5.2.14
*
* @warning Timezones other than GMT are not supported by this function.
*/
NSDate* _Nullable GCDWebServerParseRFC822(NSString* string);
/**
* Converts a date into a string using IOS 8601 formatting.
* http://tools.ietf.org/html/rfc3339#section-5.6
*/
NSString* GCDWebServerFormatISO8601(NSDate* date);
/**
* Converts a ISO 8601 formatted string into a date.
* http://tools.ietf.org/html/rfc3339#section-5.6
*
* @warning Only "calendar" variant is supported at this time and timezones
* other than GMT are not supported either.
*/
NSDate* _Nullable GCDWebServerParseISO8601(NSString* string);
#ifdef __cplusplus
}
#endif
NS_ASSUME_NONNULL_END
/*
Copyright (c) 2012-2015, Pierre-Olivier Latour
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* The name of Pierre-Olivier Latour may not be used to endorse
or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
// http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
#import <Foundation/Foundation.h>
/**
* Convenience constants for "informational" HTTP status codes.
*/
typedef NS_ENUM(NSInteger, GCDWebServerInformationalHTTPStatusCode) {
kGCDWebServerHTTPStatusCode_Continue = 100,
kGCDWebServerHTTPStatusCode_SwitchingProtocols = 101,
kGCDWebServerHTTPStatusCode_Processing = 102
};
/**
* Convenience constants for "successful" HTTP status codes.
*/
typedef NS_ENUM(NSInteger, GCDWebServerSuccessfulHTTPStatusCode) {
kGCDWebServerHTTPStatusCode_OK = 200,
kGCDWebServerHTTPStatusCode_Created = 201,
kGCDWebServerHTTPStatusCode_Accepted = 202,
kGCDWebServerHTTPStatusCode_NonAuthoritativeInformation = 203,
kGCDWebServerHTTPStatusCode_NoContent = 204,
kGCDWebServerHTTPStatusCode_ResetContent = 205,
kGCDWebServerHTTPStatusCode_PartialContent = 206,
kGCDWebServerHTTPStatusCode_MultiStatus = 207,
kGCDWebServerHTTPStatusCode_AlreadyReported = 208
};
/**
* Convenience constants for "redirection" HTTP status codes.
*/
typedef NS_ENUM(NSInteger, GCDWebServerRedirectionHTTPStatusCode) {
kGCDWebServerHTTPStatusCode_MultipleChoices = 300,
kGCDWebServerHTTPStatusCode_MovedPermanently = 301,
kGCDWebServerHTTPStatusCode_Found = 302,
kGCDWebServerHTTPStatusCode_SeeOther = 303,
kGCDWebServerHTTPStatusCode_NotModified = 304,
kGCDWebServerHTTPStatusCode_UseProxy = 305,
kGCDWebServerHTTPStatusCode_TemporaryRedirect = 307,
kGCDWebServerHTTPStatusCode_PermanentRedirect = 308
};
/**
* Convenience constants for "client error" HTTP status codes.
*/
typedef NS_ENUM(NSInteger, GCDWebServerClientErrorHTTPStatusCode) {
kGCDWebServerHTTPStatusCode_BadRequest = 400,
kGCDWebServerHTTPStatusCode_Unauthorized = 401,
kGCDWebServerHTTPStatusCode_PaymentRequired = 402,
kGCDWebServerHTTPStatusCode_Forbidden = 403,
kGCDWebServerHTTPStatusCode_NotFound = 404,
kGCDWebServerHTTPStatusCode_MethodNotAllowed = 405,
kGCDWebServerHTTPStatusCode_NotAcceptable = 406,
kGCDWebServerHTTPStatusCode_ProxyAuthenticationRequired = 407,
kGCDWebServerHTTPStatusCode_RequestTimeout = 408,
kGCDWebServerHTTPStatusCode_Conflict = 409,
kGCDWebServerHTTPStatusCode_Gone = 410,
kGCDWebServerHTTPStatusCode_LengthRequired = 411,
kGCDWebServerHTTPStatusCode_PreconditionFailed = 412,
kGCDWebServerHTTPStatusCode_RequestEntityTooLarge = 413,
kGCDWebServerHTTPStatusCode_RequestURITooLong = 414,
kGCDWebServerHTTPStatusCode_UnsupportedMediaType = 415,
kGCDWebServerHTTPStatusCode_RequestedRangeNotSatisfiable = 416,
kGCDWebServerHTTPStatusCode_ExpectationFailed = 417,
kGCDWebServerHTTPStatusCode_UnprocessableEntity = 422,
kGCDWebServerHTTPStatusCode_Locked = 423,
kGCDWebServerHTTPStatusCode_FailedDependency = 424,
kGCDWebServerHTTPStatusCode_UpgradeRequired = 426,
kGCDWebServerHTTPStatusCode_PreconditionRequired = 428,
kGCDWebServerHTTPStatusCode_TooManyRequests = 429,
kGCDWebServerHTTPStatusCode_RequestHeaderFieldsTooLarge = 431
};
/**
* Convenience constants for "server error" HTTP status codes.
*/
typedef NS_ENUM(NSInteger, GCDWebServerServerErrorHTTPStatusCode) {
kGCDWebServerHTTPStatusCode_InternalServerError = 500,
kGCDWebServerHTTPStatusCode_NotImplemented = 501,
kGCDWebServerHTTPStatusCode_BadGateway = 502,
kGCDWebServerHTTPStatusCode_ServiceUnavailable = 503,
kGCDWebServerHTTPStatusCode_GatewayTimeout = 504,
kGCDWebServerHTTPStatusCode_HTTPVersionNotSupported = 505,
kGCDWebServerHTTPStatusCode_InsufficientStorage = 507,
kGCDWebServerHTTPStatusCode_LoopDetected = 508,
kGCDWebServerHTTPStatusCode_NotExtended = 510,
kGCDWebServerHTTPStatusCode_NetworkAuthenticationRequired = 511
};
#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>
@interface IONAssetHandler : NSObject <WKURLSchemeHandler>
@property (nonatomic, strong) NSString * basePath;
@property (nonatomic, strong) NSString * scheme;
-(void)setAssetPath:(NSString *)assetPath;
- (instancetype)initWithBasePath:(NSString *)basePath andScheme:(NSString *)scheme;
@end
This diff is collapsed.
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment