【一起学Rust | Tauri2.0框架】基于 Rust 与 Tauri 2.0 框架实现跨平台二维码扫描应用


前言

这篇文章的话题在之前的文章中其实已经提到过了,但是那会Tauri2还在内测阶段,就连这个插件也是在内测的,因此现在根据最新的插件更新一下文章。(加上了Tauri2新的特性。)

在以前的Tauri中是如何来扫码呢?我们大概能想到这种方式,实时获取视频流,然后采样几帧去扫码,然后返回结果。或者使用第三方库

以下内容来自于AI

在安卓应用中实现扫描二维码操作,通常需要使用第三方的扫描库来帮助实现。以下是一种常见的实现方法:

  1. 集成扫描库:在你的安卓应用中引入一个扫描库,比如Zxing库,这是一个开源的扫描库,支持扫描各种类型的条形码和二维码。

  2. 添加权限:确保在AndroidManifest.xml文件中添加相机权限,因为扫描二维码需要访问设备的相机功能。

<uses-permission android:name="android.permission.CAMERA" />
  1. 创建扫描界面:在你的应用中创建一个扫描界面,并在该界面中初始化并启动扫描库。

  2. 处理扫描结果:当用户扫描二维码成功后,扫描库会返回扫描结果,你可以在代码中获取该结果并进行相应的处理,比如打开一个链接、展示扫描到的文本等。

  3. 销毁扫描界面:在不需要扫描功能时,记得销毁扫描界面,释放相机资源。

这是一个简单的实现流程,实际上这个思路是对的,你可能想到安卓或者IOS应该已经有可靠的工具来轻松实现扫码功能了吧,但是事实没有那么容易,因为Tauri2其实是个限制了权限的Webview,这就导致很多原生的应用是无法使用的。(后面对于安卓应用开发来说,可以使用JNI,当然,使用这种方式只能解决安卓的问题,如果是IOS就不行了),如果要想能够跨平台,比如支持IOS,那就得去抓视频流。

现在,用不着那么麻烦了。Tauri官方终于出了完整的扫码插件,他就是——Barcode Scanner,它除了可以简单配置就能集成扫码功能外,最主要是安卓和IOS全部支持,要比自己去做容易的多。


一、安装插件

1. 安装准备

首先,确保你安装的Rust版本符合条件,该插件要求你的Rust版本大于1.77.2.

然后就是看你的应用平台是否支持该插件,官方给出以下表格

在这里插入图片描述

可以明显看到,只有移动端系统受支持,也就是你的应用只能是在androidios上,这个插件才会有用,否则插件是用不了的。

2. 自动安装(推荐)

使用你所选择的包管理器直接安装即可,例如pnpm安装

pnpm tauri add barcode-scanner

3. 手动安装

首先添加依赖

cargo add tauri-plugin-barcode-scanner --target 'cfg(any(target_os = "android", target_os = "ios"))'

然后在移动端的Tauri程序入口点的时候添加插件

// src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    
    
    tauri::Builder::default()
        .setup(|app| {
    
    
        // 就是下面两行
            #[cfg(mobile)]
            app.handle().plugin(tauri_plugin_barcode_scanner::init());
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

接下来安装前端的依赖(必须配合)

pnpm add @tauri-apps/plugin-barcode-scanner

然后运行一下项目就装好插件了

# 安卓的
pnpm tauri android dev

IOS需要特别配置

在IOS上需要使用NSCameraUsageDescription属性列表值,告诉系统你需要使用摄像头。(跟安装开启权限是一样的)

需要在src-tauri/Info.ios.plist添加以下代码

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>NSCameraUsageDescription</key>
    <string>Read QR codes</string>
  </dict>
</plist>

二、配置插件

Barcode Scanner的使用主要分为两部分,一个是开启前端的权限,一个就是调用功能。

1. 开启前端权限

这部分是Tauri2.0的特性,主要是开启了权限以后,你才可以在前端调用功能代码,否则,你的插件是无法在前端使用的.

开启权限也是非常简单,当你安装插件后或者初始化了安卓的项目,就会在src-tauri目录下出现这个文件src-tauri/capabilities/mobile.json,当然,如果不存在则创建即可。

内容如下

// src-tauri/capabilities/mobile.json
{
    
    
  "$schema": "../gen/schemas/mobile-schema.json",
  "identifier": "mobile-capability",
  "windows": ["main"],
  "platforms": ["iOS", "android"],
  "permissions": ["barcode-scanner:allow-scan", "barcode-scanner:allow-cancel"]
}

关于Tauri权限的问题,我已在往期文章内说明,如果你有兴趣可以翻过去看看。

以下权限跟扫码息息相关

  • allow-cancel – 允许取消
  • allow-check-permissions – 允许检查权限
  • allow-open-app-settings – 允许打开应用设置
  • allow-request-permissions – 允许请求权限
  • allow-scan – 允许扫描
  • allow-vibrate – 允许振动

2. 调用功能

import {
    
     scan, Format } from '@tauri-apps/plugin-barcode-scanner';
// 如果设置了 `"withGlobalTauri": true`,
// 需要这样导入 const { scan, Format } = window.__TAURI__.barcodeScanner;

// `windowed: true` 会将扫描的webview设置成透明的
// 代替打开一个新的webview
// 确保你的ui界面可以显示这个透明元素
scan({
    
     windowed: true, formats: [Format.QRCode] });

3.插件权限表

权限标识 功能描述
barcode-scanner:allow-cancel 允许调用cancel命令,在没有任何预先配置的情况下
barcode-scanner:deny-cancel 禁止调用cancel命令,在没有任何预先配置的情况下
barcode-scanner:allow-check-permissions 允许调用check_permissions命令,在没有任何预先配置的情况下
barcode-scanner:deny-check-permissions 禁止调用check_permissions命令,在没有任何预先配置的情况下
barcode-scanner:allow-open-app-settings 允许调用open_app_settings命令,在没有任何预先配置的情况下
barcode-scanner:deny-open-app-settings 禁止调用open_app_settings命令,在没有任何预先配置的情况下
barcode-scanner:allow-request-permissions 允许调用request_permissions命令,在没有任何预先配置的情况下
barcode-scanner:deny-request-permissions 禁止调用request_permissions命令,在没有任何预先配置的情况下
barcode-scanner:allow-scan 允许调用scan命令,在没有任何预先配置的情况下
barcode-scanner:deny-scan 禁止调用scan命令,在没有任何预先配置的情况下
barcode-scanner:allow-vibrate 允许调用vibrate命令,在没有任何预先配置的情况下
barcode-scanner:deny-vibrate 禁止调用vibrate命令,在没有任何预先配置的情况下