//
// ViewController.m
// JSCallsOC
//
// Created by hq on 16/4/19.
// Copyright © 2016年 hanqing. All rights reserved.
//
#import "ViewController.h"
#import "NSObject+PerformSelector.h"
@interface ViewController () <UIWebViewDelegate>
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@end
@implementation ViewController
-(BOOL) prefersStatusBarHidden{
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url=[[NSBundle mainBundle] URLForResource:@"index" withExtension:@"html"];
[self.webView loadRequest:[NSURLRequest requestWithURL:url]];
self.webView.delegate=self;
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
//js调用oc原理,通过特殊的url解析方法,然后调用oc的相应方法
NSString *urlString=request.URL.absoluteString;
//我们制定了一个协议,调用oc的方法都以hq://开头,后边跟着方法名
NSString *scheme=@"hq://";
//如果是我们自定义的协议hq://call
if ([urlString hasPrefix:scheme]) {
//取出scheme后边的路径
NSString *path=[urlString substringFromIndex:scheme.length];
//根据?区分出方法名 参数
NSArray *array=[path componentsSeparatedByString:@"?"];
NSLog(@"%@",array);
NSString *methodName=array.firstObject;
//将方法名中的_变成:
methodName=[methodName stringByReplacingOccurrencesOfString:@"_" withString:@":"];
NSString *parameter=array.lastObject;
NSArray *parameters=nil;
if (array.count==2) {
//继续分解我们的变量
parameters=[parameter componentsSeparatedByString:@"&"];
}
[self performSelector:NSSelectorFromString(methodName) withObjects:parameters];
return NO;
}
return YES;
}
-(void) call{
NSLog(@"没有参数的情况--打电话给");
}
-(void) call:(NSString *) number{
NSLog(@"一个参数的情况--打电话给%@",number);
}
-(void) call:(NSString *) number number2:(NSString *) number2{
NSLog(@"2个参数的情况--打电话给%@ %@",number,number2);
}
-(void) call:(NSString *) number number2:(NSString *) number2 number3:(NSString *) number3{
NSLog(@"3个参数的情况--打电话给%@ %@ %@",number,number2,number3);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end
//
// NSObject+PerformSelector.m
// JSCallsOC
//
// Created by hq on 16/4/19.
// Copyright © 2016年 hanqing. All rights reserved.
//
#import "NSObject+PerformSelector.h"
@implementation NSObject (PerformSelector)
- (id)performSelector:(SEL)aSelector withObjects:(NSArray *)objects{
NSMethodSignature *signature=[self.class instanceMethodSignatureForSelector:aSelector];
//如果没有该方法
if (!signature) {
@throw [NSException exceptionWithName:@"没有该方法啊" reason:@"你确定有这个方法?" userInfo:nil];
//[NSException raise:@"出落喽" format:@"方法找不到啊 %@",NSStringFromSelector(aSelector)];
}
NSInvocation *invocation=[NSInvocation invocationWithMethodSignature:signature];
invocation.target=self;
invocation.selector=aSelector;
//处理参数传多了异常
//for (int i=0; i<objects.count; i++) count得用我们方法名当中参数多个数,这样用户即使传多了,也不受影响
//设置参数
//获取方法多参数个数,注意其默认包含了self,_cmd signature.numberOfArguments所以要-2
//处理有一个活多个参数,但参数为空的问题
NSInteger count= MIN(signature.numberOfArguments-2, objects.count);
for (NSInteger i=0; i<count; i++) {
id object=objects[i];
[invocation setArgument:&object atIndex:2+i];
}
[invocation invoke];
//获取返回值
id returnValue=nil;
if (signature.methodReturnLength) {
[invocation getReturnValue:&returnValue];
}
return returnValue;
}
@end