OC与JS之间的交互

来源:互联网 发布:超社会 知乎 编辑:程序博客网 时间:2024/06/05 14:28

最近产品提出需要加我目前维护的登录SDK,添加到公司的H5游戏上去,相当于做一个H5游戏的微端。然后以前也没具体接触过OC和JS的交互,觉得很新奇。其实了解了大致的做法,并不难实现。下面我就用我这边写的东西做个例子。


需求是这样的:在调用我客户端的登录SDK之前,需要知道H5游戏那边的登录状态,如果没有登录,则需要调出SDK的登录界面,用户点击登录,SDK返回token,将得到的token传递给H5游戏,H5游戏登录到游戏内。


直接上代码

在.h声明好和JS那边协定好的,JS要调用的方法

#import <UIKit/UIKit.h>#import <JavaScriptCore/JavaScriptCore.h>@protocol JSObjcDelegate <JSExport>- (void)isLogin:(BOOL)isLogin;- (void)logout;@end@interface ViewController : UIViewController<JSObjcDelegate>@end

在.m中初始化UIWebview,遵守UIWebview的UIWebViewDelegate协议,在webViewDidFinishLoad代理方法中注册OC将要提供给JS的方法。

JS调用OC的代码主要是在webViewDidFinishLoad注册OC的方法,实现和JS协定好的方法。

- (void)viewDidAppear:(BOOL)animated {    [super viewDidAppear:animated];    self.webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];    NSURL *url = [NSURL URLWithString:@"http://192.168.32.167:8989"];//    NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];    [self.webView loadRequest:[NSURLRequest requestWithURL:url]];    self.webView.delegate = self;        [self.view addSubview:self.webView];}#pragma -mark UIWebViewDelegate- (void)webViewDidFinishLoad:(UIWebView *)webView {    NSLog(@"页面加载完毕");    //获取当前页面的JSContext    JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];    //将OC提供给JS的方法进行注册 KZH5Game是和JS那边协定好的注册名    context[@"KZH5Game"] = self;    }#pragma -mark JS将要调用的方法- (void)isLogin:(BOOL)isLogin {    //JS返回过来的登录状态,根据isLogin判断是否需要显示登录界面}- (void)logout {    //JS那边登出的时候,会调用这个方法,使得SDK同步登出}
在登录成功之后,会返回token给JS,JS拿着这个返回的token去验证H5游戏登录。

OC调用JS,主要借助了evaluateScript。

#pragma -mark KSSDKInstanceDelegate//登录成功收到token- (void)ReceiveAccountToken:(NSString *)token needStartGame:(NSString *)startGameAgain {    //获取js上下文    JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];    //将获取到的字段传达给js    [context evaluateScript:[NSString stringWithFormat:@"login('%@')", token]];}

在这个交互的过程中,我遇到的问题是,用全局的context去注册OC的方法会有下列错误

@property (nonatomic, strong)JSContext *jsContext;- (void)webViewDidFinishLoad:(UIWebView *)webView {    //获取当前页面的JSContext    self.jsContext = [webView valueForKey:@"documentView.webView.mainFrame.javaScriptContext"];    //将OC提供给JS的方法进行注册    self.jsContext[@"KZH5Game"] = self; }

*** WebKit discarded an uncaught exception in the webView:didFinishLoadForFrame: delegate: <NSUnknownKeyException> [<UIWebView 0x14564840> valueForUndefinedKey:]: this class is not key value coding-compliant for the key documentView.webView.mainFrame.javaScriptContext.


百度了好久,也没找到好的解决办法,然后试着写成局部的,竟然实现了。但是还是不知道为什么全局的就不行,如果有知道的朋友,希望可以指教指教,先说声谢谢了。


原创粉丝点击