JavaScript和Objective-c交互

JavaScript和Objective-c交互

  • 現(xiàn)在的開發(fā)不再是純原生的開發(fā)了品抽,在很多APP中,很多活動頁面甜熔、或者說專題頁面圆恤,都采用了H5的頁面
  • 這種方式的好處就是這些頁面可以很方便的修改,不用提交新的APP到AppStore去審核
  • 那么js和oc的交互就分為:js調用oc方法腔稀、oc調用js方法 兩種情況

OC調用JS

  • stringByEvaluatingJavaScriptFromString方法執(zhí)行js語句
// 執(zhí)行JS語句
[webView stringByEvaluatingJavaScriptFromString:@"alert(100);"];

// 利用JS獲得當前網(wǎng)頁的標題
NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title;"];

// 執(zhí)行JS函數(shù)
[webView stringByEvaluatingJavaScriptFromString:@"login();"];

JS調用OC

  • 這種模式有點麻煩盆昙,就是傳遞參數(shù)的問題

  • 不傳遞參數(shù)、一個或者兩個參數(shù)焊虏,這些情況比較簡單

  • 但是想傳遞多個參數(shù)淡喜,就比較麻煩了

  • 思路:

    • 1、在網(wǎng)頁中發(fā)送請求诵闭,如果是想調用OC方法炼团,那么就需要自定義協(xié)議頭
    • 2、請求的地址需要自定義:協(xié)議頭和方法名還有參數(shù)的拼接需要定義好規(guī)則
    • 3疏尿、在UIWebView的代理方法中攔截請求瘟芝,判斷協(xié)議頭
    • 4、截取出方法名和參數(shù)
沒有參數(shù)
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    // URL:YYHttp://方法名
    NSString *url = request.URL.absoluteString;
    // 自定義協(xié)議頭
    NSString *scheme = @"YYHttp://";
    if ([url hasPrefix:scheme]) {
        
        NSString *methodName = [url substringFromIndex:scheme.length];
        [self performSelector:NSSelectorFromString(methodName) withObject:nil];
        return NO;
    }
    return YES;
}
一個或者兩個參數(shù)
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    // url == YYHttp://sendMessage_number2_?200&300
    NSString *url = request.URL.absoluteString;
    NSString *scheme = @"YYHttp://";
    if ([url hasPrefix:scheme]) {
        // 獲得協(xié)議后面的路徑  path == sendMessage_number2_?200&300
        NSString *path = [url substringFromIndex:scheme.length];
        // 利用?切割路徑
        NSArray *subpaths = [path componentsSeparatedByString:@"?"];
        // 方法名 methodName == sendMessage:number2:
        NSString *methodName = [[subpaths firstObject] stringByReplacingOccurrencesOfString:@"_" withString:@":"];
        // 參數(shù)  200&300
        NSString *param = [subpaths lastObject];
        NSArray *subparams = nil;
        if (subpaths.count == 2 || [param containsString:@"&"]) {
            subparams = [param componentsSeparatedByString:@"&"];
        }
        // 取出前面的2個參數(shù)
        NSString *firstParam = [subparams firstObject];
        NSString *secondParam = subparams.count <= 1 ? nil : [subparams lastObject];
        
        [self performSelector:NSSelectorFromString(methodName) withObject:firstParam withObject:secondParam];
        
        return NO;
    }
    return YES;
}

三個或以上參數(shù)
  • 這個時候就需要自定義方法去實現(xiàn)傳遞多個參數(shù)
  • 需要用到NSInvocation
  • 只要下面這個方法定義好褥琐,那么直接傳入數(shù)組即可
  • 一個或者兩個參數(shù)也可以使用下面這種方式
- (id)performSelector:(SEL)selector withObjects:(NSArray *)objects
{
    // 方法簽名(方法的描述)
    NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selector];
    if (signature == nil) {
        // 一般在這里面拋出異常
        //@throw [NSException exceptionWithName:@"方法名錯誤" reason:@"方法找不到" userInfo:nil];
        //[NSException raise:@"方法名錯誤" format:@"%@方法找不到", NSStringFromSelector(selector)];
    }
    
    // NSInvocation : 利用一個NSInvocation對象包裝一次方法調用(方法調用者模狭、方法名、方法參數(shù)踩衩、方法返回值)
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    invocation.target = self;
    invocation.selector = selector;
    
    // 設置參數(shù)
    NSInteger paramsCount = signature.numberOfArguments - 2; // 除self嚼鹉、_cmd以外的參數(shù)個數(shù)
    paramsCount = MIN(paramsCount, objects.count);
    for (NSInteger i = 0; i < paramsCount; i++) {
        id object = objects[i];
        if ([object isKindOfClass:[NSNull class]]) continue;
        [invocation setArgument:&object atIndex:i + 2];
    }
    
    // 調用方法
    [invocation invoke];
    
    // 獲取返回值
    id returnValue = nil;
    if (signature.methodReturnLength) { // 有返回值類型贩汉,才去獲得返回值
        [invocation getReturnValue:&returnValue];
    }
    return returnValue;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市锚赤,隨后出現(xiàn)的幾起案子匹舞,更是在濱河造成了極大的恐慌,老刑警劉巖线脚,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赐稽,死亡現(xiàn)場離奇詭異,居然都是意外死亡浑侥,警方通過查閱死者的電腦和手機姊舵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寓落,“玉大人括丁,你說我怎么就攤上這事×嫜。” “怎么了史飞?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長仰税。 經常有香客問我构资,道長,這世上最難降的妖魔是什么陨簇? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任吐绵,我火速辦了婚禮,結果婚禮上河绽,老公的妹妹穿的比我還像新娘拦赠。我一直安慰自己,他們只是感情好葵姥,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布荷鼠。 她就那樣靜靜地躺著,像睡著了一般榔幸。 火紅的嫁衣襯著肌膚如雪允乐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天削咆,我揣著相機與錄音牍疏,去河邊找鬼。 笑死拨齐,一個胖子當著我的面吹牛鳞陨,可吹牛的內容都是我干的。 我是一名探鬼主播瞻惋,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼厦滤,長吁一口氣:“原來是場噩夢啊……” “哼援岩!你這毒婦竟也來了?” 一聲冷哼從身側響起掏导,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤享怀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后趟咆,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體添瓷,經...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年值纱,在試婚紗的時候發(fā)現(xiàn)自己被綠了鳞贷。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡虐唠,死狀恐怖搀愧,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情凿滤,我是刑警寧澤妈橄,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布庶近,位于F島的核電站翁脆,受9級特大地震影響,放射性物質發(fā)生泄漏鼻种。R本人自食惡果不足惜反番,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望叉钥。 院中可真熱鬧罢缸,春花似錦、人聲如沸投队。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽敷鸦。三九已至息楔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扒披,已是汗流浹背值依。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留碟案,地道東北人愿险。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像价说,于是被迫代替她去往敵國和親辆亏。 傳聞我的和親對象是個殘疾皇子风秤,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內容