@@ -183,7 +183,7 @@ - (void)initCapture
183183 [MWOverlay addToPreviewLayer: self .prevLayer];
184184#endif
185185
186- self.focusTimer = [NSTimer scheduledTimerWithTimeInterval: 1 .0 target: self selector: @selector (reFocus ) userInfo: nil repeats: YES ];
186+ self.focusTimer = [NSTimer scheduledTimerWithTimeInterval: 2 .0 target: self selector: @selector (reFocus ) userInfo: nil repeats: YES ];
187187
188188 [self CustomOverlay ];
189189}
@@ -382,7 +382,12 @@ - (void)dealloc {
382382
383383- (void ) startScanning {
384384 self.state = LAUNCHING_CAMERA;
385- [self .captureSession startRunning ];
385+
386+ dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
387+ [self .captureSession startRunning ];
388+ [self setRecommendedZoomFactor ];
389+ });
390+
386391 self.prevLayer .hidden = NO ;
387392 self.state = CAMERA;
388393}
@@ -413,6 +418,57 @@ - (void) deinitCapture {
413418 }
414419}
415420
421+ - (void ) setRecommendedZoomFactor {
422+ if (@available (iOS 15.0 , *)) {
423+ float deviceMinimumFocusDistance = [self .device minimumFocusDistance ];
424+
425+ if (deviceMinimumFocusDistance == -1 ) {
426+ return ;
427+ }
428+
429+ CMVideoDimensions formatDimensions = CMVideoFormatDescriptionGetDimensions ([self .device.activeFormat formatDescription ]);
430+ float rectOfInterestWidth = (float )formatDimensions.height / (float )formatDimensions.width ;
431+
432+ float deviceFieldOfView = [self .device.activeFormat videoFieldOfView ];
433+ float minimumSubjectDistanceForCode = [self minimumSubjectDistanceForCode: deviceFieldOfView minimumCodeSize: 20 previewFillPercentage: rectOfInterestWidth];
434+
435+ if (minimumSubjectDistanceForCode < deviceMinimumFocusDistance) {
436+ float zoomFactor = deviceMinimumFocusDistance / minimumSubjectDistanceForCode;
437+
438+ @try {
439+ NSError *error;
440+ if ([self .device lockForConfiguration: &error]) {
441+ self.device .videoZoomFactor = zoomFactor;
442+
443+ [self .device unlockForConfiguration ];
444+ }
445+ }
446+ @catch (id exceptionError) {
447+ NSLog (@" Could not lock for configuration" );
448+ }
449+ }
450+ }
451+ }
452+
453+ - (float ) minimumSubjectDistanceForCode : (float )fieldOfView
454+ minimumCodeSize : (float )minimumCodeSize
455+ previewFillPercentage : (float )previewFillPercentage
456+ {
457+ /*
458+ Given the camera horizontal field of view, we can compute the distance (mm) to make a code
459+ of minimumCodeSize (mm) fill the previewFillPercentage.
460+ */
461+ float fieldOfViewDivided = fieldOfView / 2 ;
462+ float radians = [self degreesToRadians: fieldOfViewDivided];
463+ float filledCodeSize = minimumCodeSize / previewFillPercentage;
464+
465+ return filledCodeSize / tan (radians);
466+ }
467+
468+ - (float ) degreesToRadians : (float )degrees
469+ {
470+ return degrees * M_PI / 180 ;
471+ }
416472
417473- (void )decodeResultNotification : (NSNotification *)notification {
418474
0 commit comments