iOS应用中的JS交互
来源:互联网 发布:网络直播策划方案脚本 编辑:程序博客网 时间:2024/06/05 11:11
刚进公司的时候发现公司要做的是hybrid应用,当时对JS交互没有一点概念。自己研究了好几天,最后决定用JavaScriptObjectiveCDelegate协议来实现。现在记录实现过程。
首先,新建一个模型类JsObjCModel,其中包含了需要调用的方法。JavaScriptObjectiveCDelegate协议中声明了两个方法,这两个方法可以在服务端直接调用。其中一个是获取设备ID,服务端调用后直接得到返回值。另一个是注册方法,用来实现获取用户位置(因为获取用户位置需要回调方法)。服务端调用registerMethod方法,传过来一个数组作为参数,我们通过NSArray *args = [JSContext currentArguments];获取到。跟写后台的同事沟通,第一个参数表示回调函数的uuid,第二个参数代表需要实现的方法。知道第二个参数是@"device.getGps",因此调用- (void)getGps,得到结果后拼接数据,调用后台的方法window.IOS.Handle.exec()传回结果。
#import <Foundation/Foundation.h>#import <UIKit/UIKit.h>#import <JavaScriptCore/JavaScriptCore.h>@class HHYWebViewController;@protocol JavaScriptObjectiveCDelegate <JSExport>- (NSString *)getDeviceID; //获取设备id,直接调用的方法- (void)registerMethod;//注册方法,用于带参数或者有回调的调用@end@interface JsObjCModel : NSObject<JavaScriptObjectiveCDelegate>@property (nonatomic, weak) JSContext *jsContext;@property (nonatomic, weak) UIWebView *webView;@property (nonatomic, weak) HHYWebViewController *viewController;@end
#import "JsObjCModel.h"#import "HHYWebViewController.h"@interface JsObjCModel ()<CLLocationManagerDelegate>@end@implementation JsObjCModel{ CLLocationManager *locationManager; NSString *backGpsUuid;}- (void)registerMethod{ NSArray *args = [JSContext currentArguments]; for (id obj in args) { NSLog(@"html传过来的参数:::%@",obj); } if ([args count]>1) { if ([[args[1] toString] isEqualToString:@"device.getGps"]) { [self performSelector:@selector(getGps) withObject:nil afterDelay:0]; backGpsUuid = [args[0] toString]; } }}- (HHYWebViewController *)viewController{ if (!_viewController) { _viewController = [[HHYWebViewController alloc] init]; } return _viewController;}-(void)setLocation:(CLLocationCoordinate2D)location{ NSLog(@"设置值成功"); _location=location; }#pragma mark -获取设备id-(NSString *)getDeviceID{ NSUUID *deviceUID = [UIDevice currentDevice].identifierForVendor; NSString *uuuid=deviceUID.UUIDString; return uuuid;}#pragma mark -获取定位信息- (void)getGps{ locationManager = [[CLLocationManager alloc] init]; locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyBest; locationManager.distanceFilter = 5.0f; if (SYSTEM_VERSION >= 8.0) { [locationManager requestWhenInUseAuthorization]; } [locationManager startUpdatingLocation]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(gotGpsString:) name:@"GotGpsString" object:nil];}- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{ if ([locations count]) { CLLocation *latestLocation = [locations lastObject]; NSString *longitude = [NSString stringWithFormat:@"%f",latestLocation.coordinate.longitude]; NSString *latitude = [NSString stringWithFormat:@"%f",latestLocation.coordinate.latitude]; NSDictionary *arg = @{@"longitude":longitude, @"latitude":latitude}; NSArray *argArray = @[arg]; NSDictionary *backDic = @{@"succ" : @YES, @"callback" : backGpsUuid, @"arguments" : argArray}; NSData *data = [NSJSONSerialization dataWithJSONObject:backDic options:NSJSONWritingPrettyPrinted error:nil]; NSString *gpsString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; [[NSNotificationCenter defaultCenter]postNotificationName:@"GotGpsString" object:nil userInfo:@{@"gpsString":gpsString}]; [locationManager stopUpdatingLocation]; }}- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{ NSLog(@"定位失败,请检查设置"); NSDictionary *backDic = @{@"succ" : @YES, @"callback" : backGpsUuid, @"arguments" : @[@"定位失败"]}; NSData *data = [NSJSONSerialization dataWithJSONObject:backDic options:NSJSONWritingPrettyPrinted error:nil]; NSString *gpsString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; [[NSNotificationCenter defaultCenter]postNotificationName:@"GotGpsString" object:nil userInfo:@{@"gpsString":gpsString}];}- (void)gotGpsString:(NSNotification *)notificat{ NSString *gpsString = [notificat userInfo][@"gpsString"]; NSString *jsStr = [NSString stringWithFormat:@"window.IOS.Handle.exec(%@)",gpsString]; [self.viewController.webView stringByEvaluatingJavaScriptFromString:jsStr]; NSLog(@"gpsString===%@",gpsString); [[NSNotificationCenter defaultCenter] removeObserver:self name:@"GotGpsString" object:nil];}
然后是新建包含UIWebView的视图控制器,在实现文件中注入交互对象。
#import <UIKit/UIKit.h>#import <JavaScriptCore/JavaScriptCore.h>#import "JsObjCModel.h"@interface HHYWebViewController : UIViewController@property (nonatomic,strong)JsObjCModel *model;@property (nonatomic, strong) UIWebView *webView;@end注入交互对象的时机很重要,一开始我只在- (void)webViewDidFinishLoad:(UIWebView *)webView中注入,发现有时候后台在调用交互方法时页面还没有加载完,就调用不到。因此我在此处使用了https://github.com/TomSwift/UIWebView-TS_JavaScriptContext。
在m文件中导入#import "UIWebView+TS_JavaScriptContext.h",并遵守TSWebViewDelegate。在代理方法中注入交互对象,这样就能在每次创建JSContext的时候都注入,避免调用不到的情况。
- (void)webView:(UIWebView *)webView didCreateJavaScriptContext:(JSContext *)ctx{ ctx[@"JsBridge"] = self.model; ctx[@"viewController"] = self; self.model.jsContext = ctx; self.model.webView = self.webView; self.model.viewController = self; ctx.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) { context.exception = exceptionValue; NSLog(@"异常信息:%@", exceptionValue); };}
参考:
http://www.jianshu.com/p/939db6215436
http://blog.csdn.net/lwjok2007/article/details/47058795
- iOS应用中的JS交互
- iOS WebView中的JS交互
- IOS应用通过UIWEBVIEW实现与JS交互
- IOS应用通过UIWEBVIEW实现与JS交互
- IOS应用通过UIWEBVIEW实现与JS交互
- 实例:iOS 中的 JS 交互 OC & Swift 双语
- IOS UIWebView转WKWebView中的js交互问题
- iOS开发中的WKWebView与JS的交互
- IOS中的OC和JS的交互(一)
- IOS JS 交互
- JS 和IOS交互
- ios 与js 交互
- iOS 与 JS 交互
- iOS 与 js 交互
- ios与js 交互
- iOS与JS交互
- iOS WebView JS 交互
- iOS 与 JS 交互
- Clob类型
- 自定义View与ViewGroup
- mips交叉编译环境出现/bin/sh: 1: /bin/gawk/: not found
- C#GridViewMergeCell合并
- 数据库和表的基本使用
- iOS应用中的JS交互
- CRC-CCITT校验码的C程序
- VI中的多行删除与复制
- Zookeeper与paxos算法
- windows隐藏python运行时的终端
- 杭州某单位笔试大题
- SQL中LEFT JOIN、Inner Join、Right Join、Left Outer Join、full join区别
- 在CentOS中添加Swap交换文件,防止内存不足时MYSQL崩溃
- Android源码浅析(六)——SecureCRT远程连接Linux,配置端点和字节码