Skip to content

Commit ef6dd8e

Browse files
committed
chore: enhanced scan results and improved example app
1 parent 81fb261 commit ef6dd8e

18 files changed

+255
-177
lines changed

.gitignore

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,19 @@ example/android/
9595
example/dist/
9696
example/build/
9797
example/.bundle/
98-
example/.watchmanconfig
99-
example/Gemfile
100-
example/jest.config.js
101-
example/metro.config.js
102-
example/react-native.config.js
98+
99+
example/.yarn/*
100+
!example/.yarn/patches
101+
!example/.yarn/plugins
102+
!example/.yarn/releases
103+
!example/.yarn/sdks
104+
!example/.yarn/versions
105+
106+
example/.yarn/cache
107+
example/.yarn/unplugged
108+
example/.yarn/build-state.yml
109+
example/.yarn/install-state.gz
110+
example/.pnp.*
103111

104112
# Expo build artifacts
105113
example/.expo/

.npmignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ turbo.json
2121
# Build and development
2222
example/
2323
modules/
24+
scripts/
25+
test-install/
2426
android/build/
2527
ios/build/
2628
.turbo/

CHANGELOG.md

Lines changed: 14 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,62 +5,28 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [1.0.0] - 2025-08-28
8+
## [1.1.0] - 2025-09-05
99

1010
### Added
1111

12-
- Initial release of React Native Image Code Scanner
13-
- Native implementation for iOS using Vision Framework
14-
- Native implementation for Android using ML Kit
15-
- Support for 13 barcode formats (QR Code, Code 128, Code 39, etc.)
16-
- **Automatic image preprocessing** for optimal recognition:
17-
- Contrast enhancement
18-
- Grayscale conversion
19-
- Multiple rotation attempts (0°, 90°, 180°, 270°)
20-
- **Ultra-simple API** - just pass image path and formats, preprocessing is automatic by default
21-
- Full support for React Native's New Architecture (Turbo Modules)
22-
- TypeScript support with complete type definitions
23-
- Comprehensive documentation and examples
24-
- **Expo compatibility** with prebuild support
25-
- **Expo example app** with modern UI and full feature demonstration
26-
- Cross-platform example app (iOS, Android, Web)
12+
- **Enhanced scan results** - Now returns both content and format information
13+
- New `ScanResult` interface with `content` and `format` properties
14+
- Format detection for all supported barcode types (QR_CODE, CODE_128, EAN_13, etc.)
15+
- Updated example app to display both content and barcode format
16+
- TypeScript support for the new result format
2717

2818
### Changed
2919

30-
- **Major Version Release**: Stable 1.0.0 release with production-ready features
31-
- Enhanced CI pipeline and build reliability
32-
- Improved cross-platform compatibility
20+
- **Breaking Change**: `ImageCodeScanner.scan()` now returns `ScanResult[]` instead of `string[]`
21+
- Updated API to provide more detailed scan results
22+
- Enhanced example app UI to show barcode format alongside content
23+
- Improved result display with format badges
3324

3425
### Fixed
3526

36-
- Resolved CI and Android build issues with Yarn lockfile and JVM compatibility
37-
- Improved build pipeline stability
38-
- Enhanced cross-platform build reliability
39-
- CI pipeline improvements and stability enhancements
40-
- Android build compatibility improvements
41-
- Yarn lockfile consistency fixes
27+
- Better type safety with comprehensive result interface
28+
- Enhanced debugging capabilities with format information
4229

43-
### Features
30+
[1.1.0]: https://github.com/nguyenthanhan/react-native-image-code-scanner/releases/tag/v1.1.0
4431

45-
- Lightweight and performant native implementation
46-
- **Automatic preprocessing** enabled by default for best results
47-
- Smart retry logic with multiple image enhancement techniques
48-
- No additional setup required for Android
49-
- Minimal iOS setup with just pod install
50-
- **Expo integration** with proper prebuild workflow
51-
- **Modern example app** using Expo Image Picker and StatusBar
52-
- **Simplified API** - just pass image path and formats
53-
- **Performance metrics** and timing measurements
54-
55-
### Example App Features
56-
57-
- Modern Expo-based example application
58-
- Barcode format selection UI with real-time toggles
59-
- Automatic preprocessing info with optional disable switch
60-
- Improved error handling and user feedback
61-
- Comprehensive setup documentation
62-
- Support for both Expo Go (UI testing) and prebuild (full functionality)
63-
- Cross-platform compatibility (iOS, Android, Web)
64-
- Performance timing and metrics display
65-
66-
[1.0.0]: https://github.com/nguyenthanhan/react-native-image-code-scanner/releases/tag/v1.0.0
32+
_This changelog will be updated with each new release to document all changes, improvements, and new features._

README.md

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,6 @@ A lightweight, high-performance React Native library for scanning QR codes and b
6060
| **0.79.x** |**1.0.x** | **New Architecture (default)** | **Latest - Full Support** |
6161
| 0.80.x+ | 🔜 1.0.x | New Architecture | Ready when released |
6262

63-
**Latest Version**: v1.0.0 - Major stable release with enhanced CI pipeline and build reliability improvements
64-
6563
### Requirements
6664

6765
- **React Native**: >=0.70.0
@@ -129,15 +127,19 @@ npx expo run:android
129127
### Basic Usage
130128

131129
```typescript
132-
import ImageCodeScanner from 'react-native-image-code-scanner';
130+
import ImageCodeScanner, { ScanResult } from 'react-native-image-code-scanner';
133131

134132
// Scan QR code from image
135133
const scanQRCode = async (imagePath: string) => {
136134
try {
137-
const results = await ImageCodeScanner.scan({ path: imagePath });
135+
const results: ScanResult[] = await ImageCodeScanner.scan({
136+
path: imagePath,
137+
});
138138

139139
if (results.length > 0) {
140-
console.log('QR Code found:', results[0]);
140+
const firstResult = results[0];
141+
console.log('QR Code found:', firstResult.content);
142+
console.log('Format:', firstResult.format); // "QR_CODE"
141143
} else {
142144
console.log('No QR code found in image');
143145
}
@@ -152,11 +154,12 @@ const scanQRCode = async (imagePath: string) => {
152154
```typescript
153155
import ImageCodeScanner, {
154156
BarcodeFormat,
157+
ScanResult,
155158
} from 'react-native-image-code-scanner';
156159

157160
const scanMultipleFormats = async (imagePath: string) => {
158161
try {
159-
const results = await ImageCodeScanner.scan({
162+
const results: ScanResult[] = await ImageCodeScanner.scan({
160163
path: imagePath,
161164
formats: [
162165
BarcodeFormat.QR_CODE,
@@ -166,7 +169,10 @@ const scanMultipleFormats = async (imagePath: string) => {
166169
// Automatic preprocessing is enabled by default for optimal recognition
167170
});
168171

169-
console.log('Found barcodes:', results);
172+
results.forEach((result, index) => {
173+
console.log(`Barcode ${index + 1}:`, result.content);
174+
console.log(`Format:`, result.format);
175+
});
170176
} catch (error) {
171177
console.error('Scan error:', error);
172178
}
@@ -187,7 +193,7 @@ As soon as a barcode is detected with any technique, the result is returned imme
187193
### With Image Picker
188194

189195
```typescript
190-
import ImageCodeScanner from 'react-native-image-code-scanner';
196+
import ImageCodeScanner, { ScanResult } from 'react-native-image-code-scanner';
191197
import { launchImageLibrary } from 'react-native-image-picker';
192198

193199
const scanFromGallery = async () => {
@@ -199,14 +205,17 @@ const scanFromGallery = async () => {
199205
if (result.assets && result.assets[0]) {
200206
const imagePath = result.assets[0].uri;
201207

202-
const scanResults = await ImageCodeScanner.scan({
208+
const scanResults: ScanResult[] = await ImageCodeScanner.scan({
203209
path: imagePath,
204210
formats: [ImageCodeScanner.BarcodeFormat.QR_CODE],
205211
// Automatic preprocessing is enabled by default
206212
});
207213

208214
if (scanResults.length > 0) {
209-
console.log('Barcode data:', scanResults);
215+
scanResults.forEach((result) => {
216+
console.log('Content:', result.content);
217+
console.log('Format:', result.format);
218+
});
210219
}
211220
}
212221
};
@@ -215,7 +224,7 @@ const scanFromGallery = async () => {
215224
### With Expo Image Picker
216225

217226
```typescript
218-
import ImageCodeScanner from 'react-native-image-code-scanner';
227+
import ImageCodeScanner, { ScanResult } from 'react-native-image-code-scanner';
219228
import * as ImagePicker from 'expo-image-picker';
220229

221230
const scanFromGallery = async () => {
@@ -228,14 +237,17 @@ const scanFromGallery = async () => {
228237
if (!result.canceled && result.assets && result.assets[0]) {
229238
const imagePath = result.assets[0].uri;
230239

231-
const scanResults = await ImageCodeScanner.scan({
240+
const scanResults: ScanResult[] = await ImageCodeScanner.scan({
232241
path: imagePath,
233242
formats: [ImageCodeScanner.BarcodeFormat.QR_CODE],
234243
// Automatic preprocessing is enabled by default
235244
});
236245

237246
if (scanResults.length > 0) {
238-
console.log('Barcode data:', scanResults);
247+
scanResults.forEach((result) => {
248+
console.log('Content:', result.content);
249+
console.log('Format:', result.format);
250+
});
239251
}
240252
}
241253
};
@@ -246,18 +258,23 @@ const scanFromGallery = async () => {
246258
```typescript
247259
import ImageCodeScanner, {
248260
BarcodeFormat,
261+
ScanResult,
249262
} from 'react-native-image-code-scanner';
250263

251264
// Scan with automatic preprocessing and multiple formats
252-
const scanEverything = async (imagePath: string) => {
265+
const scanEverything = async (imagePath: string): Promise<ScanResult[]> => {
253266
try {
254-
const results = await ImageCodeScanner.scan({
267+
const results: ScanResult[] = await ImageCodeScanner.scan({
255268
path: imagePath,
256269
formats: Object.values(BarcodeFormat), // All supported formats
257270
// Automatic preprocessing is enabled by default
258271
});
259272

260-
console.log(`Found ${results.length} barcodes:`, results);
273+
console.log(`Found ${results.length} barcodes:`);
274+
results.forEach((result, index) => {
275+
console.log(`${index + 1}. ${result.format}: ${result.content}`);
276+
});
277+
261278
return results;
262279
} catch (error) {
263280
console.error('Scan failed:', error);
@@ -289,7 +306,16 @@ interface ScanOptions {
289306

290307
#### Returns
291308

292-
`Promise<string[]>` - Array of decoded barcode values
309+
`Promise<ScanResult[]>` - Array of scan results with content and format information
310+
311+
#### ScanResult
312+
313+
```typescript
314+
interface ScanResult {
315+
content: string; // The decoded barcode content
316+
format: string; // The detected barcode format (e.g., "QR_CODE", "EAN_13")
317+
}
318+
```
293319

294320
### `ImageCodeScanner.BarcodeFormat`
295321

@@ -396,8 +422,8 @@ The example app demonstrates:
396422

397423
**Platform Support:**
398424

399-
- 📱 **iOS**: Full camera and gallery access
400-
- 🤖 **Android**: Full camera and gallery access
425+
- 📱 **iOS**: Gallery access
426+
- 🤖 **Android**: Gallery access
401427

402428
## 🤝 Contributing
403429

@@ -413,18 +439,10 @@ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) f
413439

414440
## 📄 License
415441

416-
MIT © [Heimer Nguyen](https://github.com/nguyenthanhan)
442+
MIT
417443

418444
## 🆘 Support
419445

420446
- 🐛 [Report Issues](https://github.com/nguyenthanhan/react-native-image-code-scanner/issues)
421447
- 💬 [Discussions](https://github.com/nguyenthanhan/react-native-image-code-scanner/discussions)
422448
- ⭐ Star us on [GitHub](https://github.com/nguyenthanhan/react-native-image-code-scanner)
423-
424-
## 📝 Changelog
425-
426-
See [CHANGELOG.md](CHANGELOG.md) for version history.
427-
428-
---
429-
430-
Made with ❤️ by [Heimer Nguyen](https://github.com/nguyenthanhan)

RNImageCodeScanner.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Pod::Spec.new do |s|
1313
s.platforms = { :ios => "13.4" }
1414
s.source = { :git => "https://github.com/nguyenthanhan/react-native-image-code-scanner.git", :tag => "#{s.version}" }
1515

16-
s.source_files = "ios/**/*.{h,m,mm,swift}"
16+
s.source_files = "ios/**/*.{h,m,mm,cpp,swift}"
1717
s.swift_version = "5.0"
1818

1919
# Required frameworks for Vision and image processing

android/src/main/java/com/imagecodescanner/ImageCodeScannerModule.kt

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,30 @@ class ImageCodeScannerModule(reactContext: ReactApplicationContext) :
225225
val codes = barcodes
226226
.mapNotNull { barcode ->
227227
val value = barcode.displayValue ?: barcode.rawValue
228-
value
228+
if (value != null && value.isNotEmpty()) {
229+
val format = when (barcode.format) {
230+
Barcode.FORMAT_QR_CODE -> "QR_CODE"
231+
Barcode.FORMAT_CODE_128 -> "CODE_128"
232+
Barcode.FORMAT_CODE_39 -> "CODE_39"
233+
Barcode.FORMAT_CODE_93 -> "CODE_93"
234+
Barcode.FORMAT_EAN_13 -> "EAN_13"
235+
Barcode.FORMAT_EAN_8 -> "EAN_8"
236+
Barcode.FORMAT_UPC_A -> "UPC_A"
237+
Barcode.FORMAT_UPC_E -> "UPC_E"
238+
Barcode.FORMAT_PDF417 -> "PDF_417"
239+
Barcode.FORMAT_DATA_MATRIX -> "DATA_MATRIX"
240+
Barcode.FORMAT_AZTEC -> "AZTEC"
241+
Barcode.FORMAT_ITF -> "ITF"
242+
Barcode.FORMAT_CODABAR -> "CODABAR"
243+
else -> "UNKNOWN"
244+
}
245+
val resultMap = Arguments.createMap()
246+
resultMap.putString("content", value)
247+
resultMap.putString("format", format)
248+
resultMap
249+
} else null
229250
}
230-
.filter { it.isNotEmpty() }
251+
.filter { it != null }
231252

232253
val arr = Arguments.fromList(codes)
233254
promise.resolve(arr)

0 commit comments

Comments
 (0)