<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Leandro Campos</title>
    <description>The latest articles on DEV Community by Leandro Campos (@leandrocampos).</description>
    <link>https://dev.to/leandrocampos</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F803477%2F4b13aa6a-f1a9-404b-95a4-bdc82f7e78ec.JPG</url>
      <title>DEV Community: Leandro Campos</title>
      <link>https://dev.to/leandrocampos</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/leandrocampos"/>
    <language>en</language>
    <item>
      <title>Modernizing Bluetooth Printing in React Native 🚀</title>
      <dc:creator>Leandro Campos</dc:creator>
      <pubDate>Sun, 03 May 2026 14:25:39 +0000</pubDate>
      <link>https://dev.to/leandrocampos/modernizing-bluetooth-printing-in-react-native-mlj</link>
      <guid>https://dev.to/leandrocampos/modernizing-bluetooth-printing-in-react-native-mlj</guid>
      <description>&lt;h1&gt;
  
  
  Modernizing Bluetooth Printing in React Native 🚀
&lt;/h1&gt;

&lt;p&gt;Hello everyone,&lt;br&gt;
Anyone who has needed to implement ESC/POS printing in React Native projects knows that the&lt;br&gt;
&lt;code&gt;react-native-bluetooth-escpos-printer&lt;/code&gt; library was a cornerstone for a long time. However, as it has become&lt;br&gt;
outdated, it's presenting compatibility issues with the latest Android and iOS versions.&lt;/p&gt;

&lt;p&gt;To solve this, I'm working on&lt;br&gt;
&lt;strong&gt;&lt;a href="https://github.com/jleandrocampos/react-native-bluetooth-escpos-next" rel="noopener noreferrer"&gt;react-native-bluetooth-escpos-next&lt;/a&gt;&lt;/strong&gt;.&lt;br&gt;
It's a complete refactor from the original project by &lt;em&gt;januslo&lt;/em&gt;, but rebuilt from the ground up with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Kotlin&lt;/strong&gt; on Android for maximum compatibility with new devices.&lt;/li&gt;
&lt;li&gt;✅ Native &lt;strong&gt;TypeScript&lt;/strong&gt; for a safer and more predictable API.&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Modular architecture&lt;/strong&gt; (TS Encoder + Native Transport).&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Testing environment with a Python Mock Server:&lt;/strong&gt; Develop and preview your print layouts directly in the
browser, no physical printer needed!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Currently, the library is undergoing heavy testing on &lt;strong&gt;Android&lt;/strong&gt;. The next step will be validating and&lt;br&gt;
implementing the transport layer for &lt;strong&gt;iOS&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contribute!
&lt;/h2&gt;

&lt;p&gt;The project is open-source, and anyone who wants to test, report bugs, or contribute with code is more than&lt;br&gt;
welcome!&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Check it out on GitHub:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/jleandrocampos/react-native-bluetooth-escpos-next" rel="noopener noreferrer"&gt;jleandrocampos/react-native-bluetooth-escpos-next&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Refactored from the original library:&lt;br&gt;
&lt;a href="https://github.com/januslo/react-native-bluetooth-escpos-printer" rel="noopener noreferrer"&gt;react-native-bluetooth-escpos-printer&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xv0carsj585lsmjg7nc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xv0carsj585lsmjg7nc.png" alt=" " width="800" height="1778"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmt3wjkbbxtmoz7zihjp5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmt3wjkbbxtmoz7zihjp5.png" alt=" " width="800" height="1778"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzgn3drffc7blnb0gb6td.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzgn3drffc7blnb0gb6td.png" alt=" " width="800" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>android</category>
      <category>opensource</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Como Utilizar o Leitor NFC ACR122U/ACR122 no Tauri com Rust</title>
      <dc:creator>Leandro Campos</dc:creator>
      <pubDate>Fri, 28 Mar 2025 17:03:34 +0000</pubDate>
      <link>https://dev.to/leandrocampos/como-utilizar-o-leitor-nfc-acr122uacr122-no-tauri-com-rust-4e0c</link>
      <guid>https://dev.to/leandrocampos/como-utilizar-o-leitor-nfc-acr122uacr122-no-tauri-com-rust-4e0c</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Neste post, apresento uma solução para integrar o leitor NFC ACR122U em uma aplicação Tauri, utilizando Rust no backend para comunicação com o dispositivo.&lt;/p&gt;

&lt;p&gt;O objetivo é demonstrar como obter o UID de um cartão NFC e utilizar essa informação no React (ou qualquer framework suportado pelo Tauri).&lt;/p&gt;

&lt;p&gt;Ambiente de desenvolvimento: [windows].&lt;/p&gt;

&lt;h2&gt;
  
  
  Requisitos
&lt;/h2&gt;

&lt;p&gt;Teste realizado com as seguintes condições: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leitor NFC ACR122U&lt;/li&gt;
&lt;li&gt;Rust e Cargo&lt;/li&gt;
&lt;li&gt;Tauri CLI&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configurando o Backend (Rust)
&lt;/h2&gt;

&lt;p&gt;Vamos criar um comando no Tauri para interagir com o leitor NFC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dependências
&lt;/h2&gt;

&lt;p&gt;Adicione a dependência pcsc ao seu &lt;code&gt;Cargo.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[dependencies]
pcsc = "2.9.0"
tauri = { version = "2.0", features = [] }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implementação em Rust
&lt;/h2&gt;

&lt;p&gt;A seguir, o código que configura a leitura do UID do cartão NFC no main.rs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use pcsc::*;

#[tauri::command]
fn read_nfc() -&amp;gt; Result&amp;lt;String, String&amp;gt; {
    // Sets the context
    let ctx = match Context::establish(Scope::User) {
        Ok(ctx) =&amp;gt; ctx,
        Err(err) =&amp;gt; return Err(format!("Error establishing context: {:?}", err)),
    };

    // Buffer for listing readers
    let mut buffer = [0u8; 1024];
    let readers = match ctx.list_readers(&amp;amp;mut buffer) {
        Ok(readers) =&amp;gt; readers,
        Err(err) =&amp;gt; return Err(format!("Error listing readers: {:?}", err)),
    };

    // Converts readers into a collection for verification
    let reader_iter = readers.into_iter();
    let reader_vec: Vec&amp;lt;_&amp;gt; = reader_iter.collect();

    // Checks for connected readers
    if reader_vec.is_empty() {
        return Err("No reader connected".to_string());
    }

    // Search for ACR122
    let reader_name = match reader_vec
        .iter()
        .find(|&amp;amp;&amp;amp;r| r.to_str().map(|s| s.contains("ACR122")).unwrap_or(false))
    {
        Some(&amp;amp;reader) =&amp;gt; reader,
        None =&amp;gt; {
            // List available readers on error
            let available_readers: String = reader_vec
                .iter()
                .map(|r| r.to_str().unwrap_or("Invalid name").to_string())
                .collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()
                .join(", ");
            return Err(format!(
                "ACR122 reader not found. Available readers: {}",
                available_readers
            ));
        }
    };

    // Connects to the reader
    let card = match ctx.connect(reader_name, ShareMode::Shared, Protocols::ANY) {
        Ok(card) =&amp;gt; card,
        Err(err) =&amp;gt; return Err(format!("Error connecting to reader: {:?}", err)),
    };

    // Send APDU command to read UID
    let apdu = [0xFF, 0xCA, 0x00, 0x00, 0x00];
    let mut buffer = [0u8; 256];
    let response = match card.transmit(&amp;amp;apdu, &amp;amp;mut buffer) {
        Ok(response) =&amp;gt; response,
        Err(err) =&amp;gt; return Err(format!("Error reading tag: {:?}", err)),
    };

    // Format UUID as hexadecimal string
    let uid = response[..response.len() - 2]
        .iter()
        .map(|b| format!("{:02X}", b))
        .collect::&amp;lt;String&amp;gt;();

    Ok(uid)
}

fn main() {
    tauri::Builder::default()
        .plugin(tauri_plugin_opener::init())
        .invoke_handler(tauri::generate_handler![read_nfc])
        .run(tauri::generate_context!())
        .expect("Erro ao executar aplicação Tauri");
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  No seu Frontend (React/TypeScript)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Implementação do App.tsx
&lt;/h3&gt;

&lt;p&gt;Crie um componente React para chamar a função do backend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { invoke } from "@tauri-apps/api/core";
import "./App.css";

function App() {

  async function readNFC() {
    try {
      const uid = await invoke('read_nfc');
      console.log('Card UID =&amp;gt;', uid);
    } catch (error) {
      console.error('Error reading NFC:', error);
    }
  }

  return (
    &amp;lt;main className="container"&amp;gt;

      &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;Read NFC!&amp;lt;/h1&amp;gt;

        &amp;lt;button id="read-nfc-btn" onClick={readNFC}&amp;gt;read NFC&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;

    &amp;lt;/main&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Executando a Aplicação
&lt;/h2&gt;

&lt;p&gt;Inicie seu ambiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn tauri dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, ao pressionar o botão "Ler NFC", o UID do cartão será capturado e exibido no console.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cartão Adicionado
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flm71wwpdhmsf0r8utogz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flm71wwpdhmsf0r8utogz.jpg" alt=" " width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Com sucesso
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faa64chv5rs4focuu7ihr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faa64chv5rs4focuu7ihr.png" alt=" " width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Caso cartão não conectado ao leitor
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdnkhb9edjlpnvzak8y3b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdnkhb9edjlpnvzak8y3b.png" alt=" " width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Caso leitor não conectado
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fprbjr35mgz3podqzbxow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fprbjr35mgz3podqzbxow.png" alt=" " width="800" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Com essa solução, conseguimos integrar um leitor NFC ACR122U em um aplicativo Tauri com Rust no backend. Essa abordagem permite que criem aplicações desktop sem executáveis externos que use outras formas dependências de comunicação entre o sistemas e o leitor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Detalhe
&lt;/h3&gt;

&lt;p&gt;Em meus testes meu leitor ACR122U foi reconhecido no meu Windows como ACR122 com os drivers devidos instalados por conta disso o código foi preparado para listar os leitores disponíveis, caso ainda sim não funcione como o esperado tente verificar qual nome o Windows atribuiu ao seu leitor.  &lt;/p&gt;

&lt;p&gt;Se tiver alguma dúvida ou sugestão, deixe seu comentário! ✌️&lt;/p&gt;

&lt;p&gt;Link repositório: &lt;a href="https://github.com/jleandrocampos/tauriReaderNFC" rel="noopener noreferrer"&gt;https://github.com/jleandrocampos/tauriReaderNFC&lt;/a&gt;&lt;/p&gt;

</description>
      <category>development</category>
      <category>tauri</category>
      <category>react</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
