JS与OC互调,JS打开系统相机,JS获取iOS系统图片,iOS中JS调OC

来源:互联网 发布:python.org上不去 编辑:程序博客网 时间:2024/06/11 16:42

废话不多说,直接进入正题

1.首先在在viewController中实现JavaScript代理

我直接把.m文件中的内容全部粘贴了,看注释,大家懂得

[objc] view plain copy
  1. #import "ViewController.h"  
  2. #import <JavaScriptCore/JavaScriptCore.h>// 导入JavaScriptCore 系统框架文件  
  3. #import "SaveImage_Util.h"// 这是保存图片的类  
  4. /** 
  5.  *  实现js代理,js调用ios的入口就在这里 
  6.  */  
  7. @protocol JSDelegate <JSExport>  
  8.   
  9. - (void)getImage:(id)parameter;// 这个方法就是window.document.iosDelegate.getImage(JSON.stringify(parameter)); 中的 getImage()方法  
  10.   
  11. @end  
  12.   
  13. @interface ViewController ()<JSDelegate,UIWebViewDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate>//导入代理  JSDelegate UIWebViewDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate 这两个代理是打开系统相机的代理  
  14. /** 
  15.  *  声明 两个属性, 
  16.  */  
  17. @property(strongnonatomicJSContext *jsContext;  
  18. @property(retainnonatomicUIWebView *myWebView;  
  19.   
  20. @end  
  21.   
  22. @implementation ViewController  
  23. {  
  24.     int indextNumb;// 交替图片名字  
  25.     UIImage *getImage;//获取的图片  
  26. }  
  27. - (void)viewDidLoad {  
  28.     [super viewDidLoad];  
  29.     [self gotoWebView];  
  30. }  
  31. - (void)gotoWebView  
  32. {  
  33.     if (!self.myWebView)  
  34.     {  
  35.         //初始化 WebView  
  36.         self.myWebView = [[UIWebView alloc] initWithFrame:  
  37.                         CGRectMake(00self.view.bounds.size.widthself.view.bounds.size.height-100)];  
  38.         self.myWebView.backgroundColor = [UIColor colorWithRed:1.000 green:1.000 blue:0.400 alpha:1.000];  
  39.         // 代理  
  40.         self.myWebView.delegate = self;  
  41.         NSURL *path = [[NSBundle mainBundle] URLForResource:@"testJS" withExtension:@"html"];  
  42.         [self.myWebView loadRequest:[NSURLRequest requestWithURL:path]];  
  43.         [self.view addSubview:self.myWebView];  
  44.     }  
  45. }  
  46. #pragma mark UIWebViewDelegate   
  47. // 加载完成开始监听js的方法  
  48. - (void)webViewDidFinishLoad:(UIWebView *)webView  
  49. {  
  50.     self.jsContext = [self.myWebView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];  
  51.     self.jsContext[@"iosDelegate"] = self;//挂上代理  iosDelegate是window.document.iosDelegate.getImage(JSON.stringify(parameter)); 中的 iosDelegate  
  52.     self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception){  
  53.         context.exception = exception;  
  54.         NSLog(@"获取 self.jsContext 异常信息:%@",exception);  
  55.     };  
  56. }  
  57. - (void)getImage:(id)parameter  
  58. {  
  59.     // 把 parameter json字符串解析成字典  
  60.     NSString *jsonStr = [NSString stringWithFormat:@"%@", parameter];  
  61.     NSDictionary *jsParameDic = [NSJSONSerialization JSONObjectWithData:[jsonStr dataUsingEncoding:NSUTF8StringEncoding ] options:NSJSONReadingAllowFragments error:nil];  
  62.     NSLog(@"js传来的json字典: %@", jsParameDic);  
  63.     for (NSString *key in jsParameDic.allKeys)  
  64.     {  
  65.         NSLog(@"jsParameDic[%@]:%@", key, jsParameDic[key]);  
  66.     }  
  67.     [self beginOpenPhoto];  
  68. }  
  69. - (void)beginOpenPhoto  
  70. {  
  71.     // 主队列 异步打开相机  
  72.     dispatch_async(dispatch_get_main_queue(), ^{  
  73.         [self takePhoto];  
  74.     });  
  75. }  
  76. #pragma mark 取消选择照片代理方法  
  77. - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker  
  78. {  
  79.     [picker dismissViewControllerAnimated:YES completion:nil];  
  80. }  
  81. #pragma mark      //打开本地照片  
  82. - (void) localPhoto  
  83. {  
  84.     UIImagePickerController *imagePicker = [[UIImagePickerController alloc]init];  
  85.     imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;  
  86.     imagePicker.delegate = self;  
  87.     [self presentViewController:imagePicker animated:YES completion:nil];  
  88. }  
  89. #pragma mark      //打开相机拍照  
  90. - (void) takePhoto  
  91. {  
  92.     UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;  
  93.     if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])  
  94.     {  
  95.         UIImagePickerController *picker = [[UIImagePickerController alloc]init];  
  96.         picker.delegate = self;  
  97.         picker.allowsEditing = YES;  
  98.         picker.sourceType = sourceType;  
  99.         picker.modalTransitionStyle = UIModalTransitionStyleCoverVertical;  
  100.         [self presentViewController:picker animated:YES completion:nil];  
  101.     }  
  102.     else  
  103.     {  
  104.         NSLog(@"模拟器中不能打开相机");  
  105.         [self localPhoto];  
  106.     }  
  107. }  
  108. //  选择一张照片后进入这里  
  109. - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info  
  110. {  
  111.     NSString *type = [info objectForKey:UIImagePickerControllerMediaType];  
  112.     //  当前选择的类型是照片  
  113.     if ([type isEqualToString:@"public.image"])  
  114.     {  
  115.         // 获取照片  
  116.         getImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];  
  117.         NSLog(@"===Decoded image size: %@", NSStringFromCGSize(getImage.size));  
  118.         // obtainImage 压缩图片 返回原尺寸  
  119.         indextNumb = indextNumb == 1?2:1;  
  120.         NSString *nameStr = [NSString stringWithFormat:@"Varify%d.jpg",indextNumb];  
  121.         [SaveImage_Util saveImage:getImage ImageName:nameStr back:^(NSString *imagePath) {  
  122.             dispatch_async(dispatch_get_main_queue(), ^{  
  123.                 NSLog(@"图片路径:%@",imagePath);  
  124.                 /** 
  125.                  *  这里是IOS 调 js 其中 setImageWithPath 就是js中的方法 setImageWithPath(),参数是字典 
  126.                  */  
  127.                 JSValue *jsValue = self.jsContext[@"setImageWithPath"];  
  128.                 [jsValue callWithArguments:@[@{@"imagePath":imagePath,@"iosContent":@"获取图片成功,把系统获取的图片路径传给js 让html显示"}]];  
  129.             });  
  130.         }];  
  131.         [picker dismissViewControllerAnimated:YES completion:nil];  
  132.     }  
  133. }  
  134. - (void)didReceiveMemoryWarning {  
  135.     [super didReceiveMemoryWarning];  
  136.     // Dispose of any resources that can be recreated.  
  137. }  
  138.   
  139. @end  


2.保存图片的类SaveImage_Util.h和.m文件中的代码,该类继承NSObject

[objc] view plain copy
  1. //  SaveImage_Util.h  
  2. //  JS和iOS交互  
  3. //  
  4. //  Created by user on 16/7/28.  
  5. //  Copyright © 2016年 user. All rights reserved.  
  6. //  
  7.   
  8. #import <Foundation/Foundation.h>  
  9. #import <UIKit/UIKit.h>  
  10. @interface SaveImage_Util : NSObject  
  11. #pragma mark  保存图片到document  
  12. + (BOOL)saveImage:(UIImage *)saveImage ImageName:(NSString *)imageName back:(void(^)(NSString *imagePath))back;  
  13.   
  14. @end  

[objc] view plain copy
  1. //  SaveImage_Util.m  
  2. //  JS和iOS交互  
  3. //  
  4. //  Created by user on 16/7/28.  
  5. //  Copyright © 2016年 user. All rights reserved.  
  6. //  
  7.   
  8. #import "SaveImage_Util.h"  
  9.   
  10. @implementation SaveImage_Util  
  11. #pragma mark  保存图片到document  
  12. + (BOOL)saveImage:(UIImage *)saveImage ImageName:(NSString *)imageName back:(void(^)(NSString *imagePath))back  
  13. {  
  14.     NSString *path = [SaveImage_Util getImageDocumentFolderPath];  
  15.     NSData *imageData = UIImagePNGRepresentation(saveImage);  
  16.     NSString *documentsDirectory = [NSString stringWithFormat:@"%@/", path];  
  17.     // Now we get the full path to the file  
  18.     NSString *imageFile = [documentsDirectory stringByAppendingPathComponent:imageName];  
  19.     // and then we write it out  
  20.     NSFileManager *fileManager = [NSFileManager defaultManager];  
  21.     //如果文件路径存在的话  
  22.     BOOL bRet = [fileManager fileExistsAtPath:imageFile];  
  23.     if (bRet)  
  24.     {  
  25.         //        NSLog(@"文件已存在");  
  26.         if ([fileManager removeItemAtPath:imageFile error:nil])  
  27.         {  
  28.             //            NSLog(@"删除文件成功");  
  29.             if ([imageData writeToFile:imageFile atomically:YES])  
  30.             {  
  31.                 //                NSLog(@"保存文件成功");  
  32.                 back(imageFile);  
  33.             }  
  34.         }  
  35.         else  
  36.         {  
  37.               
  38.         }  
  39.           
  40.     }  
  41.     else  
  42.     {  
  43.         if (![imageData writeToFile:imageFile atomically:NO])  
  44.         {  
  45.             [fileManager createDirectoryAtPath:documentsDirectory withIntermediateDirectories:YES attributes:nil error:nil];  
  46.             if ([imageData writeToFile:imageFile atomically:YES])  
  47.             {  
  48.                 back(imageFile);  
  49.             }  
  50.         }  
  51.         else  
  52.         {  
  53.             return YES;  
  54.         }  
  55.           
  56.     }  
  57.     return NO;  
  58. }  
  59. #pragma mark  从文档目录下获取Documents路径  
  60. + (NSString *)getImageDocumentFolderPath  
  61. {  
  62.     NSString *patchDocument = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];  
  63.     return [NSString stringWithFormat:@"%@/Images", patchDocument];  
  64. }  
  65. @end  



3. 接下来就是HTML文件中的标签及JS代码,这里的JS就不单独用一个类实现了,就在testJS.html中实现。

[html] view plain copy
  1. <!DOCTYPE html>  
  2. <html>  
  3.     <head>  
  4.         <meta charset="UTF-8">  
  5.         <title></title>  
  6.     </head>  
  7.     <body>  
  8.         <div>  
  9.             <h3>JS与iOS交互</h3>  
  10.             <h4>JS页面获取iOS系统图片</h5>  
  11.         </div>  
  12.         <div>  
  13.             <input type = "button" style="width: 50%;height: 5%;" id="Button" value="打开相机获取图片" onclick="getIOSImage()"></button>  
  14.         </div><dir />  
  15.         <div>  
  16.             <img src="testImage.png" id="changeImage"style="width: 30%; height: 30%;" onclick="getIOSImage()"><!--src="图片的相对路径" 如果把html文件导入工程中,图片路径和OC一样只写图片名字和后缀就可以,(记得要先把图片添加到工程) 图片也可以实现按钮的方法getIOSImage -->  
  17.         </div>  
  18.         <span id="iosParame" style="width: 200px; height: 50%; color:orangered; font-size:15px" value="等待获取ios参数" >  
  19.             </div>  
  20.         <script>  
  21.             var getIOSImage = function(){  
  22.                 var parameter = {'title':'JS调OC','describe':'这里就是JS传给OC的参数'};  
  23.                 // 在下面这里实现js 调用系统原生api  
  24.     window.iosDelegate.getImage(JSON.stringify(parameter));// 实现数据的 json 格式字符串  
  25.             }  
  26.         // 这里是 iOS调用js的方法  
  27.         function setImageWithPath(arguments){  
  28.             document.getElementById('changeImage').src = arguments['imagePath'];  
  29.             document.getElementById('iosParame').innerHTML = arguments['iosContent'];  
  30.         }  
  31.         </script>  
  32.     </body>  
  33. </html>  
注意:在js获取的object对象的解析和取值的方式有两种,一种类似OC的方法(上面HTML中写的方法: arguments['iosContent']),另一种是用eval()方法,如

[javascript] view plain copy
  1. document.getElementById('iosParame').innerHTML = eval("arguments."+'iosContent');  
下面是我调试丑丑的效果图:      
原创粉丝点击