縱觀所有iOS與H5互動的方案,有以下幾種:
第一種:有很多的app直接使用在webview的代理中通過攔截的方式與native進行互動,通常是通過攔截url scheme判斷是否是我們需要攔截處理的url及其所對應的要處理的功能是什麼。任意版本都支援。
第二種:iOS7之後出了JavaScriptCore.framework用于與JS互動,但是不支援iOS6,對于還需要支援iOS6的app,就不能考慮這個了。若需要了解,看最後的推薦閱讀。
第三種:WebViewJavascriptBridge開源庫使用,本質上,它也是通過webview的代理攔截scheme,然後注入相應的JS。
第四種:react-native,這個沒玩過(與前三種不同)。
1、UIWebView 和 js 互動 【JavaScriptCore.framework】
ViewController.m:
#import "WebViewController.h"
#import "WebViewModel.h"
@interface WebViewController () <UIWebViewDelegate>
@property (nonatomic, strong) UIWebView *webView;
@property (nonatomic, strong) JSContext *jsContext;
@property (nonatomic, strong) WebViewModel *model;
@end
@implementation WebViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.webView];
[self createButtons];
// // 一個JSContext對象,就類似于Js中的window,隻需要建立一次即可。
// self.jsContext = [[JSContext alloc] init];
//
// // jscontext可以直接執行JS代碼。
// [self.jsContext evaluateScript:@"var num = 10"];
// [self.jsContext evaluateScript:@"var squareFunc = function(value) { return value * 2 }"];
// // 計算正方形的面積
// JSValue *square = [self.jsContext evaluateScript:@"squareFunc(num)"];
//
// // 也可以通過下标的方式擷取到方法
// JSValue *squareFunc = self.jsContext[@"squareFunc"];
// JSValue *value = [squareFunc callWithArguments:@[@"20"]];
// NSLog(@"%@", square.toNumber);
// NSLog(@"%@", value.toNumber);
}
- (void)createButtons {
NSArray *array = @[@"ocCallJS",
@"ocCallJSWithString",
//@"ocCallJSWithTitle:message",
//@"ocCallJSWithDictionary",
//@"ocCallJSWithArray"
];
NSInteger index = 0;
for (NSString *string in array) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[button setTitle:string forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonAciton:) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(kScreenWidth-300, 100+(index * 50), 280, 30);
button.layer.borderColor = [UIColor redColor].CGColor;
button.layer.borderWidth = 1;
button.layer.cornerRadius = 3;
index ++;
[self.view addSubview:button];
}
}
- (void)buttonAciton:(UIButton *)button {
if ([button.currentTitle isEqualToString:@"ocCallJS"]) {
[self.model ocCallJS];
}else if ([button.currentTitle isEqualToString:@"ocCallJSWithString"]) {
[self.model ocCallJSWithString:@"myocString"];
}else if ([button.currentTitle isEqualToString:@"ocCallJSWithTitle:message"]) {
// [self.model ocCallJSWithString];
}else if ([button.currentTitle isEqualToString:@"ocCallJSWithDictionary"]) {
[self.model ocCallJSWithDictionary:@{@"title":@"myoctitle",@"message":@"myocmessage"}];
}else if ([button.currentTitle isEqualToString:@"ocCallJSWithArray"]) {
[self.model ocCallJSWithArray:@[@"myoctitle",@"myocmessage",@"30"]];
}
}
- (UIWebView *)webView {
if (_webView == nil) {
_webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
NSURL *url = [[NSBundle mainBundle] URLForResource:@"callEach" withExtension:@"html"];
[_webView loadRequest:[NSURLRequest requestWithURL:url]];
//忽略web頁面與_WebView元件的大小關系如果設定為YES可以執行縮放,但是web頁面加載出來的時候,就會縮小到UIWebView元件的大小
_webView.scalesPageToFit = NO;
_webView.delegate = self;
}
return _webView;
}
#pragma mark - UIWebViewDelegate
- (void)webViewDidFinishLoad:(UIWebView *)webView {
self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
WebViewModel *model = [[WebViewModel alloc] init];
self.jsContext[@"CallEachModel"] = model;
model.jsContext = self.jsContext;
model.webView = self.webView;
model.currentVC = self;
self.model = model;
self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
NSLog(@"異常資訊:%@", exceptionValue);
};
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
}
@end
model.h:
#import <Foundation/Foundation.h>
@protocol WebViewJSExport <JSExport>
/** 遵守了 協定後 這些方法就暴露給 js 調用 **/
/** jsCallOC **/
- (void)jsCallOC;
- (void)jsCallOCWithString:(NSString *)string;
//js調用時候取函數名就好了 不要冒号 jsCallOCWithTitleMessage
- (void)jsCallOCWithTitle:(NSString *)title message:(NSString *)msg;
- (void)jsCallOCWithDictionary:(NSDictionary *)dictionary;
- (void)jsCallOCWithArray:(NSArray *)array;
/** ocCallJS **/
- (void)ocCallJS;
- (void)ocCallJSWithString:(NSString *)string;
- (void)ocCallJSWithTitle:(NSString *)title message:(NSString *)message;
- (void)ocCallJSWithDictionary:(NSDictionary *)dictionary;
- (void)ocCallJSWithArray:(NSArray *)array;
/** callEach **/
- (void)jsCallOCAndOCCallJSWithParams:(NSDictionary *)params;
- (void)ocCallJSAndJSCallOCWithParams:(NSDictionary *)params;
@end
@class BaseViewController;
@interface WebViewModel : NSObject <WebViewJSExport>
@property (nonatomic, weak) JSContext *jsContext;
@property (nonatomic, weak) UIWebView *webView;
@property (nonatomic, weak) BaseViewController *currentVC;
@end
model.m
#import "WebViewModel.h"
#import "BaseViewController.h"
@implementation WebViewModel
#pragma mark - jsCallOC
- (void)jsCallOC {
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
message:@"jsCallOC"
delegate:nil
cancelButtonTitle:@"I konw"
otherButtonTitles:nil, nil];
[alert show];
});
}
- (void)jsCallOCWithString:(NSString *)string {
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:string
message:nil
delegate:nil
cancelButtonTitle:@"I konw"
otherButtonTitles:nil, nil];
[alert show];
});
}
- (void)jsCallOCWithTitle:(NSString *)title message:(NSString *)msg {
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:msg
delegate:nil
cancelButtonTitle:@"I konw"
otherButtonTitles:nil, nil];
[alert show];
});
}
- (void)jsCallOCWithDictionary:(NSDictionary *)dictionary {
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:dictionary[@"title"]
message:dictionary[@"message"]
delegate:nil
cancelButtonTitle:@"I konw"
otherButtonTitles:nil, nil];
[alert show];
});
NSLog(@"===== %@",dictionary);
}
- (void)jsCallOCWithArray:(NSArray *)array {
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:array[0]
message:array[1]
delegate:nil
cancelButtonTitle:@"I konw"
otherButtonTitles:nil, nil];
[alert show];
});
NSLog(@"===== %@",array);
}
#pragma mark - OCCallJS
- (void)ocCallJS {
JSValue *jsFunc = self.jsContext[@"func1"];
[jsFunc callWithArguments:nil];
}
- (void)ocCallJSWithString:(NSString *)string {
NSInteger arc = arc4random()%1000;
JSValue *jsFunc = self.jsContext[@"func2"];
[jsFunc callWithArguments:@[@{@"title": @"change--> myoctitle", @"message": @(arc)}]];
}
- (void)ocCallJSWithTitle:(NSString *)title message:(NSString *)message {
}
- (void)ocCallJSWithDictionary:(NSDictionary *)dictionary {
}
- (void)ocCallJSWithArray:(NSArray *)array {
}
#pragma mark - callEach
- (void)jsCallOCAndOCCallJSWithParams:(NSDictionary *)params {
[self.currentVC createTopView];
self.currentVC.field.text = params[@"title"];
[self.currentVC setBlock:^(NSString *string){
if (string != nil && string.length > 0) {
JSValue *jsFunc = self.jsContext[@"func2"];
[jsFunc callWithArguments:@[@{@"title":@"js 調出來topView 輸入填充到html:" , @"message": string}]];
}
}];
}
- (void)ocCallJSAndJSCallOCWithParams:(NSDictionary *)params {
JSValue *jsFunc = self.jsContext[@"func3"];
[jsFunc callWithArguments:@[@{@"title": @"myoctitle", @"message": @"myocmessage"}]];
}
@end
github位址: https://github.com/lc081200/H5ObjCExample
轉載于:https://www.cnblogs.com/saytome/p/7133552.html