feat: 初始化

This commit is contained in:
杭城小刘
2018-09-11 10:11:39 +08:00
committed by 杭城小刘
commit 8e5d2c9e7f
264 changed files with 12082 additions and 0 deletions

134
第一部分 iOS/1.10.md Normal file
View File

@@ -0,0 +1,134 @@
## UIWebView加载网页内容
可以通过本地文件、url等方式。
```objective-c
NSString *htmlPath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:htmlPath]];
[self.webView loadRequest:request];
```
## Native调用JavaScript
Native调用JS是通过UIWebView的stringByEvaluatingJavaScriptFromString 方法实现的该方法返回js脚本的执行结果。
```objective-c
[webView stringByEvaluatingJavaScriptFromString:@"Math.random();"];
```
实际上就是调用了网页的Window下的一个对象。如果我们需要让native端调用js方法那么这个js方法必须在window下可以访问到。
## JavaScript调用Native
反过来JavaScript调用Native并没有现成的API可以调用而是间接地通过一些其它手段来实现。UIWebView有个代理方法在UIWebView内发起的任何网络请求都可以通过delegate函数在Native层得到通知。由此思路我们就可以在UIWebView内发起一个自定义的网络请求通常是这样的格式**jsbridge://methodName?param1=value1&param2=value2...**
在UIWebView的delegate函数中我们判断请求的scheme如果request.URL.scheme是jsbridge那么就不进行网页内容的加载而是去执行相应的方法。方法名称就是request.URL.host。参数可以通过request.URL.query得到。
问题来了??
发起这样1个网络请求有2种方式。1:location.href .2iframe。通过location.href有个问题就是如果js多次调用原生的方法也就是location.href的值多次变化Native端只能接受到最后一次请求前面的请求会被忽略掉。
使用ifrmae方式以调用Native端的方法。
```javascript
var iFrame;
iFrame = document.createElement("iframe");
iFrame.style.height = "1px";
iFrame.style.width = "1px";
iFrame.style.display = "none";
iFrame.src = url;
document.body.appendChild(iFrame);
setTimeout(function(){
iFrame.remove();
},100);
```
举个🌰:
需求:
原生端提供一个UIWebView加载一个网页内容。还有1个按钮按钮点击一下网页增加一段段落文本。网页上有2个输入框用户输入数字点击按钮js将用户输入的参数告诉native端native去执行加法计算完成后将结果返回给js
```html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
<script language="javascript">
function loadURL(url) {
var iFrame;
iFrame = document.createElement("iframe");
iFrame.style.height = "1px";
iFrame.style.width = "1px";
iFrame.style.display = "none";
iFrame.src = url;
document.body.appendChild(iFrame);
setTimeout(function () {
iFrame.remove();
}, 100);
}
function receiveValue(value) {
alert("从原生拿到加法结果为:" + value);
}
function check() {
var par1 = document.getElementById("par1").value;
var par2 = document.getElementById("par2").value;
loadURL("JSBridge://plus?par1=" + par1 + "&par2=" + par2);
}
</script>
</head>
<body>
<input type="text" placeholder="请输入数字" id="par1" > +
<input type="text" placeholder="请输入数字" id="par2" >
<input type="button" value="=" onclick="check()" />
</body>
</html>
```
```objective-c
-(void)addContentToWebView{
NSString *jsString = @" var pNode = document.createElement(\"p\"); pNode.innerText = \"我是由原生代码调用js后将一段文件添加到html上也就是注入\";document.body.appendChild(pNode);";
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
}
-(NSInteger)plusparm:(NSInteger)par1 parm2:(NSInteger)par2{
return par1 + par2;
}
#pragma mark -- UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
NSURL *url = request.URL;
NSString *scheme = url.scheme;
NSString *method = url.host;
NSString *parms = url.query;
NSArray *pars = [parms componentsSeparatedByString:@"&"];
NSInteger par1 = [[pars[0] substringFromIndex:5] integerValue];
NSInteger par2 = [[pars[1] substringFromIndex:5] integerValue];
if ([scheme isEqualToString:@"jsbridge"]) {
//发现scheme是JSBridge那么就是自定义的URLscheme不去加载网页内容而拦截去处理事件。
if ([method isEqualToString:@"plus"]) {
NSInteger result = [self plusparm:par1 parm2:par2];
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"receiveValue(%@);",@(result)]];
}
return NO;
}
return YES;
}
```
## 同步和异步问题
js调用native是通过在一个网页上插入一个iframe这个iframe插入完了就完了执行的结果需要native另外调用stringByEvaluatingJavaScriptString 方法通知js。这明显是1个异步的调用。而stringByEvaluatingJavaScriptString方法会返回执行js脚本的结果。本质上是一个同步调用
所以js call native是异步native call js是同步。