iOS: honor frameWidth/frameHeight as the scan area, improve scan reliability - #469
Open
macCesar wants to merge 11 commits into
Open
iOS: honor frameWidth/frameHeight as the scan area, improve scan reliability#469macCesar wants to merge 11 commits into
macCesar wants to merge 11 commits into
Conversation
…yst slices Repackage the vendored ZXingObjC.xcframework with modern slices only: ios-arm64 (device) and ios-arm64_x86_64-simulator. Drops armv7/i386 (32-bit) and the Mac Catalyst slice, none of which are supported by current Titanium SDKs or Xcode toolchains. Update the manifest accordingly: architectures arm64 x86_64, mac: false (Catalyst slice no longer shipped), and bump module version to 6.0.1. minsdk is unchanged.
…s for Xcode 26 Bump TITANIUM_SDK_VERSION to 13.3.0.GA and replace the recursive Frameworks/** search path with per-SDK slice paths. Xcode 26's module resolution picked the ios-arm64 (device) TitaniumKit slice while compiling the x86_64 simulator arch, failing with 'unsupported Swift architecture'. Pointing iphoneos/iphonesimulator builds at their matching xcframework slices fixes the archive on both destinations. Verified with: ti build -p ios --build-only (SDK 13.3.0.GA, Xcode 26.6)
Dropping the Mac Catalyst slice (shipped in the v6.0.0-iphone release) is a breaking change for Catalyst consumers, so this is a major bump rather than a patch. Matches the Android precedent (v7.0.0-android was a major bump for its library update).
Bring the iOS scanner to parity with Android: capture() now reads frameWidth/frameHeight (points) and sizes the overlay crop rect to a centered rect of those dimensions. Since applyRectOfInterest already maps the crop rect to ZXCapture.scanRect, both the drawn rectangle and the decoded region honor the requested size — a thin rect isolates a single barcode on dense sheets, like a scanner gun. Also draw a red laser line through the middle of the scan area, matching the Android viewfinder. Default behavior (no frame options) is unchanged. Bump module to 7.1.0.
…ensor The previous scanRect math scaled the crop rect by layer/video size directly, ignoring that AVLayerVideoGravityResizeAspectFill scales the video until it fills the layer and hides the overflow (and it mixed the X/Y scale factors after the portrait axis swap). On 16:9 screens the error was small enough for the huge default rect to work, but on 4:3 screens (iPads) the decoded region drifted far from the drawn rectangle — with a small custom frame nothing under it ever decoded. Unproject the on-screen crop rect through the aspect-fill transform (uniform scale + hidden overflow) before converting it to sensor coordinates, and drop the now-unused _captureSizeTransform ivar. Also darken the area outside the scan rect, matching the Android viewfinder mask.
- Capture at 1080p instead of ZXCapture's 720p default, so small or distant barcodes have enough pixels to decode without misreads. - Restrict autofocus to the near range and enable smooth autofocus (Apple's recommendation for barcode scanning) so the camera stops hunting to infinity at typical scanning distances. - Play a system beep on each new decoded value, matching the Android client's BeepManager. Deduped by value: with keepOpen the same barcode decodes on every frame and would otherwise beep continuously. - Fix captureResult's NSLog to use a proper format string instead of passing the scanned text as the format (crash/format-specifier risk).
…xists ZXCapture only honors sessionPreset when it first creates its capture session, which the camera setter triggers — before viewDidLoad. Setting the preset there left the session at 720p while applyRectOfInterest mapped the scan area against the 1080p geometry the property reported, pushing the decode crop out of the real buffer and breaking scanning entirely. Set the preset right after the ZXCapture instance is created instead.
applyRectOfInterest only ran when the native rectangle was drawn, so apps that hide it (showRectangle: false) to draw their own overlay silently lost the frameWidth/frameHeight decode limit and scanned the whole frame. Android limits the decode region independently of the drawn viewfinder; do the same here.
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
Brings the iOS scanner to parity with Android and fixes long-standing accuracy issues in the scan-area mapping:
frameWidth/frameHeightsupport —capture()now honors these options (in points) to size the scan area, as Android already does: both the drawn rectangle and the region ZXCapture decodes are limited to a centered rect of the requested size. A thin rect (e.g.frameWidth: 300, frameHeight: 50) isolates a single barcode on dense sheets, like a scanner gun.scanRectmath scaled the crop rect by layer/video size directly, ignoring the overflow hidden byAVLayerVideoGravityResizeAspectFill(and mixing X/Y scales after the portrait axis swap). On 16:9 phones the huge default rect masked the error; on 4:3 iPads the decoded region drifted far from the drawn rectangle.keepOpendecodes the same barcode on every frame.captureResultno longer passes scanned text as anNSLogformat string.Module bumped to 7.1.0 with a CHANGELOG entry. Default behavior without
frameWidth/frameHeightis unchanged.Test plan
ti build -p ios --build-onlygreen (Titanium SDK 13.3.0.GA, Xcode 26.6)keepOpen: true) collects multiple distinct codes reliably