Lebensmittel-Scanner mit React Native erstellen
Eine Schritt-für-Schritt-Anleitung zur Erstellung eines Barcode-Scanners in React Native, der Nährwertinformationen von der Open Food Facts API abruft und mit der leistungsstarken Vision Camera-Bibliothek anzeigt.
Auf dieser Seite
Haben Sie sich jemals im Supermarkt gefragt, welche Nährwertinformationen ein Produkt enthält? In einer Zeit des gesundheitsbewussten Konsums ist der sofortige Zugriff auf diese Informationen ein echter Wendepunkt. Dieser Artikel führt Sie durch meine Erfahrung beim Erstellen einer Mobilgeräte-App-Funktion, die genau das ermöglicht: einen Barcode-Scanner, der Nährwertdaten abruft und anzeigt.
Wir werden die leistungsstarke Bibliothek react-native-vision-camera verwenden, ein Hochleistungswerkzeug für alle kamerabezogenen Funktionen in React Native. Als Datenquelle nutzen wir die großartige Open Food Facts API, eine kostenlose, offene und von der Crowd gespeiste Datenbank für Lebensmittelprodukte aus der ganzen Welt.
Dieses Projekt ist mehr als nur eine technische Übung; es geht darum, ein praktisches Werkzeug zu schaffen, das Benutzer befähigt, fundiertere Entscheidungen über ihre Ernährung zu treffen. Am Ende dieses Tutorials werden Sie ein solides Verständnis dafür haben, wie Sie Kamerafunktionen in Ihre React Native-Apps integrieren und mit externen APIs interagieren können, um wertvolle Daten für Ihre Benutzer zugänglich zu machen.
Voraussetzungen:
- Grundlegendes Verständnis von React Native und JavaScript.
- Node.js und npm/yarn installiert.
- Eine Entwicklungsumgebung für React Native eingerichtet (einschließlich Android Studio oder Xcode).
- Ein physisches Gerät zum Testen der Kamerafunktion wird dringend empfohlen.
Das Problem verstehen
Die zentrale Herausforderung ist zweifach: Erstens müssen wir zuverlässig einen Barcode von einem Produkt mit der Kamera des Geräts erfassen. Zweitens müssen wir diese Barcode-Informationen nehmen und die entsprechenden Nährwertdaten aus einer großen Online-Datenbank abrufen.
Technische Herausforderungen:
- Kameraintegration: Der Zugriff auf und die Verwaltung der Gerätekamera kann komplex sein und umfasst Berechtigungen, verschiedene Gerätefunktionen und die Gewährleistung einer reibungslosen Benutzererfahrung.
- Barcode-Erkennung: Der Scan muss schnell und präzise sein, auch bei suboptimalen Lichtverhältnissen oder leicht beschädigten Barcodes.
- API-Interaktion: Wir müssen asynchrone Datenabrufe verarbeiten, potenziell komplexe JSON-Antworten parsen und Lade- sowie Fehlerzustände elegant verwalten.
Glücklicherweise haben moderne Bibliotheken wie react-native-vision-camera die Kameraintegration vereinfacht, und mit ihren integrierten Code-Scan-Funktionen können wir auf mehrere Bibliotheken verzichten.
Voraussetzungen
Bevor wir mit dem Programmieren beginnen, richten wir unser Projekt ein.
-
Erstellen Sie ein neues React Native-Projekt:
bash npx react-native@latest init NutritionScanner cd NutritionScanner -
Installieren Sie
react-native-vision-camera:bash npm install react-native-vision-camera cd ios && pod install -
Berechtigungen konfigurieren: Um die Kamera zu verwenden, müssen wir die erforderlichen Berechtigungen in unseren nativen Projektdateien deklarieren.
-
iOS (
ios/NutritionScanner/Info.plist):xml <key>NSCameraUsageDescription</key> <string>$(PRODUCT_NAME) benötigt Zugriff auf Ihre Kamera.</string> -
Android (
android/app/src/main/AndroidManifest.xml):xml <uses-permission android:name="android.permission.CAMERA" />
-
Mit unserem initialisierten Projekt und den konfigurierten Berechtigungen sind wir bereit, mit dem Aufbau zu beginnen.
Schritt 1: Implementierung des Barcode-Scanners
Unsere erste große Aufgabe ist es, die Kamera zum Laufen zu bringen und aktiv nach Barcodes zu scannen.
Was wir tun
Wir erstellen eine Komponente, die Kamera-Berechtigungen anfordert, den Kamera-Feed anzeigt und einen Hook von react-native-vision-camera verwendet, um Barcodes in Echtzeit zu erkennen.
Implementierung
Erstellen Sie eine neue Datei src/BarcodeScanner.js:
// src/BarcodeScanner.js
import React, { useEffect, useState } from 'react';
import { View, StyleSheet, Text, Linking, Button } from 'react-native';
import {
Camera,
useCameraDevice,
useCodeScanner,
} from 'react-native-vision-camera';
const BarcodeScanner = ({ onBarcodeScanned }) => {
const [hasPermission, setHasPermission] = useState(false);
const device = useCameraDevice('back');
useEffect(() => {
const checkCameraPermission = async () => {
const status = await Camera.getCameraPermissionStatus();
if (status === 'not-determined') {
const newStatus = await Camera.requestCameraPermission();
setHasPermission(newStatus === 'granted');
} else {
setHasPermission(status === 'granted');
}
};
checkCameraPermission();
}, []);
const codeScanner = useCodeScanner({
codeTypes: ['ean-13', 'upc-a', 'qr'], // Geben Sie die Barcode-Typen an, die Sie scannen möchten
onCodeScanned: (codes) => {
if (codes.length > 0) {
onBarcodeScanned(codes[0].value);
}
},
});
if (device == null) {
return <Text>Kein Kamera-Gerät gefunden.</Text>;
}
if (!hasPermission) {
return (
<View style={styles.container}>
<Text>Die Kamera-Berechtigung ist erforderlich, um Barcodes zu scannen.</Text>
<Button title="Berechtigung erteilen" onPress={() => Linking.openSettings()} />
</View>
);
}
return (
<View style={StyleSheet.absoluteFill}>
<Camera
style={StyleSheet.absoluteFill}
device={device}
isActive={true}
codeScanner={codeScanner}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default BarcodeScanner;
Wie es funktioniert
- Wir verwenden den
useEffect-Hook, um beim Laden der Komponente die Kamera-Berechtigungen zu überprüfen und anzufordern. useCameraDevice('back')wählt die rückwärtige Kamera zum Scannen aus.- Der
useCodeScanner-Hook ist das Herzstück unserer Scan-Logik. Wir geben ihm die Barcode-Typen, nach denen wir suchen möchten, und eine Callback-Funktion,onCodeScanned. - Wenn ein Barcode erkannt wird, wird
onCodeScannedausgelöst, und wir übergeben den gescannten Wert an die übergeordnete Komponente.
Häufige Fallstricke
- Berechtigungen verweigert: Wenn der Benutzer die Kamera-Berechtigung verweigert, müssen wir ihm eine Möglichkeit bieten, diese später zu erteilen. Deshalb bieten wir eine Schaltfläche zum Öffnen der App-Einstellungen an.
- Simulator-Einschränkungen: Die Kamera funktioniert auf einem Simulator nicht. Testen Sie immer auf einem physischen Gerät.
Schritt 2: Abrufen von Nährwertdaten
Jetzt, da wir einen Barcode erfassen können, verwenden wir ihn, um Daten von der Open Food Facts API abzurufen.
Was wir tun
Wir erstellen eine Funktion, um die Open Food Facts API mit dem gescannten Barcode aufzurufen. Dann parsen wir die JSON-Antwort, um die Nährwertinformationen zu extrahieren, die wir benötigen.
Implementierung
Zunächst erstellen wir eine Service-Datei für unsere API-Aufrufe, src/api.js:
// src/api.js
const API_URL = 'https://world.openfoodfacts.org/api/v2/product/';
export const fetchNutritionData = async (barcode) => {
try {
const response = await fetch(`${API_URL}${barcode}?fields=product_name,nutriments,image_url`);
if (!response.ok) {
throw new Error('Produkt nicht gefunden');
}
const data = await response.json();
if (data.status === 0 || !data.product) {
throw new Error('Produkt nicht in der Datenbank gefunden.');
}
return data.product;
} catch (error) {
console.error('API-Fehler:', error);
throw error;
}
};
Wie es funktioniert
- Wir definieren die Basis-URL für den Open Food Facts-Produktendpunkt.
- Die Funktion
fetchNutritionDatanimmt einen Barcode, konstruiert die vollständige API-URL und führt eine GET-Anfrage durch. - Wir haben
?fields=...zur URL hinzugefügt. Dies ist eine leistungsstarke Funktion der Open Food Facts API, die es uns ermöglicht, nur die benötigten Daten anzufordern und die Antwortgröße zu reduzieren. - Eine grundlegende Fehlerbehandlung ist enthalten, um Fälle zu behandeln, in denen das Produkt nicht gefunden wird oder ein Netzwerkfehler auftritt.
Häufige Fallstricke
- Unvollständige Daten: Die Open Food Facts-Datenbank wird von der Crowd gespeist, daher könnten einige Produkte unvollständige oder fehlende Nährwertinformationen haben. Ihre Benutzeroberfläche sollte dies elegant behandeln können.
- Rate-Limiting: Seien Sie sich der Rate-Limits der API bewusst, insbesondere wenn Ihre App beliebt wird.
Alles zusammenfügen
Jetzt integrieren wir unseren BarcodeScanner und den API-Service in unsere Hauptdatei App.js.
Vollständiges Beispiel
// App.js
import React, { useState } from 'react';
import {
SafeAreaView,
StyleSheet,
View,
Text,
Button,
ActivityIndicator,
Image,
} from 'react-native';
import BarcodeScanner from './src/BarcodeScanner';
import { fetchNutritionData } from './src/api';
const App = () => {
const [isScanning, setIsScanning] = useState(false);
const [productData, setProductData] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const handleBarcodeScanned = async (barcode) => {
setIsScanning(false);
setIsLoading(true);
setError(null);
setProductData(null);
try {
const data = await fetchNutritionData(barcode);
setProductData(data);
} catch (err) {
setError(err.message);
} finally {
setIsLoading(false);
}
};
const renderProductInfo = () => {
if (!productData) return null;
const { product_name, nutriments, image_url } = productData;
return (
<View style={styles.infoContainer}>
{image_url && <Image source={{ uri: image_url }} style={styles.productImage} />}
<Text style={styles.title}>{product_name}</Text>
<Text>Kalorien pro 100g: {nutriments['energy-kcal_100g'] || 'N/V'}</Text>
<Text>Kohlenhydrate pro 100g: {nutriments.carbohydrates_100g || 'N/V'}</Text>
<Text>Eiweiß pro 100g: {nutriments.proteins_100g || 'N/V'}</Text>
<Text>Fett pro 100g: {nutriments.fat_100g || 'N/V'}</Text>
</View>
);
};
if (isScanning) {
return <BarcodeScanner onBarcodeScanned={handleBarcodeScanned} />;
}
return (
<SafeAreaView style={styles.container}>
<Text style={styles.header}>Nährwert-Scanner</Text>
<View style={styles.content}>
{isLoading && <ActivityIndicator size="large" />}
{error && <Text style={styles.errorText}>Fehler: {error}</Text>}
{productData && renderProductInfo()}
</View>
<Button
title={productData ? 'Weiteres Produkt scannen' : 'Scan starten'}
onPress={() => {
setProductData(null);
setError(null);
setIsScanning(true);
}}
/>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'space-between', padding: 16 },
header: { fontSize: 24, fontWeight: 'bold', textAlign: 'center' },
content: { flex: 1, justifyContent: 'center', alignItems: 'center' },
infoContainer: { alignItems: 'center' },
productImage: { width: 150, height: 150, resizeMode: 'contain', marginBottom: 12 },
title: { fontSize: 20, fontWeight: 'bold', marginBottom: 8 },
errorText: { color: 'red', textAlign: 'center' },
});
export default App;
Wie es funktioniert
- Wir verwalten den Zustand der App mit mehreren
useState-Hooks:isScanning,productData,isLoadingunderror. - Wenn die Schaltfläche „Scan starten" gedrückt wird, wird
isScanningauftruegesetzt, was unsereBarcodeScanner-Komponente rendert. - Sobald ein Barcode gescannt wird, wird
handleBarcodeScannedaufgerufen. Es setztisScanningauffalse, zeigt einen Ladeindikator an und ruft unseren API-Service auf. - Die Ergebnisse werden dann in der Funktion
renderProductInfoangezeigt, die die Produktdetails bedingt rendert.
Ein Hinweis zur Benutzererfahrung
Ein häufiges Problem bei Barcode-Scannern ist, dass sie zu häufig scannen können, was zu mehreren API-Aufrufen für ein einzelnes Produkt führt. In unserer Implementierung verhindern wir dieses Problem effektiv, indem wir isScanning sofort nach dem ersten erfolgreichen Scan auf false setzen, und bieten so eine kontrolliertere Benutzererfahrung.
Fazit
Wir haben erfolgreich eine funktionale und praktische Funktion in einer React Native-Anwendung entwickelt. Wir haben die Kameraintegration mit react-native-vision-camera gemeistert, Berechtigungen verarbeitet und Daten von der Open Food Facts API abgerufen und angezeigt.
Dieses Projekt dient als fantastische Grundlage. Sie könnten es erweitern durch:
- Anzeige detaillierterer Nährwertinformationen (wie Vitamine, Mineralien und Zusatzstoffe).
- Hinzufügen eines Verlaufs der gescannten Produkte.
- Implementierung von Offline-Funktionen zum Zwischenspeichern zuvor gescannter Produkte.
- Beitrag zur Open Food Facts-Community, indem Sie Benutzern ermöglichen, Fotos von Produkten einzureichen, die noch nicht in der Datenbank sind.
Ressourcen
- React Native Vision Camera: https://react-native-vision-camera.com/
- Open Food Facts API-Dokumentation: https://openfoodfacts.github.io/openfoodfacts-server/
Kurzübersicht
| Aspekt | Wichtige Informationen |
|---|---|
| Thema | Entwicklung |
| Relevanz | Patientenaufklärung und -sensibilisierung |
| Maßnahme | Besprechen Sie dies mit Ihrem Arzt |
| Häufigkeit | Nach Empfehlung Ihres Behandlungsteams |
| Evidenz | Basierend auf aktuellen klinischen Richtlinien |
Häufig gestellte Fragen
F: Woher weiß ich, ob dies auf mich zutrifft? A: Besprechen Sie Ihre persönliche und familiäre Krankengeschichte mit Ihrem Arzt, um Ihre individuellen Risikofaktoren einzuschätzen und geeignete nächste Schritte zu bestimmen.
F: Was sollte ich meinen Arzt fragen? A: Gute Fragen sind unter anderem: „Was bedeuten meine Ergebnisse?", „Was sind meine Optionen?", „Welche Änderungen des Lebensstils würden helfen?" und „Wann sollte ich nachuntersuchen lassen?"
F: Gibt es Änderungen des Lebensstils, die helfen können? A: Die meisten Erkrankungen profitieren von grundlegenden Maßnahmen: ausgewogene Ernährung, regelmäßige körperliche Aktivität (über 150 Minuten/Woche), qualitativer Schlaf (7-9 Stunden), Stressmanagement und Vermeidung von Tabak.
Medizinischer Haftungsausschluss
Dieser Artikel dient ausschließlich zu Bildungszwecken und stellt keine medizinische Beratung dar. Konsultieren Sie immer einen qualifizierten Gesundheitsdienstleister, bevor Sie Entscheidungen über Ihre Gesundheit, Behandlung oder Pflege treffen. Individuelle Umstände variieren, und das, was für eine Person angemessen ist, ist möglicherweise nicht für eine andere Person angemessen.
Wenn Sie einen medizinischen Notfall erleben, rufen Sie sofort 911 (oder Ihre lokale Notrufnummer) an.