1幽歼、html ,js 谬盐,oc交互
1.1甸私、點擊html頁面上的button,調(diào)用oc的方法
html代碼:
<div class="editCaptcha">
<img id="captchaImg" src="" onClick="refreshCaptcha()">
</div>
js代碼:
function refreshCaptcha(){
window.location.href = "huihui://refreshCaptchas/";
}
oc代碼:
- (void)refreshCaptchas
{
[self getVerifyCode];
}
1.2飞傀、通過oc方法皇型,傳值給js,從而改變html頁面
html代碼:
<div class="editCaptcha">
<img id="captchaImg" src="" onClick="refreshCaptcha()">
</div>
js代碼:
function setCaptchaImg(url){
document.getElementById('captchaImg').src = url + '&_=' + new Date().getTime();
}
oc代碼:
- (void)getVerifyCode
{
NSMutableDictionary* params = [[NSMutableDictionary alloc]init];
[params safeSetObject:_passport forKey:@"passportId"];
[params safeSetObject:@"58" forKey:@"width"];
[params safeSetObject:@"30" forKey:@"height"];
NSString *url =[XGSDKAuthServer getRequestUrl:@"getCaptcha" withParams:params] ;
[self evaluatingscript:[NSString stringWithFormat:@"setCaptchaImg('%@')", url]];
}
1.3砸烦、點擊html頁面上的button弃鸦,調(diào)用oc的方法并傳參給oc方法。
html代碼:
<div class="editCaptcha">
<input type="number" id="captcha" placeholder="captcha" value="" style="display: inline-block;">
<img id="captchaImg" src="" onClick="refreshCaptcha()">
</div>
<div class="btn">
<input type="button" id="confirmBtn" value="submit" onClick="onConfirmCaptcha()" >
</div>
js代碼:
function onConfirmCaptcha(){
var captcha = getValueById('captcha');
window.location.href = "huihui://onConfirm/?captcha=" + captcha;
}
oc代碼:
- (void)onConfirm:(NSArray *)param
{
NSAssert(param.count == 1, @"傳入的參數(shù)不符合預(yù)期");
//獲取從html頁面?zhèn)鬟^來的參數(shù)
NSString *code = [param safeObjectAtIndex:0];
}
1.4幢痘、在oc的方法中獲取html頁面上的輸入框中的值
html代碼:
<div class="editCaptcha">
<input type="number" id="captcha" placeholder="captcha" value="" style="display: inline-block;">
<img id="captchaImg" src="" onClick="refreshCaptcha()">
</div>
<div class="btn">
<input type="button" id="confirmBtn" value="submit" onClick="onConfirmCaptcha()" >
</div>
js代碼:
function onConfirmCaptcha(){
var captcha = getValueById('captcha');
window.location.href = "kingsoft://onConfirm/?captcha=" + captcha;
}
oc代碼:
-(void)ocCall{
NSString *code=[self evaluatingscript:@"onConfirmCaptcha()"];
}
- (NSString *)onConfirm:(NSArray *)param
{
NSAssert(param.count == 1, @"傳入的參數(shù)不符合預(yù)期");
//獲取從html頁面?zhèn)鬟^來的參數(shù)
NSString *code = [param safeObjectAtIndex:0];
return code;
}
2唬格、html ,js 颜说,oc交互實現(xiàn)原理
js代碼:
//獲取html的觸摸事件
function pageLoad(){
document.ontouchend = function(){
window.location.href = "huihui://documentclick/";
};
}
oc代碼:
- (void)documentclick{
NSLog(@"documentclick");
}
@interface XGSDKBaseViewController ()<IMYWebViewDelegate, UIGestureRecognizerDelegate, UIScrollViewDelegate>{
IMYWebView *_webview;
}
- (NSString *)evaluatingscript:(NSString *)script
{
return [_webview stringByEvaluatingJavaScriptFromString:script];
}
#pragma mark - UIWebView delegate
//攔截js中window.location.href方法發(fā)送的字符串
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
//huihui://onCancel/
NSString *requestString = [[[request URL] absoluteString] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
if ([requestString hasPrefix:@"ios-log:"]) {
NSLog(@"requestString = %@",[request.URL resourceSpecifier]);
return NO;
}
NSURL *url = [request URL];
if ( [url.absoluteString rangeOfString:@"itms-app"].location != NSNotFound || [url.absoluteString rangeOfString:@"itunes.apple.com"].location != NSNotFound ){
[[UIApplication sharedApplication] openURL:url];
return NO;
}
if ([[request.URL scheme] isEqual:@"huihui"]) {
NSMutableString *resourceSpecifier = [[NSMutableString alloc] initWithString:[[request.URL resourceSpecifier] substringFromIndex:2]];
NSArray *arr = [resourceSpecifier componentsSeparatedByString:@"/"];
NSAssert(arr.count > 0, @"URL參數(shù)不符合規(guī)范");
if(arr.count > 0){
NSString *paramstr = [request.URL query];
NSArray *paramarr = [paramstr componentsSeparatedByString:@"&"];
NSString *split = paramarr.count > 0 ? @":" : @"";
NSString *method = [NSString stringWithFormat:@"%@%@", [arr firstObject], split];
NSMutableArray *param = nil;
for(NSInteger i = 0; i < paramarr.count; i++){
NSString *str = [paramarr safeObjectAtIndex:i];
if(![str isEmptyOrNull]){
if(!param){
param = [[NSMutableArray alloc] init];
}
NSString *value = [[[str componentsSeparatedByString:@"="] lastObject] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
if(!value){
value = @"";
}
[param safeAddObject:value];
}
}
SEL selector = NSSelectorFromString(method);
if([self respondsToSelector:selector]){
[self performSelectorOnMainThread:selector withObject:param waitUntilDone:YES];
}else{
NSAssert(NO, @"傳入了不存在的方法名");
}
return NO;
}
}
return YES;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSLog(@"load html webViewDidFinishLoad");
//執(zhí)行還原信息
NSString *htmlInfo = [[XGSDKAuthViewManager sharedManager].htmlInputInfoDic valueForKey:NSStringFromClass([self class])];
if(htmlInfo){
NSString *toJsInfo = [NSString stringWithFormat:@"convertInputInfo('%@')",htmlInfo];
[self evaluatingscript:toJsInfo];
}
[self onload];
[self evaluatingscript:@"pageLoad()"];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error
{
//一個頁面沒有被完全加載之前收到下一個請求购岗,此時迅速會出現(xiàn)此error,error=-999
//此時可能已經(jīng)加載完成,則忽略此error脑沿,繼續(xù)進(jìn)行加載藕畔。
if([error code] == NSURLErrorCancelled)
{
NSLog(@"上個頁面還沒加載完");
return;
}
NSLog(@"load html didFailLoadWithError");
[self setWebViewWithLocalHtml:@"error"];
}
3马僻、若要刷新html頁面庄拇,只需點擊一下html頁面即可,不需要重新運行韭邓。
分析:當(dāng)工程部署到模擬器的時候措近,工程的資源文件會被打包到一個bundle中。若修改了項目目錄下的html文件女淑,讓其在模擬器上顯示瞭郑,需要再次編譯。但是可以從代碼上修改項目尋找html文件的路徑鸭你,讓其在項目目錄下尋找html而不是在bundle中尋找屈张,就可以做到實時更新擒权。
@interface XGSDKBaseViewController ()<IMYWebViewDelegate, UIGestureRecognizerDelegate, UIScrollViewDelegate>{
IMYWebView *_webview;
}
@end
//設(shè)置本地html,localHtml(huihui)
- (void)setWebViewWithLocalHtml:(NSString *)localHtml
{
//js跟css 在不同文件阁谆,要baseURL
NSURL *baseURL = nil;
NSString* templateStr = nil;
templateStr = [self getTemplateStr:localHtml];
//判斷加載位置...
#if (TARGET_IPHONE_SIMULATOR && DEBUG)
baseURL = [NSURL fileURLWithPath:[self getBaseURLInWorkSpace] isDirectory:YES];
NSLog(@"baseURL=%@",baseURL);
#else
baseURL = [NSURL fileURLWithPath:[self getBaseURLInBundle] isDirectory:YES];
#endif // #if TARGET_IPHONE_SIMULATOR
//調(diào)用
[_webview loadHTMLString:templateStr baseURL:baseURL];
}
//返回整個html頁面的代碼
- (NSString *)getTemplateStr:(NSString *)localHtml
{
NSString *templateStr = nil;
#if (TARGET_IPHONE_SIMULATOR && DEBUG)
templateStr = [self getTemplateInWorkSpaceWithHtml:localHtml];
#else
templateStr = [self getTemplateInBundleWithHtml:localHtml];
#endif // #if TARGET_IPHONE_SIMULATOR
return templateStr;
}
- (NSString *)getBaseURLInWorkSpace
{
NSString *srcDir = [NSString stringWithFormat:@"%@/html/",[SamuraiWatcher sharedInstance].sourcePath];
return srcDir;
}
- (NSString *)getBaseURLInBundle
{
NSString *srcDir = [[XGSDKBaseViewController frameworkBundle] bundlePath];
return srcDir;
}
#pragma mark - 正式環(huán)境下的路徑
- (NSString *)getTemplateInBundleWithHtml:(NSString *)html
{
//先看看有沒有對應(yīng)的patch文件碳抄,有的話就拿,沒有就拿bundle
NSString *patch = [self getDownloadPath:@"xx.html"];
NSString *scrPath = nil;
BOOL enablePatch = [self checkFileIsExit:patch];
if(enablePatch){
scrPath = patch;
}else{
scrPath = [self localizedPathForResource:html ofType:@".html" bundle:[self frameworkBundle]];
}
return [NSString stringWithContentsOfFile:scrPath encoding:NSUTF8StringEncoding error:nil];
}
#pragma mark - 工程目錄下用的路徑
- (NSString *)getTemplateInWorkSpaceWithHtml:(NSString *)html
{
//獲取在工程目錄下的
NSString *patch = [self getDownloadPath:@"xx.html"];
NSString *srcPath;
BOOL enablePatch = [self checkFileIsExit:patch];
if(enablePatch){
srcPath = patch;
} else {
srcPath = [NSString stringWithFormat:@"%@/%@.html",[self getBaseURLInWorkSpace],html];
NSLog(@"srcPath=%@",srcPath);
}
return [NSString stringWithContentsOfFile:srcPath encoding:NSUTF8StringEncoding error:nil];
}
+(NSString *)getDownloadPath:(NSString *)fileName{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *cachesDirectory = [paths objectAtIndex:0];
NSString *dirPath = [NSString stringWithFormat:@"%@/%@",cachesDirectory, huihui];
NSString *filePath = [NSString stringWithFormat:@"%@%@%@",dirPath,@"/",fileName];
return filePath;
}
+(BOOL)checkFileIsExit:(NSString *)filePath{
// 創(chuàng)建文件管理器
NSFileManager *fileMgr = [NSFileManager defaultManager];
BOOL isFileExist = [fileMgr fileExistsAtPath:filePath];
if (isFileExist) {
return YES;
}
return NO;
}
- (NSString *)getBaseURLInWorkSpace
{
NSString *srcDir = [NSString stringWithFormat:@"%@/html/",[SamuraiWatcher sharedInstance].sourcePath];
return srcDir;
}
#pragma mark - bundle
+ (NSBundle *)frameworkBundle {
static NSBundle* frameworkBundle = nil;
static dispatch_once_t predicate;
NSString *bundle = @"huihui.bundle";
dispatch_once(&predicate, ^{
NSString* mainBundlePath = [[NSBundle mainBundle] resourcePath];
NSString* frameworkBundlePath = [mainBundlePath stringByAppendingPathComponent:bundle];
frameworkBundle = [NSBundle bundleWithPath:frameworkBundlePath];
});
return frameworkBundle;
}
- (NSString *)localizedPathForResource:(NSString *)name ofType:(NSString *)extension bundle:(NSBundle *)bundle {
NSBundle *searchBundle = bundle ? bundle : [NSBundle mainBundle];
NSString *path = [searchBundle pathForResource:name ofType:extension inDirectory:nil forLocalization:'en'];
path = path ? path : [searchBundle pathForResource:name ofType:extension];
return path;
}