Web和Native的交互,也就是iOS object-C與Javascript之間的交互;核心代碼是 [webView stringByEvaluatingJavaScriptFromString:@"xxxxxxxxxx"]; 這裡主要用到的就是iOS WebKit載入網路頁面,功能有獲取用戶位 ...
Web和Native的交互,也就是iOS object-C與Javascript之間的交互;核心代碼是
[webView stringByEvaluatingJavaScriptFromString:@"xxxxxxxxxx"];
這裡主要用到的就是iOS WebKit載入網路頁面,功能有獲取用戶位置信息,拍照,判斷當前手機網路連接類型的功能(拍照和獲取當前用戶地理位置需要真機環境下)所以需要導入以下幾個框架:
這裡需要註意的是iOS8以後獲取位置地理信息需要在info.plist文件中手動添加:
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
設置他們的鍵值為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]; } 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 if([[vals objectAtIndex:0] isEqualToString:@"location"]) { callback = [vals objectAtIndex:1]; [self sendlocationInformation]; } else if([[vals objectAtIndex:0] isEqualToString:@"netType"]) { callback = [vals objectAtIndex:1]; [self sendNetWorkType]; } else { [webView stringByEvaluatingJavaScriptFromString:@"alert('未定義/lwme.cnblogs.com');"]; } return NO; } return YES; }
點擊載入的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:0 animated: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> function openLocation(){ window.location.href="js-call://location/locationCallback"; } function chooseImage(){ window.location.href="js-call://photolibrary/photolibraryCallback"; } function goCamera(){ window.location.href="js-call://camera/cameraCallback"; } function getNetType(){ window.location.href="js-call://netType/netTypeCallback"; } function openAlbum(){ window.location.href="js-call://album/albumCallback"; } function cameraCallback(imageData) { var img = createImageWithBase64(imageData); document.getElementById("camera_image_div").appendChild(img); } function photolibraryCallback(imageData) { var img = createImageWithBase64(imageData); document.getElementById("choose_image_div").appendChild(img); } function albumCallback(imageData) { var img = createImageWithBase64(imageData); document.getElementById("open_image_div").appendChild(img); } function createImageWithBase64(imageData) { var img = new Image(); img.src = "data:image/jpeg;base64," + imageData; img.style.width = "200px"; img.style.height = "200px"; return img; } </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>
載入地圖:
@interface MapViewController ()<MKMapViewDelegate,CLLocationManagerDelegate> { NSString *locationStr; } @property (nonatomic,strong) MKMapView *mapView; @property (nonatomic,strong) CLLocationManager *locationManager; @end @implementation MapViewController - (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]; } #pragma mark - 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中:
@interface NetWorkType : NSObject typedef enum { 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" @implementation NetWorkType +(NETWORK_TYPE)getNetworkTypeFromStatusBar { UIApplication *app = [UIApplication sharedApplication]; NSArray *subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews]; NSNumber *dataNetworkItemView = nil; for (id subview in subviews) { if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) { dataNetworkItemView = subview; break; } } NETWORK_TYPE nettype = NETWORK_TYPE_NONE; NSNumber * num = [dataNetworkItemView valueForKey:@"dataNetworkType"]; nettype = [num intValue]; return nettype; } @end
下麵就是我寫的關於這個demo運行的效果圖片:
以上就是自己寫的iOS Native-Web交互方面的心得,轉載請說明出處;O(∩_∩)O謝謝