JS與OC互調,JS開啟系統相機,JS獲取iOS系統圖片,iOS中JS調OC
阿新 • • 發佈:2019-02-12
廢話不多說,直接進入正題
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
- @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
- {
- 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
- {
- returnYES;
- }
- }
- returnNO;
- }
- #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>
- <metacharset="UTF-8">
- <title></title>
- </head>
- <body>
- <div>
- <h3>JS與iOS互動</h3>
- <h4>JS頁面獲取iOS系統圖片</h5>
- </div>
- <div>
- <inputtype = "button"style="width: 50%;height: 5%;"id="Button"value="開啟相機獲取圖片"onclick="getIOSImage()"></button>
- </div><dir/>
- <div>
- <imgsrc="testImage.png"id="changeImage"style="width: 30%; height: 30%;" onclick="getIOSImage()"><!--src="圖片的相對路徑" 如果把html檔案匯入工程中,圖片路徑和OC一樣只寫圖片名字和字尾就可以,(記得要先把圖片新增到工程) 圖片也可以實現按鈕的方法getIOSImage -->
- </div>
- <spanid="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');