iOS 上使用jsBridge的方法


聊聊iOS開發中的JSBridge

https://www.jianshu.com/p/eff176e220e0

 

https://www.jianshu.com/p/0026be142442

 

iOS 上使用jsBridge的方法

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <button onclick="jsFunc()">打開相冊按鈕</button> <button onclick="jsFunc1()">獲取版本號</button>
  <script>
        function jsFunc() {
         alert('返回參數' + common("openCamera","1234567"))
      };
  function jsFunc1() {
      alert('返回參數' + common("getCode"))
  };
  function common (){
      var args = Array.prototype.slice.call(arguments);
      alert(args);
      var type = "JSbridge";
      var payload = { "type": type, "arguments": args };
      return prompt(JSON.stringify(payload));
  };


  </script>
</body>

</html>

 

iOS 代碼實現

#include <objc/objc.h>
#include <objc/runtime.h>
#include <objc/message.h>

- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
    NSError *err = nil;
    NSData *dataFromString = [prompt dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary *payload = [NSJSONSerialization JSONObjectWithData:dataFromString options:NSJSONReadingMutableContainers error:&err];
    if (!err)
    {
        NSString *type = [payload objectForKey:@"type"];
        if (type && [type isEqualToString:@"JSbridge"])
        {
            NSString *returnValue = @"";
            NSArray *args = [payload objectForKey:@"arguments"];
            if (args.count < 1) {
                completionHandler(returnValue);
                return;
            }
            NSString * functionName = [args firstObject];
            NSMutableArray * newArrayArgs = [[NSMutableArray alloc]initWithArray:args];
            [newArrayArgs removeObjectAtIndex:0];
            SEL sel = newArrayArgs.count < 1 ? NSSelectorFromString(functionName) : NSSelectorFromString([NSString stringWithFormat:@"%@:",functionName]);
            if ([self respondsToSelector:sel]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
                returnValue = [self performSelector:sel withObject:newArrayArgs];
#pragma clang diagnostic pop
                if(![returnValue isKindOfClass:[NSString class]])
                {
                    returnValue = @"";
                }
            }

            completionHandler(returnValue);
        }
    }
}



- (NSString *)getAppVersion {
    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
    NSString *app_Version = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
    return app_Version;
}



-(void)openCamera:(NSArray *)argsArray{
    if (argsArray.count > 0) {
        NSString *orderId = argsArray[0];
        // 打開相機
     }
}

 

這上面注意點

  1. var type = "JSbridge"; 是web 和 app上確定好的協議
  2. web 傳遞的數據是[方法名,參數1,參數2,...]
  3. 通過方法名字生成方法 sel
  4. 通過是否有參數來確定使用那種sel,如果有參數那么需要使用帶參數的sel,否則使用沒有參數的sel
  5. 通過 performSelector 來執行sel,注意在func沒有返回值的時候,那么performSelector返回的就是參數,需要特殊處理一下
  6. 走過的彎路
 Method method = class_getInstanceMethod([self class], sel);
    
    const char *types = method_getTypeEncoding(method);
    NSLog(@"--------  %@",[NSString stringWithUTF8String: types]);
//    v為 void , i 為 int , f為float
//
//    ? 為 block ( void(^)(void) )
//
//    開頭帶v16 v32表示無返回值,其他帶什么表示返回值為什么類型;
//
//    :8 是 SEL標示
//
//    @28 返回值為 NSString, @16代表參數為 NSString,
//
//    @24 返回值為id,
// 通過types來確定返回值是什么
returnValue =  ((NSString* (*) (id,SEL))objc_msgSend)(self,sel);
((void (*) (id,SEL))objc_msgSend)(self,sel);
returnValue =  ((NSString * (*) (id,SEL,id))objc_msgSend)(self,sel,newArrayArgs);

 

 真心的不建議用 objc_msgSend 因為如果要用這個需要更改編譯器,這樣編譯器就不檢測類型了,對app 對安全是一個重大的曲線 
 
image.png


作者:SteveKwok
鏈接:https://www.jianshu.com/p/0026be142442
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM