zoukankan      html  css  js  c++  java
  • iOS UIWebView中javascript与Objective-C交互、获取摄像头

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

    1. <a href="js-call://test/lwme.cnblogs.com">测试</a>

    2. <a href="js-call://other/lwme.cnblogs.com">测试2</a>复制代码
    复制代码


        然后,在Native实现如下代码: 

    1. @interface LwmeTestViewController ()<UIWebViewDelegate>

    2. @end



    3. @implementation LwmeTestViewController

    4. - (void)viewDidLoad

    5. {

    6.     [super viewDidLoad];

    7.     // 设置delegate并加载html

    8.     self.webView.delegate = self;

    9.     NSString *filePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"html"];

    10.     NSString *fileContent = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];

    11.     [self.webView loadHTMLString:fileContent baseURL:nil];

    12. }

    13. - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

    14. {

    15.     NSString *requestString = [[request URL] absoluteString];

    16.     NSString *protocol = @"js-call://";

    17.     if ([requestString hasPrefix:protocol]) {

    18.         NSString *requestContent = [requestString substringFromIndex:[protocol length]];

    19.         NSArray *vals = [requestContent componentsSeparatedByString:@"/"];

    20.         if ([vals[0] isEqualToString:@"test"]) { //test方法

    21.             [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"alert('地址:%@');", vals[1]]];

    22.         }

    23.         else {

    24.             [webView stringByEvaluatingJavaScriptFromString:@"alert('未定义');"];

    25.         }

    26.         return NO; // 对于js-call://协议不执行跳转

    27.     }

    28.     return YES;

    29. }
    复制代码


        这样就完成了简单的通信,UIWebView中的网页需要访问设备的功能都可以在webView:shouldStartLoadWithRequest:navigationType:编写相应的代码来实现。 在UIWebView中调用摄像头、相册、图库iOS 6以上版本的Mobile Safari支持在网页中调用摄像头,只需要放置以下代码:

    1. <input type="file" capture="camera" accept="image/*" id="cameraInput">
    复制代码


        但是iOS 5的浏览器还不支持这个功能,如果需要调用摄像头,则依然需要通过Hybrid开发方式来实现。首先,创建一个文件命名为camera.html,定义三个按钮分别用于获取摄像头、图库、相册: 

    1. <script>

    2.     function cameraCallback(imageData) {

    3.         var img = createImageWithBase64(imageData);

    4.         document.getElementById("cameraWrapper").appendChild(img);

    5.     }

    6.     function photolibraryCallback(imageData) {

    7.         var img = createImageWithBase64(imageData);

    8.         document.getElementById("photolibraryWrapper").appendChild(img);

    9.     }

    10.     function albumCallback(imageData) {

    11.         var img = createImageWithBase64(imageData);

    12.         document.getElementById("albumWrapper").appendChild(img);

    13.     }

    14.     function createImageWithBase64(imageData) {

    15.         var img = new Image();

    16.         img.src = "data:image/jpeg;base64," + imageData;

    17.         img.style.width = "50px";

    18.         img.style.height = "50px";

    19.         return img;

    20.     }

    21. </script>

    22. <p style="text-align:center;padding:20px;">

    23.     <a href="js-call://camera/cameraCallback">拍照</a>  

    24.     <a href="js-call://photolibrary/photolibraryCallback">图库</a>  

    25.     <a href="js-call://album/albumCallback">相册</a>

    26. </p>



    27. <fieldset>

    28.     <legend>拍照</legend>

    29.     <div id="cameraWrapper">

    30.     </div>

    31. </fieldset>



    32. <fieldset>

    33.     <legend>图库</legend>

    34.     <div id="photolibraryWrapper">

    35.     </div>

    36. </fieldset>



    37. <fieldset>

    38.     <legend>相册</legend>

    39.     <div id="albumWrapper">

    40.     </div>

    41. </fieldset>
    复制代码


        Native实现代码如下:

    1. #import "LwmeViewController.h"

    2. #import "NSData+Base64.h"

    3. // Base64代码从 http://svn.cocoasourcecode.com/MGTwitterEngine/NSData+Base64.h 和 http://svn.cocoasourcecode.com/MGTwitterEngine/NSData+Base64.m 获取



    4. @interface LwmeViewController ()<UIWebViewDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate>

    5. {

    6.     NSString *callback; // 定义变量用于保存返回函数

    7. }

    8. @end



    9. @implementation LwmeViewController

    10. - (void)viewDidLoad

    11. {

    12.     [super viewDidLoad];

    13.     // 设置delegate并载入html文件

    14.     self.webView.delegate = self;

    15.     NSString *filePath = [[NSBundle mainBundle] pathForResource:@"camera" ofType:@"html"];

    16.     NSString *fileContent = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];

    17.     [self.webView loadHTMLString:fileContent baseURL:nil];

    18. }



    19. - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

    20. {

    21.     NSString *requestString = [[request URL] absoluteString];

    22.     NSString *protocol = @"js-call://"; //协议名称

    23.     if ([requestString hasPrefix:protocol]) {

    24.         NSString *requestContent = [requestString substringFromIndex:[protocol length]];

    25.         NSArray *vals = [requestContent componentsSeparatedByString:@"/"];

    26.         if ([[vals objectAtIndex:0] isEqualToString:@"camera"]) { // 摄像头

    27.             callback = [vals objectAtIndex:1];

    28.             [self doAction:UIImagePickerControllerSourceTypeCamera];

    29.         } else if([[vals objectAtIndex:0] isEqualToString:@"photolibrary"]) { // 图库

    30.             callback = [vals objectAtIndex:1];

    31.             [self doAction:UIImagePickerControllerSourceTypePhotoLibrary];

    32.         } else if([[vals objectAtIndex:0] isEqualToString:@"album"]) { // 相册

    33.             callback = [vals objectAtIndex:1];

    34.             [self doAction:UIImagePickerControllerSourceTypeSavedPhotosAlbum];

    35.         }

    36.         else {

    37.             [webView stringByEvaluatingJavaScriptFromString:@"alert('未定义/lwme.cnblogs.com');"];

    38.         }

    39.         return NO;

    40.     }

    41.     return YES;

    42. }



    43. - (void)doAction:(UIImagePickerControllerSourceType)sourceType

    44. {

    45.     UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];

    46.     imagePicker.delegate = self;

    47.     if ([UIImagePickerController isSourceTypeAvailable:sourceType]) {

    48.         imagePicker.sourceType = sourceType;

    49.     } else {

    50.         UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"照片获取失败" message:@"没有可用的照片来源" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];

    51.         [av show];

    52.         return;

    53.     }

    54.     // iPad设备做额外处理

    55.     if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {

    56.         UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];

    57.         [popover presentPopoverFromRect:CGRectMake(self.view.bounds.size.width / 2, self.view.bounds.size.height / 3, 10, 10) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

    58.     } else {

    59.         [self presentModalViewController:imagePicker animated:YES];

    60.     }

    61. }



    62. - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

    63. {

    64.     if ([[info objectForKey:UIImagePickerControllerMediaType] isEqualToString:@"public.image"]) {

    65.         // 返回图片

    66.         UIImage *originalImage = [info objectForKey:UIImagePickerControllerOriginalImage];

    67.         // 设置并显示加载动画

    68.         UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"正在处理图片..." message:@" "

    69.                                                 delegate:self

    70.                                        cancelButtonTitle:nil

    71.                                        otherButtonTitles:nil, nil];

    72.          

    73.         UIActivityIndicatorView *loading = [[UIActivityIndicatorView alloc]

    74.                                             initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

    75.         loading.center = CGPointMake(139.5, 75.5);

    76.         [av addSubview:loading];

    77.         [loading startAnimating];

    78.         [av show];

    79.         // 在后台线程处理图片

    80.         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{

    81.             // 这里可以对图片做一些处理,如调整大小等,否则图片过大显示在网页上时会造成内存警告

    82.             NSString *base64 = [UIImagePNGRepresentation(originalImage, 0.3) base64Encoding]; // 图片转换成base64字符串

    83.             [self performSelectorOnMainThread:@selector(doCallback:) withObject:base64 waitUntilDone:YES]; // 把结果显示在网页上

    84.             [av dismissWithClickedButtonIndex:0 animated:YES]; // 关闭动画

    85.         });

    86.     }

    87.      

    88.     [picker dismissModalViewControllerAnimated:YES];

    89. }



    90. - (void)doCallback:(NSString *)data

    91. {

    92.     [self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@('%@');", callback, data]];

    93. }

    94. @end
    复制代码

  • 相关阅读:
    JBoss+Ant实现EJB无状态会话bean实例
    Nginx简单介绍
    SVN版本号管理工具使用中常见的代码提交冲突问题的解决方法
    深入分析Java中的I/O类的特征及适用场合
    ZOJ 3689 Digging(贪心+dp)
    uva 10641 (来当雷锋的这回....)
    Java编程中“为了性能”尽量要做到的一些地方
    wikioi 1306 机智Trie树
    PE文件结构(三) 输入表
    初始化的数值(int、double等)(一)
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318037.html
Copyright © 2011-2022 走看看