OC与JS交互 -- 原生
来源:互联网 发布:淘宝介入卖家不举证 编辑:程序博客网 时间:2024/05/17 00:14
本文只是介绍简单的OC与JS交互
一、OC调用JS
<html> <header> <meta http-equiv="Content-Type" content="text/html"; charset="UTF-8"/> <title>zhaoName制作的网页</title> </header> <script Type = "text/javascript"> function login() { return 100; } </script> <body> 电话:10086 <button style="background:red; width:120px; height:30px;">call</button> </body></html>
调用webView的方法
// 获取网页的标题self.title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];// 调用JS中的函数NSLog(@"%@", [webView stringByEvaluatingJavaScriptFromString:@"login();"]);
该方法返回一个字符串,注意它是一个同步方法,若使用它执行非常耗时的操作会导致界面的卡顿。有两个解决方案:
1>使用官方推荐webView方法evaluateJavaScript:completionHandler:
2>自定义一个延迟执行方法来防止阻塞,或将方法放到setTimeout 中
二、JS调用OC
<html> <header> <meta http-equiv="Content-Type" content="text/html"; charset="UTF-8"/> <title>zhaoName制作的网页</title> </header> <script Type = "text/javascript"> function login() { location.href = 'zhaoName://openLibrary'; } </script> <body> 电话:10086 <button style="background:red; width:120px; height:30px;" onclick="login();">call</button> <br> <a href="https://github.com/zhaoName">zhaoName的Git</a> </body></html>
以下都是点击webView上的按钮”call”,调用OC中的方法
1、没有参数
/** * 通过这个方法完成JS调OC */- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ NSString *url = @"zhaoname://"; if ([request.URL.absoluteString hasPrefix:url]) { NSString *methodName = [request.URL.absoluteString substringFromIndex:url.length]; [self performSelector:NSSelectorFromString(methodName) withObject:nil]; return NO; } NSLog(@"想加载网络请求,不想做JS调用OC"); return YES;}- (void)openLibrary{ NSLog(@"JS调用OC方法--%s", __func__);}
2、一个参数
上面HTML中函数修改为
function login(){ location.href = 'zhaoName://sendMessage_?How are you';}
OC获取的路径path会自动删除’:’,所以此处用’_’代替。参数用?分割。(实际开发中需要你和写HTML的人共同制定JS调OC的规则)
/** * 通过这个方法完成JS掉OC */- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ NSString *url = @"zhaoname://"; if ([request.URL.absoluteString hasPrefix:url]) { // 路径 NSString *path = [request.URL.absoluteString substringFromIndex:url.length]; NSArray *subPaths = [path componentsSeparatedByString:@"?"]; // 获取方法名 NSString *methodName = [subPaths.firstObject stringByReplacingOccurrencesOfString:@"_" withString:@":"]; // 参数 NSString *para = subPaths.lastObject; [self performSelector:NSSelectorFromString(methodName) withObject:para]; return NO; } NSLog(@"想加载网络请求,不想做JS调用OC"); return YES;}- (void)sendMessage:(NSString *)message{ NSLog(@"JS调用OC方法--%s 参数:%@", __func__, message);}
3、两个参数
上面HTML中函数修改为
function login(){ location.href = 'zhaoName://sendMessage_sendName_?hehe&zhaoName';}
‘:’用’_’代替,方法名和参数用’?’分割,参数之间用’&’分割
/** * 通过这个方法完成JS掉OC */- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ NSString *url = @"zhaoname://"; if ([request.URL.absoluteString hasPrefix:url]) { // 路径 NSString *path = [request.URL.absoluteString substringFromIndex:url.length]; NSArray *subPaths = [path componentsSeparatedByString:@"?"]; // 获取方法名 NSString *methodName = [subPaths.firstObject stringByReplacingOccurrencesOfString:@"_" withString:@":"]; // 参数 NSArray *paras = nil; // 防止出现无参数的情况 if(subPaths.count == 2 || [subPaths.lastObject containsString:@"&"]) { paras = [subPaths.lastObject componentsSeparatedByString:@"&"]; } // 防止出现参数为空的情况 NSString *firstPara = paras.firstObject; NSString *secondPara = paras.count <= 1 ? nil : paras.lastObject; [self performSelector:NSSelectorFromString(methodName) withObject:firstPara withObject:secondPara]; return NO; } NSLog(@"想加载网络请求,不想做JS调用OC"); return YES;}- (void)sendMessage:(NSString *)message sendName:(NSString *)sendName{ NSLog(@"JS调用OC方法--%s 参数:%@ %@", __func__, message, sendName);}
4、三个及以上的参数
系统自带的方法performSelector最多只能传两个参数,所以有三个及以上的参数我们要借助NSInvocation类。
NSObject+Invocation.h文件
#import <Foundation/Foundation.h>@interface NSObject (Invocation)/** * 基于NSObject封装一个可用于JS调用OC方法的分类,适用于参数可有可无,可有多个 @param selector 方法名 @param parameters 参数 @return 返回值 */- (id)performSelector:(SEL)selector withParameters:(NSArray *)parameters;@end
NSObject+Invocation.m文件
#import "NSObject+Invocation.h"@implementation NSObject (Invocation)- (id)performSelector:(SEL)selector withParameters:(NSArray *)parameters{ // 方法签名 NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selector]; if(signature == nil) return nil; // 利用NSIvocation可以包装一次方法调用(设置方法调用者、方法名、参数、返回值) NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; // 设置方法调用者 invocation.target = self; // 设置方法名 invocation.selector = selector; // 设置方法参数 注意参数下标从2开始,0、1被系统占用 for(int i=0; i<parameters.count; i++) { id object = parameters[i]; if([object isKindOfClass:[NSNull class]]) continue; [invocation setArgument:&object atIndex:i+2]; } // 执行 [invocation invoke]; // 设置返回值 id returnValue = nil; // 兼顾没有返回值的方法 if(signature.methodReturnLength != 0) { [invocation getReturnValue:&returnValue];// 说明此方法有返回值 } return returnValue;}@end
上面HTML中函数修改为
function login(){ location.href = 'zhaoName://sendMessage_sendName_reviceName_?hehe&zhaoName&nicai';}
/** * 通过这个方法完成JS掉OC */- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ NSString *url = @"zhaoname://"; if ([request.URL.absoluteString hasPrefix:url]) { // 路径 NSString *path = [request.URL.absoluteString substringFromIndex:url.length]; NSArray *subPaths = [path componentsSeparatedByString:@"?"]; // 获取方法名 NSString *methodName = [subPaths.firstObject stringByReplacingOccurrencesOfString:@"_" withString:@":"]; // 参数 NSArray *paras = [subPaths.lastObject componentsSeparatedByString:@"&"]; // 调用OC中的方法 并获取返回值 NSString *result = [self performSelector:NSSelectorFromString(methodName) withParameters:paras]; NSLog(@"%@", result); return NO; } NSLog(@"想加载网络请求,不想做JS调用OC"); return YES;}- (NSString *)sendMessage:(NSString *)message sendName:(NSString *)sendName reviceName:(NSString *)reviceName{ NSLog(@"JS调用OC方法--%s 参数:%@ %@ %@", __func__, message, sendName, reviceName); return @"发信息";}
0 0
- OC与JS交互 -- 原生
- JS与原生OC的三种交互方式
- oc与js 交互
- oc与js交互
- JS与OC交互
- js与oc 交互
- OC与JS交互
- OC与JS交互
- OC与JS交互
- OC与JS交互
- OC 与JS 交互
- OC与JS交互
- oc 与 js 交互
- OC与JS交互
- OC与JS交互
- oc与js交互
- js与oc交互
- js 与oc 交互
- PKU 3468
- SpringBoot快速入门(一)
- Java网络爬虫--HTML DOM(HTML 基础)
- STM32L4超低功耗特性概述
- 函数:将网页提取的cookie转换成python用来模拟登录的cookie
- OC与JS交互 -- 原生
- 7.环境搭建-flume安装
- hibernate正向生成数据库表以及配置——hibernate.cfg.xml
- Professional C++ 01 A Crash Course in C++ 快速的C++基础知识复习
- Java的浅拷贝与深拷贝
- kaptcha 验证码使用
- php排序
- JavaScript Object使用toString
- autoconf 与 automake