iOS、Android 與 Vue的交互(使用DSBridge第三方庫)

ddd.jpeg

圖片來自網絡

首先我是一個半吊子的Vue開發者,也是一個半吊子的Android開發者,iOS才是我的主業,只不過現在是我都有在弄。寫這個文章,主要還是記錄并分享給第一次用Vue 和 Android、iOS交互的人使用。網上資料也是參差不齊。很多都是復制別人的。沒有成系統性。

一、 Vue方面的集成及使用

1、在Vue項目中使用npm命令安裝DSBridge 將DSBridge集成到你的項目中

npm install dsbridge 

2、再main.js中補充代碼

var dsBridge = require('dsbridge')
Vue.prototype.$bridge = dsBridge;

3、測試代碼編寫(以下是我完整的測試代碼)

<template>
  <rt-view>
    <rt-button type="primary" size="large" @click.native="handleOKClick">確定</rt-button>
  </rt-view>
</template>

<script>
export default {
  data() {
    return {};
  },
  mounted() {

    // 這是重點,涉及到Vue的域問題,如果想要將傳進的參數進其他函數的使用,就必須將this 賦值給 一個常量保存起來,再調用其methds中的函數,將其參數進行使用
    let than = this;

    // 注冊 javascript API 
    dsBridge.register('callJsFunction',function(data1, data2) {
      console.log("登錄信息打印:" + data1);
      console.log("用戶信息打印:" + data2);

      // 將傳進來的參數交給 methods 進行處理(如果在mounthed中進行處理,會報錯)
      than.addUserInfoAndToken(data1, data2);
      return "調用Vue函數回調文字";
    })
  },
  methods: {

    // 處理 注冊事件(注冊后,客戶端iOS-Android就能調用你的函數)
    addUserInfoAndToken(str, str1) {
      console.log("打印了,就意味著被調用了");
      const auth = JSON.parse(str);
      this.$store.commit('UPDATE_AUTH', auth);
      this.$store.commit('UPDATE_USER', str1);
      this.$router.push({
        name: "main"
      });
    },

    // 按鈕點擊事件(點擊后能夠調用客戶端-iOS、Android的函數)
    handleOKClick() {
      console.log("打印了,就意味著調用iOS程序了");

      // 同步調用(調用后客戶端給的反饋是同步進行的)(函數名需要跟客戶端約定好)
      var str = dsBridge.call("echo.testSyn","syn");

      // 異步調用(調用后客戶端給的反饋是異步進行的-也就是可能客戶端會過一會才給你回復他處理好了)(函數名需要跟客戶端約定好)
      dsBridge.call("echo.testAsyn","asyn", function (v) {
        console.log("打印了,就意味著客戶端回調了");
        console.log(v);
      })
    }
  }
};
</script>

<style scoped>

</style>

至此Vue的代碼集成已經寫好,請大家重點看代碼中的注釋。里面有些小細節很重要






二、 Android 方面的集成及使用

我使用的Android Studio版本是 2021年10月12號的最新版。

版本號
WeChate0ec540c345d45d646d95e124e86207b.png

我的build.gradle配置為:
defaultConfig {
        applicationId "XXXXX"
        targetSdk 31
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        minSdkVersion 24
        targetSdkVersion 31
    }

dependencies {
        // 集成 DSBridge
        implementation 'com.github.wendux:DSBridge-Android:3.0-SNAPSHOT'
    }

因為我使用的這個Android 版本所以我的 jitpack.io 是加在 settings.gradle中,如圖下所示:

WeChatee0daa179be946f9aaaef9b65a01e972.png

maven { url 'https://jitpack.io' }

配置好了后,將包下載下來。接下來進入代碼使用環節。

在xml中定義一個組件:

<wendu.dsbridge.DWebView
        android:id="@+id/main_webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

新建一個 JsEchoApi 的class類,這個類主要用于注冊Vue調用Android 的函數。代碼如下

public class JsEchoApi {

    @JavascriptInterface
    public Object testSyn(Object args) throws JSONException {
        LogTool.simplenessLog("我調用了,是同步調用");
        return  args;
    }

    @JavascriptInterface
    public void testAsyn(Object args, CompletionHandler handler) {
        LogTool.simplenessLog("我調用了,是異步調用");
        handler.complete(args);
    }
}

之后在Activity中使用它。

public class WebViewActivity extends BaseActivity {

    private DWebView webView;

    private String sLoginData, sUserInfo;

    @SuppressLint("WrongViewCast")
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_webview);

        StatusBarUtil.setColor(WebViewActivity.this, Color.parseColor("#db2c42"), 1);

        // 上層傳遞過來的封裝數據的對象
        sLoginData = (String)this.getIntent().getSerializableExtra("LoginData");
        sUserInfo = (String)this.getIntent().getSerializableExtra("UserInfo");

        // 定義WebView組件
        webView = findViewById(R.id.main_webview);

        // 開啟Debug調試模式
        DWebView.setWebContentsDebuggingEnabled(true);

        // 重點:注冊API,其中echo為API的空間名(這個JsEchoApi 的 class 里面的函數就是 給 Vue調用 Android 的函數)
        webView.addJavascriptObject(new JsEchoApi(), "echo");

        monitoring();
        setWebViewConfig(webView, this);
        // 加載一個網頁
        webView.loadUrl("http://172.19.23.47:8080");
    }
    
    // 監控WebView的回調
    public void monitoring() {

        webView.setWebViewClient(new WebViewClient() {
            // 在頁面加載結束時調用。
            @Override
            public void onPageFinished(WebView view, String url) {
                // 設定加載結束的操作
                LogTool.simplenessLog("在頁面加載結束時調用");

                // 重點(這個是在頁面加載結束時才調用Vue里面的函數)(這個callJsFunction就是 Android 調用 Vue的函數)
                webView.callHandler("callJsFunction", new Object[]{sLoginData, sUserInfo}, new OnReturnValue<String>() {
                    @Override
                    public void onValue(String retValue) {
                        LogTool.simplenessLog(retValue);
                    }
                });
            }
    }
}

這樣一來 Android 在 onPageFinished 調用后,使用callJsFunction 就能調用到 Vue中的函數。完成了Android-Vue 交互
同時點擊網頁的確認按鈕后,就能調用到 Android 中的函數。完成了Vue-Android 交互






三、 iOS 方面的集成及使用

先在 CocoaPods 中集成

pod "dsBridge"

新建一個 JSApi 的 NSObject 類,代碼如下

@implementation JSApi

// 同步API
- (NSString *)testSyn:(NSString *)msg {
    Log(@"我被調用了,是同步調用%@", msg);
    return [msg stringByAppendingString:@"[syn call]"];
}

// 異步API
- (void)testAsyn:(NSString *)msg :(JSCallback)completionHandler {
    Log(@"我被調用了,是異步調用%@", msg);
    completionHandler([msg stringByAppendingString:@"[asyn call]"], YES);
}

@end

之后在Controller使用它

#import "DZWebViewController.h"
#import <WebKit/WebKit.h>
#import "DWKWebView.h"
#import "JSApi.h"

@interface DZWebViewController () <WKNavigationDelegate, WKUIDelegate, WKScriptMessageHandler>

@property (nonatomic, strong) DWKWebView *dwebview;

//@property (nonatomic, strong) WKWebView *dwebview;

@end

@implementation DZWebViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.dwebview = [[DWKWebView alloc] initWithFrame:CGRectZero];

    // 開啟Debug調試模式
    [self.dwebview setDebugMode:true];
    self.dwebview.DSUIDelegate = self;
    // 導航代理
    self.dwebview.navigationDelegate = self;
    // 是否允許手勢左滑返回上一級, 類似導航控制的左滑返回
    self.dwebview.allowsBackForwardNavigationGestures = YES;
    
    [self.view addSubview:self.dwebview];
    
    [self.dwebview mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.view.mas_left);
        make.right.equalTo(self.view.mas_right);
        make.top.equalTo(self.vNavigation.mas_bottom);
        make.bottom.equalTo(self.view.mas_bottom);
    }];
    
    // 重點:注冊API,其中echo為API的空間名(這個JSApi 的 NSObject 里面的函數就是 給 Vue調用 iOS 的函數)
    [self.dwebview addJavascriptObject:[[JSApi alloc] init] namespace:@"echo"];

    [self.dwebview loadUrl:@"http://172.19.23.47:8080"];
    
    // 讓Xcode的控制臺可以打印HTML的console.log
    [self catchJsLog];
    
}

// 重寫html的Log打印方法,因為在網頁中的打印不會在Xcode的控制臺出現。所以重寫方法后,讓其打印可以在Xcode的控制臺出現.
- (void)catchJsLog{
    if(DEBUG){
        NSString *sJS = @"console.log = (function(oriLogFunc){return function(str){oriLogFunc.call(console,str);window.webkit.messageHandlers.log.postMessage(str);}})(console.log);";
        WKUserScript *script = [[WKUserScript alloc] initWithSource:sJS injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
        [self.dwebview.configuration.userContentController addUserScript:script];
        [self.dwebview.configuration.userContentController addScriptMessageHandler:self name:@"log"];
    }
}

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if ([message.name isEqualToString:@"log"]) {
        Log(@"Web頁面打印:%@", message.body);
    }
}

#pragma mark - WKNavigationDelegate
// 頁面開始加載時調用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
    Log(@"頁面開始加載時調用");
}

// 頁面加載失敗時調用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
    Log(@"頁面加載失敗時調用");
}

// 當內容開始返回時調用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
    Log(@"當內容開始返回時調用");
}

// 頁面加載完成之后調用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    Log(@"頁面加載完成之后調用");

    // 重點(這個是在頁面加載結束時才調用Vue里面的函數)(這個callJsFunction就是 iOS 調用 Vue的函數)
    [self.dwebview callHandler:@"callJsFunction" arguments:@[@"我是登錄信息",@"我是用戶信息"] completionHandler:^(NSNumber* value){
        Log(@"%@",value);
    }];
}



@end

這樣一來 iOS 在 didFinishNavigation 調用后,使用callJsFunction 就能調用到 Vue中的函數。完成了iOS-Vue 交互
同時點擊網頁的確認按鈕后,就能調用到 iOS 中的函數。完成了Vue-iOS 交互

文章就寫到了這里。有什么問題的可以評論討論交流。感謝!!!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容