运行部分脚本时需要确定页面是否加载完成(DOMContentLoaded)。当然,stringByEvaluatingJavaScriptFromString只是Native向UIWebView中的网页单向的通信,UIWebView中的网页向Native通信则需要通过UIWebView的协webView:shouldStartLoadWithRequest:navigationType:。首先,创建一个文件命名为test.html,内容如下:
复制代码
然后,在Native实现如下代码:
复制代码
这样就完成了简单的通信,UIWebView中的网页需要访问设备的功能都可以在webView:shouldStartLoadWithRequest:navigationType:编写相应的代码来实现。 在UIWebView中调用摄像头、相册、图库iOS 6以上版本的Mobile Safari支持在网页中调用摄像头,只需要放置以下代码:
复制代码
但是iOS 5的浏览器还不支持这个功能,如果需要调用摄像头,则依然需要通过Hybrid开发方式来实现。首先,创建一个文件命名为camera.html,定义三个按钮分别用于获取摄像头、图库、相册:
复制代码
Native实现代码如下:
复制代码
- <a href="js-call://test/lwme.cnblogs.com">测试</a>
-
- <a href="js-call://other/lwme.cnblogs.com">测试2</a>复制代码
然后,在Native实现如下代码:
- @interface LwmeTestViewController ()<UIWebViewDelegate>
-
- @end
-
-
-
- @implementation LwmeTestViewController
-
- - (void)viewDidLoad
-
- {
-
- [super viewDidLoad];
-
- // 设置delegate并加载html
-
- self.webView.delegate = self;
-
- NSString *filePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"html"];
-
- NSString *fileContent = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
-
- [self.webView loadHTMLString:fileContent baseURL:nil];
-
- }
-
- - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
-
- {
-
- NSString *requestString = [[request URL] absoluteString];
-
- NSString *protocol = @"js-call://";
-
- if ([requestString hasPrefix:protocol]) {
-
- NSString *requestContent = [requestString substringFromIndex:[protocol length]];
-
- NSArray *vals = [requestContent componentsSeparatedByString:@"/"];
-
- if ([vals[0] isEqualToString:@"test"]) { //test方法
-
- [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"alert('地址:%@');", vals[1]]];
-
- }
-
- else {
-
- [webView stringByEvaluatingJavaScriptFromString:@"alert('未定义');"];
-
- }
-
- return NO; // 对于js-call://协议不执行跳转
-
- }
-
- return YES;
-
- }
这样就完成了简单的通信,UIWebView中的网页需要访问设备的功能都可以在webView:shouldStartLoadWithRequest:navigationType:编写相应的代码来实现。 在UIWebView中调用摄像头、相册、图库iOS 6以上版本的Mobile Safari支持在网页中调用摄像头,只需要放置以下代码:
- <input type="file" capture="camera" accept="image/*" id="cameraInput">
但是iOS 5的浏览器还不支持这个功能,如果需要调用摄像头,则依然需要通过Hybrid开发方式来实现。首先,创建一个文件命名为camera.html,定义三个按钮分别用于获取摄像头、图库、相册:
- <script>
-
- function cameraCallback(imageData) {
-
- var img = createImageWithBase64(imageData);
-
- document.getElementById("cameraWrapper").appendChild(img);
-
- }
-
- function photolibraryCallback(imageData) {
-
- var img = createImageWithBase64(imageData);
-
- document.getElementById("photolibraryWrapper").appendChild(img);
-
- }
-
- function albumCallback(imageData) {
-
- var img = createImageWithBase64(imageData);
-
- document.getElementById("albumWrapper").appendChild(img);
-
- }
-
- function createImageWithBase64(imageData) {
-
- var img = new Image();
-
- img.src = "data:image/jpeg;base64," + imageData;
-
- img.style.width = "50px";
-
- img.style.height = "50px";
-
- return img;
-
- }
-
- </script>
-
- <p style="text-align:center;padding:20px;">
-
- <a href="js-call://camera/cameraCallback">拍照</a>
-
- <a href="js-call://photolibrary/photolibraryCallback">图库</a>
-
- <a href="js-call://album/albumCallback">相册</a>
-
- </p>
-
-
-
- <fieldset>
-
- <legend>拍照</legend>
-
- <div id="cameraWrapper">
-
- </div>
-
- </fieldset>
-
-
-
- <fieldset>
-
- <legend>图库</legend>
-
- <div id="photolibraryWrapper">
-
- </div>
-
- </fieldset>
-
-
-
- <fieldset>
-
- <legend>相册</legend>
-
- <div id="albumWrapper">
-
- </div>
-
- </fieldset>
Native实现代码如下:
- #import "LwmeViewController.h"
-
- #import "NSData+Base64.h"
-
- // Base64代码从 http://svn.cocoasourcecode.com/MGTwitterEngine/NSData+Base64.h 和 http://svn.cocoasourcecode.com/MGTwitterEngine/NSData+Base64.m 获取
-
-
-
- @interface LwmeViewController ()<UIWebViewDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate>
-
- {
-
- NSString *callback; // 定义变量用于保存返回函数
-
- }
-
- @end
-
-
-
- @implementation LwmeViewController
-
- - (void)viewDidLoad
-
- {
-
- [super viewDidLoad];
-
- // 设置delegate并载入html文件
-
- self.webView.delegate = self;
-
- NSString *filePath = [[NSBundle mainBundle] pathForResource:@"camera" ofType:@"html"];
-
- NSString *fileContent = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
-
- [self.webView loadHTMLString:fileContent baseURL:nil];
-
- }
-
-
-
- - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
-
- {
-
- NSString *requestString = [[request URL] absoluteString];
-
- NSString *protocol = @"js-call://"; //协议名称
-
- if ([requestString hasPrefix:protocol]) {
-
- NSString *requestContent = [requestString substringFromIndex:[protocol length]];
-
- NSArray *vals = [requestContent componentsSeparatedByString:@"/"];
-
- if ([[vals objectAtIndex:0] isEqualToString:@"camera"]) { // 摄像头
-
- callback = [vals objectAtIndex:1];
-
- [self doAction:UIImagePickerControllerSourceTypeCamera];
-
- } else if([[vals objectAtIndex:0] isEqualToString:@"photolibrary"]) { // 图库
-
- callback = [vals objectAtIndex:1];
-
- [self doAction:UIImagePickerControllerSourceTypePhotoLibrary];
-
- } else if([[vals objectAtIndex:0] isEqualToString:@"album"]) { // 相册
-
- callback = [vals objectAtIndex:1];
-
- [self doAction:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
-
- }
-
- else {
-
- [webView stringByEvaluatingJavaScriptFromString:@"alert('未定义/lwme.cnblogs.com');"];
-
- }
-
- return NO;
-
- }
-
- return YES;
-
- }
-
-
-
- - (void)doAction:(UIImagePickerControllerSourceType)sourceType
-
- {
-
- UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
-
- imagePicker.delegate = self;
-
- if ([UIImagePickerController isSourceTypeAvailable:sourceType]) {
-
- imagePicker.sourceType = sourceType;
-
- } else {
-
- UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"照片获取失败" message:@"没有可用的照片来源" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
-
- [av show];
-
- return;
-
- }
-
- // iPad设备做额外处理
-
- if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
-
- UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
-
- [popover presentPopoverFromRect:CGRectMake(self.view.bounds.size.width / 2, self.view.bounds.size.height / 3, 10, 10) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
-
- } else {
-
- [self presentModalViewController:imagePicker animated:YES];
-
- }
-
- }
-
-
-
- - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
-
- {
-
- if ([[info objectForKey:UIImagePickerControllerMediaType] isEqualToString:@"public.image"]) {
-
- // 返回图片
-
- UIImage *originalImage = [info objectForKey:UIImagePickerControllerOriginalImage];
-
- // 设置并显示加载动画
-
- UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"正在处理图片..." message:@"\n\n"
-
- delegate:self
-
- cancelButtonTitle:nil
-
- otherButtonTitles:nil, nil];
-
-
-
- UIActivityIndicatorView *loading = [[UIActivityIndicatorView alloc]
-
- initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
-
- loading.center = CGPointMake(139.5, 75.5);
-
- [av addSubview:loading];
-
- [loading startAnimating];
-
- [av show];
-
- // 在后台线程处理图片
-
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
-
- // 这里可以对图片做一些处理,如调整大小等,否则图片过大显示在网页上时会造成内存警告
-
- NSString *base64 = [UIImagePNGRepresentation(originalImage, 0.3) base64Encoding]; // 图片转换成base64字符串
-
- [self performSelectorOnMainThread:@selector(doCallback:) withObject:base64 waitUntilDone:YES]; // 把结果显示在网页上
-
- [av dismissWithClickedButtonIndex:0 animated:YES]; // 关闭动画
-
- });
-
- }
-
-
-
- [picker dismissModalViewControllerAnimated:YES];
-
- }
-
-
-
- - (void)doCallback:(NSString *)data
-
- {
-
- [self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@('%@');", callback, data]];
-
- }
-
- @end