JS与OC互调,JS打开系统相机,JS获取iOS系统图片,iOS中JS调OC
废话不多说,直接进入正题
1.首先在在viewController中实现JavaScript代理
我直接把.m文件中的内容全部粘贴了,看注释,大家懂得
- #import "ViewController.h"
- #import <JavaScriptCore/JavaScriptCore.h>// 导入JavaScriptCore 系统框架文件
- #import "SaveImage_Util.h"// 这是保存图片的类
- /**
- * 实现js代理,js调用ios的入口就在这里
- */
- @protocol JSDelegate <JSExport>
- - (void)getImage:(id)parameter;// 这个方法就是window.document.iosDelegate.getImage(JSON.stringify(parameter)); 中的 getImage()方法
- @end
- @interface ViewController ()<JSDelegate,UIWebViewDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate>//导入代理 JSDelegate UIWebViewDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate 这两个代理是打开系统相机的代理
- /**
- * 声明 两个属性,
- */
- @property(strong, nonatomic) JSContext *jsContext;
- @property(retain, nonatomic) UIWebView *myWebView;
- @end
- @implementation ViewController
- {
- int indextNumb;// 交替图片名字
- UIImage *getImage;//获取的图片
- }
- - (void)viewDidLoad {
- [super viewDidLoad];
- [self gotoWebView];
- }
- - (void)gotoWebView
- {
- if (!self.myWebView)
- {
- //初始化 WebView
- self.myWebView = [[UIWebView alloc] initWithFrame:
- CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height-100)];
- self.myWebView.backgroundColor = [UIColor colorWithRed:1.000 green:1.000 blue:0.400 alpha:1.000];
- // 代理
- self.myWebView.delegate = self;
- NSURL *path = [[NSBundle mainBundle] URLForResource:@"testJS" withExtension:@"html"];
- [self.myWebView loadRequest:[NSURLRequest requestWithURL:path]];
- [self.view addSubview:self.myWebView];
- }
- }
- #pragma mark UIWebViewDelegate
- // 加载完成开始监听js的方法
- - (void)webViewDidFinishLoad:(UIWebView *)webView
- {
- self.jsContext = [self.myWebView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
- self.jsContext[@"iosDelegate"] = self;//挂上代理 iosDelegate是window.document.iosDelegate.getImage(JSON.stringify(parameter)); 中的 iosDelegate
- self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception){
- context.exception = exception;
- NSLog(@"获取 self.jsContext 异常信息:%@",exception);
- };
- }
- - (void)getImage:(id)parameter
- {
- // 把 parameter json字符串解析成字典
- NSString *jsonStr = [NSString stringWithFormat:@"%@", parameter];
- NSDictionary *jsParameDic = [NSJSONSerialization JSONObjectWithData:[jsonStr dataUsingEncoding:NSUTF8StringEncoding ] options:NSJSONReadingAllowFragments error:nil];
- NSLog(@"js传来的json字典: %@", jsParameDic);
- for (NSString *key in jsParameDic.allKeys)
- {
- NSLog(@"jsParameDic[%@]:%@", key, jsParameDic[key]);
- }
- [self beginOpenPhoto];
- }
- - (void)beginOpenPhoto
- {
- // 主队列 异步打开相机
- dispatch_async(dispatch_get_main_queue(), ^{
- [self takePhoto];
- });
- }
- #pragma mark 取消选择照片代理方法
- - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
- {
- [picker dismissViewControllerAnimated:YES completion:nil];
- }
- #pragma mark //打开本地照片
- - (void) localPhoto
- {
- UIImagePickerController *imagePicker = [[UIImagePickerController alloc]init];
- imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
- imagePicker.delegate = self;
- [self presentViewController:imagePicker animated:YES completion:nil];
- }
- #pragma mark //打开相机拍照
- - (void) takePhoto
- {
- UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;
- if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
- {
- UIImagePickerController *picker = [[UIImagePickerController alloc]init];
- picker.delegate = self;
- picker.allowsEditing = YES;
- picker.sourceType = sourceType;
- picker.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
- [self presentViewController:picker animated:YES completion:nil];
- }
- else
- {
- NSLog(@"模拟器中不能打开相机");
- [self localPhoto];
- }
- }
- // 选择一张照片后进入这里
- - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
- {
- NSString *type = [info objectForKey:UIImagePickerControllerMediaType];
- // 当前选择的类型是照片
- if ([type isEqualToString:@"public.image"])
- {
- // 获取照片
- getImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
- NSLog(@"===Decoded image size: %@", NSStringFromCGSize(getImage.size));
- // obtainImage 压缩图片 返回原尺寸
- indextNumb = indextNumb == 1?2:1;
- NSString *nameStr = [NSString stringWithFormat:@"Varify%d.jpg",indextNumb];
- [SaveImage_Util saveImage:getImage ImageName:nameStr back:^(NSString *imagePath) {
- dispatch_async(dispatch_get_main_queue(), ^{
- NSLog(@"图片路径:%@",imagePath);
- /**
- * 这里是IOS 调 js 其中 setImageWithPath 就是js中的方法 setImageWithPath(),参数是字典
- */
- JSValue *jsValue = self.jsContext[@"setImageWithPath"];
- [jsValue callWithArguments:@[@{@"imagePath":imagePath,@"iosContent":@"获取图片成功,把系统获取的图片路径传给js 让html显示"}]];
- });
- }];
- [picker dismissViewControllerAnimated:YES completion:nil];
- }
- }
- - (void)didReceiveMemoryWarning {
- [super didReceiveMemoryWarning];
- // Dispose of any resources that can be recreated.
- }
- @end
2.保存图片的类SaveImage_Util.h和.m文件中的代码,该类继承NSObject
- // SaveImage_Util.h
- // JS和iOS交互
- //
- // Created by user on 16/7/28.
- // Copyright © 2016年 user. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- #import <UIKit/UIKit.h>
- @interface SaveImage_Util : NSObject
- #pragma mark 保存图片到document
- + (BOOL)saveImage:(UIImage *)saveImage ImageName:(NSString *)imageName back:(void(^)(NSString *imagePath))back;
- @end
- // SaveImage_Util.m
- // JS和iOS交互
- //
- // Created by user on 16/7/28.
- // Copyright © 2016年 user. All rights reserved.
- //
- #import "SaveImage_Util.h"
- @implementation SaveImage_Util
- #pragma mark 保存图片到document
- + (BOOL)saveImage:(UIImage *)saveImage ImageName:(NSString *)imageName back:(void(^)(NSString *imagePath))back
- {
- NSString *path = [SaveImage_Util getImageDocumentFolderPath];
- NSData *imageData = UIImagePNGRepresentation(saveImage);
- NSString *documentsDirectory = [NSString stringWithFormat:@"%@/", path];
- // Now we get the full path to the file
- NSString *imageFile = [documentsDirectory stringByAppendingPathComponent:imageName];
- // and then we write it out
- NSFileManager *fileManager = [NSFileManager defaultManager];
- //如果文件路径存在的话
- BOOL bRet = [fileManager fileExistsAtPath:imageFile];
- if (bRet)
- {
- // NSLog(@"文件已存在");
- if ([fileManager removeItemAtPath:imageFile error:nil])
- {
- // NSLog(@"删除文件成功");
- if ([imageData writeToFile:imageFile atomically:YES])
- {
- // NSLog(@"保存文件成功");
- back(imageFile);
- }
- }
- else
- {
- }
- }
- else
- {
- if (![imageData writeToFile:imageFile atomically:NO])
- {
- [fileManager createDirectoryAtPath:documentsDirectory withIntermediateDirectories:YES attributes:nil error:nil];
- if ([imageData writeToFile:imageFile atomically:YES])
- {
- back(imageFile);
- }
- }
- else
- {
- return YES;
- }
- }
- return NO;
- }
- #pragma mark 从文档目录下获取Documents路径
- + (NSString *)getImageDocumentFolderPath
- {
- NSString *patchDocument = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
- return [NSString stringWithFormat:@"%@/Images", patchDocument];
- }
- @end
3. 接下来就是HTML文件中的标签及JS代码,这里的JS就不单独用一个类实现了,就在testJS.html中实现。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <div>
- <h3>JS与iOS交互</h3>
- <h4>JS页面获取iOS系统图片</h5>
- </div>
- <div>
- <input type = "button" style="width: 50%;height: 5%;" id="Button" value="打开相机获取图片" onclick="getIOSImage()"></button>
- </div><dir />
- <div>
- <img src="testImage.png" id="changeImage"style="width: 30%; height: 30%;" onclick="getIOSImage()"><!--src="图片的相对路径" 如果把html文件导入工程中,图片路径和OC一样只写图片名字和后缀就可以,(记得要先把图片添加到工程) 图片也可以实现按钮的方法getIOSImage -->
- </div>
- <span id="iosParame" style="width: 200px; height: 50%; color:orangered; font-size:15px" value="等待获取ios参数" >
- </div>
- <script>
- var getIOSImage = function(){
- var parameter = {'title':'JS调OC','describe':'这里就是JS传给OC的参数'};
- // 在下面这里实现js 调用系统原生api
- window.iosDelegate.getImage(JSON.stringify(parameter));// 实现数据的 json 格式字符串
- }
- // 这里是 iOS调用js的方法
- function setImageWithPath(arguments){
- document.getElementById('changeImage').src = arguments['imagePath'];
- document.getElementById('iosParame').innerHTML = arguments['iosContent'];
- }
- </script>
- </body>
- </html>
- document.getElementById('iosParame').innerHTML = eval("arguments."+'iosContent');