UIWebView
加载文件
NSURL *url = [[NSBundle mainBundle] URLForResource:@"demo.html" withExtension:nil];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
利用 WebView 加载文件功能,用于在 QQ 之类的软件中查看对方发送的文件(Word, Excel, PDF等)
与 js 交互
OC 调用 JS
// 执行 js
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title;"];
NSLog(@"%@", title);
[webView stringByEvaluatingJavaScriptFromString:@"clickme();"];
}
JS 调用 OC
- 解释自定义协议
href="myfunc:///showMessage:/晚上请你吃饭:D"
调用 OC 中的方法 `showMessage:` 显示内容 `晚上请你吃饭:D`
- 准备代码
- (void)showMessage:(NSString *)msg {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:msg preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[self dismissViewControllerAnimated:YES completion:nil];
}]];
[self presentViewController:alert animated:YES completion:nil];
}
- 代理方法
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(@"%@", request.URL);
return YES;
}
在 OC 中,如果代理方法返回 BOOL 类型,返回 YES 会正常执行
- 代码实现
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(@"%@ %zd", request.URL, navigationType);
// 判断是否自定义协议
if (![request.URL.scheme isEqual:@"myfunc"]) {
return YES;
}
NSLog(@"自定义协议 %@", request.URL.pathComponents);
if (request.URL.pathComponents.count != 3) {
NSLog(@"自定义协议格式错误");
return NO;
}
NSString *methodName = request.URL.pathComponents[1];
NSString *param = request.URL.pathComponents[2];
SEL func = NSSelectorFromString(methodName);
[self performSelector:func withObject:param];
return NO;
}
- 警告处理
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[self performSelector:func withObject:param];
#pragma clang diagnostic pop
使用预编译指令,可以让编译器忽略指定警告信息,这一技巧在非常多的第三方框架中使用
利用运行时的发送消息方法
- 导入头文件
#import <objc/message.h>
- 发送消息
((void (*)(id, SEL, NSString *))objc_msgSend)(self, func, param);
- 格式说明
((发送消息格式声明)objc_msgSend)(对象, 调用方法的 SEL, 参数...)
// 发送消息格式声明
返回值 (*)(id, SEL, 参数类型...)