您的位置:首页 > 移动开发 > Objective-C

iOS UIWebView中javascript与Objective-C交互、获取摄像头

2015-07-14 13:49 477 查看
运行部分脚本时需要确定页面是否加载完成(DOMContentLoaded)。当然,stringByEvaluatingJavaScriptFromString只是Native向UIWebView中的网页单向的通信,UIWebView中的网页向Native通信则需要通过UIWebView的协webView:shouldStartLoadWithRequest:navigationType:。首先,创建一个文件命名为test.html,内容如下:

<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.hhttp://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

复制代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: