0
# QR & Barcode Scanning
1
2
Camera-based scanning capabilities for QR codes, barcodes, and other machine-readable codes with customizable scanning modes and output formats.
3
4
## Capabilities
5
6
### QR Code Reader
7
8
Open QR code scanner with camera for scanning QR codes and receiving decoded data.
9
10
```typescript { .api }
11
/**
12
* Open QR code scanner with camera
13
* @returns Scanned QR code data and format
14
*/
15
function send(method: 'VKWebAppOpenCodeReader'): Promise<CodeReaderOutput>;
16
17
/**
18
* Alternative QR scanner method
19
* @returns Scanned QR code data
20
*/
21
function send(method: 'VKWebAppOpenQR'): Promise<{
22
qr_data: string;
23
}>;
24
25
interface CodeReaderOutput {
26
/** Scanned code data content */
27
code_data: string;
28
/** Code format type */
29
code_type?: string;
30
}
31
```
32
33
**Usage Examples:**
34
35
```typescript
36
// Basic QR code scanning
37
try {
38
const qrResult = await bridge.send('VKWebAppOpenCodeReader');
39
console.log('QR Code data:', qrResult.code_data);
40
console.log('Code type:', qrResult.code_type);
41
42
// Handle different QR code types
43
if (qrResult.code_data.startsWith('http')) {
44
// Handle URL QR codes
45
window.open(qrResult.code_data, '_blank');
46
} else if (qrResult.code_data.includes('@')) {
47
// Handle email QR codes
48
window.location.href = `mailto:${qrResult.code_data}`;
49
} else {
50
// Handle text QR codes
51
console.log('Text content:', qrResult.code_data);
52
}
53
} catch (error) {
54
console.error('QR scanning failed:', error);
55
}
56
57
// Alternative QR scanning method
58
try {
59
const qrData = await bridge.send('VKWebAppOpenQR');
60
console.log('QR data:', qrData.qr_data);
61
} catch (error) {
62
console.error('QR scanning cancelled or failed:', error);
63
}
64
65
// Check scanner availability before use
66
const canScanQR = await bridge.supportsAsync('VKWebAppOpenCodeReader');
67
if (canScanQR) {
68
const result = await bridge.send('VKWebAppOpenCodeReader');
69
handleQRResult(result);
70
} else {
71
// Fallback: manual input or web-based scanner
72
console.log('Camera scanning not available');
73
}
74
```
75
76
### QR Code Processing
77
78
Process and validate scanned QR code data for different content types.
79
80
```typescript
81
// QR code content type detection
82
function detectQRType(qrData: string): 'url' | 'email' | 'phone' | 'wifi' | 'text' {
83
if (qrData.startsWith('http://') || qrData.startsWith('https://')) {
84
return 'url';
85
} else if (qrData.includes('@') && qrData.includes('.')) {
86
return 'email';
87
} else if (qrData.startsWith('tel:') || /^\+?[\d\s-()]+$/.test(qrData)) {
88
return 'phone';
89
} else if (qrData.startsWith('WIFI:')) {
90
return 'wifi';
91
} else {
92
return 'text';
93
}
94
}
95
96
// Handle different QR code types
97
async function handleQRResult(result: CodeReaderOutput) {
98
const type = detectQRType(result.code_data);
99
100
switch (type) {
101
case 'url':
102
// Open URL
103
if (confirm(`Open ${result.code_data}?`)) {
104
window.open(result.code_data, '_blank');
105
}
106
break;
107
108
case 'email':
109
// Open email client
110
window.location.href = `mailto:${result.code_data}`;
111
break;
112
113
case 'phone':
114
// Open phone dialer
115
const phoneNumber = result.code_data.replace('tel:', '');
116
window.location.href = `tel:${phoneNumber}`;
117
break;
118
119
case 'wifi':
120
// Parse WiFi configuration
121
const wifiMatch = result.code_data.match(/WIFI:T:([^;]*);S:([^;]*);P:([^;]*);H:([^;]*);/);
122
if (wifiMatch) {
123
const [, type, ssid, password, hidden] = wifiMatch;
124
console.log('WiFi Network:', { type, ssid, password, hidden });
125
// Display WiFi connection info to user
126
}
127
break;
128
129
case 'text':
130
// Handle plain text
131
console.log('Text content:', result.code_data);
132
// Copy to clipboard or display to user
133
await bridge.send('VKWebAppCopyText', { text: result.code_data });
134
break;
135
}
136
}
137
```
138
139
### Scanner Integration Patterns
140
141
Common patterns for integrating QR scanning into app workflows.
142
143
```typescript
144
// Scanner button component
145
class QRScannerButton {
146
private async scanQR(): Promise<string | null> {
147
try {
148
// Check availability first
149
if (!await bridge.supportsAsync('VKWebAppOpenCodeReader')) {
150
throw new Error('QR scanner not available');
151
}
152
153
const result = await bridge.send('VKWebAppOpenCodeReader');
154
return result.code_data;
155
} catch (error) {
156
if (error.error_type === 'client_error' && error.error_data.error_code === 4) {
157
// User cancelled scanning
158
console.log('QR scanning cancelled by user');
159
return null;
160
} else {
161
// Other errors
162
console.error('QR scanning error:', error);
163
throw error;
164
}
165
}
166
}
167
168
async handleScanClick() {
169
try {
170
const qrData = await this.scanQR();
171
if (qrData) {
172
this.onQRScanned(qrData);
173
}
174
} catch (error) {
175
this.onScanError(error);
176
}
177
}
178
179
private onQRScanned(data: string) {
180
// Handle successful scan
181
console.log('QR Code scanned:', data);
182
}
183
184
private onScanError(error: any) {
185
// Handle scan error
186
console.error('Scan failed:', error);
187
}
188
}
189
190
// Continuous scanning workflow
191
class ContinuousQRScanner {
192
private isScanning = false;
193
194
async startContinuousScanning() {
195
this.isScanning = true;
196
197
while (this.isScanning) {
198
try {
199
const result = await bridge.send('VKWebAppOpenCodeReader');
200
201
// Process result
202
if (this.isValidQR(result.code_data)) {
203
this.processQR(result.code_data);
204
break; // Stop after successful scan
205
} else {
206
// Invalid QR, continue scanning
207
console.log('Invalid QR code, scanning again...');
208
}
209
} catch (error) {
210
if (error.error_data?.error_code === 4) {
211
// User cancelled
212
this.isScanning = false;
213
break;
214
} else {
215
// Other error, retry after delay
216
await new Promise(resolve => setTimeout(resolve, 1000));
217
}
218
}
219
}
220
}
221
222
stopScanning() {
223
this.isScanning = false;
224
}
225
226
private isValidQR(data: string): boolean {
227
// Implement validation logic
228
return data.length > 0;
229
}
230
231
private processQR(data: string) {
232
// Process valid QR code
233
console.log('Valid QR processed:', data);
234
}
235
}
236
```
237
238
## Platform Availability
239
240
QR scanning is available on the following platforms:
241
242
- **iOS WebView**: Full camera access with VKWebAppOpenCodeReader
243
- **Android WebView**: Full camera access with VKWebAppOpenCodeReader
244
- **Web/Desktop**: Not available (camera access restricted)
245
246
Always check method support before attempting to use camera functionality:
247
248
```typescript
249
const canScan = await bridge.supportsAsync('VKWebAppOpenCodeReader');
250
if (!canScan) {
251
// Provide alternative input method
252
showManualInputDialog();
253
}
254
```
255
256
## Error Handling
257
258
Common error scenarios and handling strategies:
259
260
```typescript
261
try {
262
const result = await bridge.send('VKWebAppOpenCodeReader');
263
processQRResult(result);
264
} catch (error) {
265
switch (error.error_data?.error_code) {
266
case 4: // User cancelled
267
console.log('User cancelled QR scanning');
268
break;
269
case 6: // Permission denied
270
console.error('Camera permission denied');
271
showPermissionDialog();
272
break;
273
case 10: // Camera not available
274
console.error('Camera not available on device');
275
showCameraUnavailableMessage();
276
break;
277
default:
278
console.error('QR scanning failed:', error);
279
showGenericErrorMessage();
280
}
281
}
282
```