Repository navigation
Conversation
Both scanners already detect all codes in a frame (MLKit on Android,
AVCaptureMetadataOutput on iOS) but only the first one was forwarded to JS.
onReadCode now also includes `codes`, an array of { codeStringValue, codeFormat }
for every code in the frame. Top-level codeStringValue/codeFormat still mirror
the first code, so existing consumers are unaffected.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UjZbt9u2A3dueq2sWj2j5Q
Native code constructing ReadCodeEvent with a single code keeps compiling, and an empty code list no longer throws when building the event payload. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UjZbt9u2A3dueq2sWj2j5Q
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Motivation
Some scanning workflows need several codes that are visible at the same time. In our case, a delivery driver scans a location QR (on a fridge) and a shipping-label QR in a single shot.
onReadCodecan only deliver one code per frame today, even though both native scanners already detect every code in the frame:BarcodeScanning.process()returns a list, andCKCamerafilters it byallowedBarcodeTypes/barcodeFrameSize.onBarcodeRead()then dispatches onlybarcodes.first().AVCaptureMetadataOutputdeliversmetadataObjectsfor every code in the frame, butmetadataOutput(_:didOutput:from:)forwards onlymetadataObjects.first.The extra codes are computed and then thrown away. This PR forwards all of them. It is a feature addition, not a bug fix.
API change (additive)
Backward compatibility
The event goes from carrying one code to carrying many, without changing anything existing single-code consumers rely on:
nativeEvent.codeStringValue/codeFormatcodes. We deliberately did not emit one event per code, so apps that de-duplicate or lock after the firstonReadCodekeep workingscanThrottleDelay,allowedBarcodeTypes,barcodeFrameSizeWritableMapcodesis one extra keyOnReadCodecodes: OnReadCodeCodes[].onFaceDetectedalready uses array-of-object event payloads, so there is no new minimum React Native versionReadCodeEvent(public class)(surfaceId, viewId, codeStringValue, codeFormat)CameraProtocol,ScannedCode)internalonly; no public Swift API changeTwo points worth a reviewer's call:
codesis typed as required because native always sends it. Code that only reads the event is unaffected. Code that builds anOnReadCodeDataby hand, such as test mocks, needscodes: []. I'm happy to make it optional if you prefer.nilstringValue. Now that object is skipped, and the remaining valid codes are still reported.Suggested release: minor.
Implementation
src/specs/CameraNativeComponent.ts,src/CameraProps.ts: addcodesto the event type. This follows the existingonFaceDetected/facespattern.ReadCodeEventtakes aList<ReadCodePayload>and writescodesplus the first code's top-level fields.CKCamera.onBarcodeRead()maps every filtered barcode.onBarcodeReadclosure (CameraProtocol/RealCamera/SimulatorCamera) now passes[ScannedCode].RealCamerausescompactMapover all metadata objects, andCameraViewemitscodesalongside the existing fields.CKCameraViewComponentView.mmbuilds the codegenOnReadCodeCodesvector, the same way it buildsOnFaceDetectedFaces.onReadCoderow andexample/src/BarcodeScreenExample.tsxnow showcodes.How did you test this change?
Static checks
tsc --noEmitpasses for the library and the example app.react-native codegen --platform ios): the generatedEventEmitters.hcontainsstruct OnReadCodeCodes { codeStringValue; codeFormat; }andstruct OnReadCode { codeStringValue; codeFormat; std::vector<OnReadCodeCodes> codes; }. These match the designated initializers inCKCameraViewComponentView.mm.Devices (example app → Barcode screen, two QR codes inside the scan frame)
codes.length === 2, both values showncodes.length === 2, both values showncodeStringValue/codeFormatunchanged,codes.length === 1onReadCode