Web和Native的交互,也就是iOS object-C与javascript之间的交互;核心代码是
[webView stringByEvaluatingJavascriptFromString:@"xxxxxxxxxx"];
这里主要用到的就是iOS WebKit加载网络页面,功能有获取用户位置信息,拍照,判断当前手机网络连接类型的功能(拍照和获取当前用户地理位置需要真机环境下)所以需要导入以下几个框架:
这里需要注意的是iOS8以后获取位置地理信息需要在info.plist文件中手动添加:
NSLocationWhenInUseUsageDescriptionNSLocationAlwaysUsageDescription
设置他们的键值为YES;
那么现在我们的准备工作就做好了;
首先加载本地的Html文件:这里因为需要调用系统相机所以添加代理UIWebViewDelegate,UINavigationControllerDelegate, UIImagePickerControllerDelegate
@interface ViewController ()<UIWebViewDelegate,UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
NSString *callback;
}
@PRoperty (nonatomic,strong) UIWebView *webView;
@property (nonatomic,strong) MapViewController *map;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_webView=[[UIWebView alloc]initWithFrame:self.view.bounds];
[self.view addSubview:_webView];
_webView.delegate=self;
NSString*filePath = [[NSBundle mainBundle] pathForResource:@"api"ofType:@"html"];
NSString*fileContent =[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
[_webView loaDHTMLString:fileContent baseURL:nil];
}
现在开始上干货了:WebViewDelegate代理方法
//js调用iOS- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString*requestString =[[request URL] absoluteString];//jS协议头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];
}elseif([[vals objectAtIndex:0] isEqualToString:@"photolibrary"]) {
callback= [vals objectAtIndex:1];
[self doAction:UIImagePickerControllerSourceTypePhotoLibrary];
}elseif([[vals objectAtIndex:0] isEqualToString:@"album"]) {
callback= [vals objectAtIndex:1];
[self doAction:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
}elseif([[vals objectAtIndex:0] isEqualToString:@"location"]) {
callback= [vals objectAtIndex:1];
[self sendlocationInformation];
}elseif([[vals objectAtIndex:0] isEqualToString:@"netType"]) {
callback= [vals objectAtIndex:1];
[self sendNetWorkType];
}else{
[webView stringByEvaluatingJavaScriptFromString:@"alert('未定义/lwme.cnblogs.com');"];
}returnNO;
}returnYES;
}
点击加载的Web页面的按钮,native端响应事件:
- (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;
}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 presentViewController:imagePicker animated:YES completion:nil];
}
}
拍照,获取相册的代理方法:
- (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 = [UIImageJPEGRepresentation(originalImage,0.5) base64EncodedStringWithOptions:0];
[self performSelectorOnMainThread:@selector(doCallback:) withObject:base64 waitUntilDone:NO];
[av dismissWithClickedButtonIndex:0animated:YES];
});
}
[picker dismissViewControllerAnimated:YES completion:nil];
}- (void)doCallback:(NSString *)data
{
[_webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@('%@');", callback, data]];
}
Web页面的HTML代码信息:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>微信JS-SDK Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
<link rel="stylesheet" href="CSS/style_demo.css">
<script>functionopenLocation(){window.location.href="js-call://location/locationCallback";
}functionchooseImage(){window.location.href="js-call://photolibrary/photolibraryCallback";
}functiongoCamera(){window.location.href="js-call://camera/cameraCallback";
}functiongetNetType(){window.location.href="js-call://netType/netTypeCallback";
}functionopenAlbum(){window.location.href="js-call://album/albumCallback";
}functioncameraCallback(imageData) {varimg =createImageWithBase64(imageData);
document.getElementById("camera_image_div").appendChild(img);
}functionphotolibraryCallback(imageData) {varimg =createImageWithBase64(imageData);
document.getElementById("choose_image_div").appendChild(img);
}functionalbumCallback(imageData) {varimg =createImageWithBase64(imageData);
document.getElementById("open_image_div").appendChild(img);
}functioncreateImageWithBase64(imageData) {varimg =newImage();
img.src= "data:image/jpeg;base64," +imageData;
img.style.width= "200px";
img.style.height= "200px";returnimg;
}</script>
</head>
<body ontouchstart="">
<div class="wxapi_container">
<div class="lbox_close wxapi_form">
<h3 id="menu-image">图像接口</h3>
<span class="desc">地理位置</span>
<button class="btn btn_primary" id="openLocation" onclick="openLocation()">地理位置</button>
<span id="spLoc" class="desc"></span>
<span class="desc">选择图片</span>
<button class="btn btn_primary" id="chooseImage" onclick="chooseImage()">选择图片</button>
<div id="choose_image_div"></div>
<span class="desc">拍照</span>
<button class="btn btn_primary" id="takePic" onclick="goCamera()">拍照</button>
<div id="camera_image_div"></div>
<span class="desc">网络连接类型</span>
<button class="btn btn_primary" id="netType" onclick="getNetType()">网络连接类型</button>
<span id="spNet" class="desc"></span>
<span class="desc">相册</span>
<button class="btn btn_primary" id="openAlbum" onclick="openAlbum()">打开相册</button>
<div id="open_image_div"></div>
<div id="hidpicdiv" style="display: none;">
<img id="hidpic" src="" width="200" height="200"/>
</div>
</div>
</div>
</body>
获取当前用户位置信息和判断当前手机的连接网络类型:
- (void)sendNetWorkType
{if([NetWorkType getNetworkTypeFromStatusBar]==0) {
UIAlertView*alert = [[UIAlertView alloc] initWithTitle:@"网络连接类型"message:@"当前无网络连接"delegate:self cancelButtonTitle:@"OK"otherButtonTitles:nil, nil];
[alert show];
}if([NetWorkType getNetworkTypeFromStatusBar]==1) {
UIAlertView*alert = [[UIAlertView alloc] initWithTitle:@"网络连接类型"message:@"当前2G连接"delegate:self cancelButtonTitle:@"OK"otherButtonTitles:nil, nil];
[alert show];
}if([NetWorkType getNetworkTypeFromStatusBar]==2) {
UIAlertView*alert = [[UIAlertView alloc] initWithTitle:@"网络连接类型"message:@"当前为3G连接"delegate:self cancelButtonTitle:@"OK"otherButtonTitles:nil, nil];
[alert show];
}if([NetWorkType getNetworkTypeFromStatusBar]==3) {
UIAlertView*alert = [[UIAlertView alloc] initWithTitle:@"网络连接类型"message:@"当前为4G连接"delegate:self cancelButtonTitle:@"OK"otherButtonTitles:nil, nil];
[alert show];
}if([NetWorkType getNetworkTypeFromStatusBar]==5) {
UIAlertView*alert = [[UIAlertView alloc] initWithTitle:@"网络连接类型"message:@"当前为WIFI连接"delegate:self cancelButtonTitle:@"OK"otherButtonTitles:nil, nil];
[alert show];
}
}- (void)sendlocationInformation
{
_map=[[MapViewController alloc]init];
_map.modalPresentationStyle=UIModalPresentationFullScreen;
[self presentViewController:_map animated:YES completion:nil];
}
获取当前用户的位置信息:
头文件导入:
#import<MapKit/MapKit.h>#import<CoreLocation/CoreLocation.h>
加载地图:
@interfaceMapViewController ()<MKMapViewDelegate,CLLocationManagerDelegate>{
NSString*locationStr;
}
@property (nonatomic,strong) MKMapView*mapView;
@property (nonatomic,strong) CLLocationManager*locationManager;@end@implementationMapViewController- (void)viewDidLoad {
[super viewDidLoad];//Do any additional setup after loading the view, typically from a nib._mapView =[[MKMapView alloc]initWithFrame:self.view.frame];
[self.view addSubview:_mapView];
UIButton*backButton =[UIButton buttonWithType:UIButtonTypeCustom];
backButton.frame= CGRectMake((self.view.bounds.size.width)/2-40,20,80,30);
[backButton setTitle:@"返回"forState:UIControlStateNormal];
[backButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
backButton.backgroundColor=[UIColor cyanColor];
backButton.titleLabel.textAlignment=NSTextAlignmentCenter;
[backButton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
[_mapView addSubview:backButton];//1.跟踪用户位置(显示用户的具体位置)self.mapView.userTrackingMode =MKUserTrackingModeFollow;//2.设置地图类型self.mapView.mapType =MKMapTypeStandard;//3.设置代理self.mapView.delegate=self;
_locationManager=[[CLLocationManager alloc] init];
_locationManager.delegate=self;//设置定位精度_locationManager.desiredAccuracy=kCLLocationAccuracyBest;//定位频率,每隔多少米定位一次CLLocationDistance distance=1.0;//1米定位一次_locationManager.distanceFilter=distance;
_locationManager.desiredAccuracy=kCLLocationAccuracyBest;if([_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[_locationManager requestWhenInUseAuthorization];
}
[_locationManager startUpdatingLocation];
}#pragmamark - MKMapViewDelegate/**
* 当用户的位置更新,就会调用
*
* @param userLocation 表示地图上蓝色那颗大头针的数据*/- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
CLLocationCoordinate2D center=userLocation.location.coordinate;//设置地图的显示范围, 让其显示到当前指定的位置MKCoordinateSpan span = MKCoordinateSpanMake(0,0);//这个显示大小精度自己调整MKCoordinateRegion region =MKCoordinateRegionMake(center, span);
[mapView setRegion:region animated:YES];
}//可以通过模拟器设置一个虚拟位置,否则在模拟器中无法调用此方法-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
CLLocation*location=[locations firstObject];//取出第一个位置CLLocationCoordinate2D coordinate=location.coordinate;//位置坐标locationStr= [NSString stringWithFormat:@"经度:%f,纬度:%f,海拔:%f,航向:%f,行走速度:%f",coordinate.longitude,coordinate.latitude,location.altitude,location.course,location.speed];//如果不需要实时定位,使用完即使关闭定位服务[_locationManager stopUpdatingLocation];
}- (void)back
{
[self dismissViewControllerAnimated:YES completion:nil];
}
判断当前手机网络连接的类型:
这里我写了一个类方法,因为我们判断当前用户使用的网络连接方式可以从状态栏信息中获取:
在.h中:
@interfaceNetWorkType : NSObject
typedefenum{
NETWORK_TYPE_NONE=0,
NETWORK_TYPE_2G=1,
NETWORK_TYPE_3G=2,
NETWORK_TYPE_4G=3,
NETWORK_TYPE_5G=4,//5G目前为猜测结果NETWORK_TYPE_WIFI=5,
}NETWORK_TYPE;+(NETWORK_TYPE)getNetworkTypeFromStatusBar;@end
在.m:
#import"NetWorkType.h"#import"AppDelegate.h"@implementationNetWorkType+(NETWORK_TYPE)getNetworkTypeFromStatusBar {
UIapplication*app =[UIApplication sharedApplication];
NSArray*subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews];
NSNumber*dataNetworkItemView =nil;for(idsubviewinsubviews) {if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView")class]]) {
dataNetworkItemView=subview;
break;
}
}
NETWORK_TYPE nettype=NETWORK_TYPE_NONE;
NSNumber* num = [dataNetworkItemView valueForKey:@"dataNetworkType"];
nettype=[num intValue];returnnettype;
}@end
下面就是我写的关于这个demo运行的效果图片:
以上就是自己写的iOS Native-Web交互方面的心得,转载请说明出处;O(∩_∩)O谢谢