先阐述背景:
app需要集成一个本地的html文件,并且在调用时url带参数。如:
analysis.html?sId=417492&apiUrl=http://192.168.100.1:8888
1、传统方法。
首先我采取了之前的本地网页集成方法
//htmlPath即是本地html的路径,filename即是html名
NSString *filePath = [htmlPath stringByAppendingPathComponent:filename];
NSString *htmlString = [[NSString alloc]initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
[webView loadHTMLString:htmlString baseURL:[NSURL fileURLWithPath:htmlPath]];
传入文件名filename = @"analysis.html?sId=417492&apiUrl=http://192.168.100.1:8888";
发现htmlString为空,并不能通过带参数的文件地址找到对应的文件。
后来也试过NSString的initWithContentsOfURL
等方法。均无法实现需求。
放弃。
2、relativeToURL
之后我找到了另一个方法
NSString *filePath = [htmlPath stringByAppendingPathComponent:filename];
NSURL *fileUrl = [NSURL URLWithString:@"?sId=417492&apiUrl=http://192.168.100.1:8888"
relativeToURL:[NSURL fileURLWithPath:filePath]];
NSURLRequest *request = [NSURLRequest requestWithURL: fileUrl];
[webView loadRequest:request];
经试验,该方法可以正常打开html文件,并将参数传入。
需要注意的是,有时候我们发现使用[NSURL URLWithString:filePath]
也可以达到相同的效果,在UIWebView是这样的,但放到WKWebView就行不通了,所以还是建议统一使用:[NSURL fileURLWithPath:filePath]
。
问题解决,于是轻松加惬意得继续扩展。还有没有更简单的方法呢?
3、直接拼URL
基于方法二,既然通过url,为什么不能直接将参数拼接在url后面呢。仔细看,其实这种用法其实很像网络请求的Get方法,所以
//htmlPath即是本地html的路径,filename=@"analysis.html?sId=417492&apiUrl=http://192.168.100.1:8888"
NSString *filePath = [htmlPath stringByAppendingPathComponent:filename];
接下来将path转化为url就好了吧?
NSURL *fileUrl = [NSURL fileURLWithPath: filePath];
NSURLRequest *request = [NSURLRequest requestWithURL: fileUrl];
[webview loadRequest:request];
然而并没有。网页并没有加载显示出来,自然参数也并没有传递进去。难道我想错了?
打印一下url发现
Printing description of fileUrl:
file:///var/containers/Bundle/Application/39A2343F-37E1-42B4-8D7E-F373A153BF1D/UrlDemo.app/statis/analysis.html%3FsId=417492&apiUrl=192.168.100.1:8888
发现问题:url中的"?"被转码成"%3F",直接导致整个url的解析失败。再然后,我试过对参数编码,对path编码,最后发现,是在方法二中建议使用的fileURLWithPath:
的问题,在该方法中,会自动进行编码。不推荐使用的URLWithString:
方法反而不会。于是为了解决编码问题,我尝试着使用URLWithString将Path转化成URL
NSURL *fileUrl = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@", filePath]];
就是手动拼接一个文件头。打印url正常,编译正常,运行正常,正确打开网页并传递了参数。
但是总觉得手动拼一个头做法不太正规,于是继续挖坑。
4、NSURLComponents
直接上代码
NSString *filePath = [htmlPath stringByAppendingPathComponent:filename];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath isDirectory:NO];//此部分没有?所以没有问题,isDirectory=YES会导致多一层目录。
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:fileUrl resolvingAgainstBaseURL:NO];
[urlComponents setQueryItems:@[[NSURLQueryItem queryItemWithName:@"sId" value:@"417492"], [NSURLQueryItem queryItemWithName:@"apiUrl" value:@"http://192.168.100.1:8888"]]];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:urlComponents.URL];
正确实现需求。
综上,解决问题的方法永远不止一个。
不求甚解是一种态度;
浅尝辄止是一种态度;
刨根问底是一种态度;
精益求精是一种态度。
浅尝辄止了~