Сбой приложения iOS (конденсатор) при повороте устройства при инициализации камеры

#ios #swift #capacitor

#iOS #swift #конденсатор

Вопрос:

У меня есть приложение, созданное с использованием Ionic и Capacitor, и я использую некоторые встроенные плагины. Один из них называется CameraPreview и позволяет пользователю открывать собственную камеру для съемки с пользовательским дизайном. Проблема в том, что сегодня я только что столкнулся на своей панели управления Crashlytics с сообщением о неустранимой ошибке на нескольких устройствах iOS со следующим журналом:

 Crashed: com.apple.main-thread
0  CapacitorCommunityCameraPreview    0x9ff4 CameraPreview.rotated()   45 (Plugin.swift:45)
1  CapacitorCommunityCameraPreview    0xa028 @objc CameraPreview.rotated()   4299071528 (<compiler-generated>:4299071528)
2  CoreFoundation                     0x2aed8 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__   28
3  CoreFoundation                     0xc6b8c ___CFXRegistrationPost_block_invoke   52
4  CoreFoundation                     0x99f44 _CFXRegistrationPost   456
5  CoreFoundation                     0x40d44 _CFXNotificationPost   716
6  Foundation                         0x1a628 -[NSNotificationCenter postNotificationName:object:userInfo:]   96
7  UIKitCore                          0x299f70 -[UIDevice setOrientation:animated:]   296
8  GAXClient                          0x93b8 GAXProfileOverridesFromConfiguration   32140
9  UIKitCore                          0x832484 __134-[_UIWindowSceneDeviceOrientationSettingsDiffAction _updateDeviceOrientationWithSettingObserverContext:windowScene:transitionContext:]_block_invoke   144
10 UIKitCore                          0x270350  [BSAnimationSettings(UIKit) tryAnimatingWithSettings:actions:completion:]   892
11 UIKitCore                          0x1b2340 _UISceneSettingsDiffActionPerformChangesWithTransitionContext   276
12 UIKitCore                          0x43ab0 -[_UIWindowSceneDeviceOrientationSettingsDiffAction _updateDeviceOrientationWithSettingObserverContext:windowScene:transitionContext:]   264
13 UIKitCore                          0x5d9710 -[_UIWindowSceneDeviceOrientationSettingsDiffAction _performActionsForUIScene:withUpdatedFBSScene:settingsDiff:fromSettings:transitionContext:lifecycleActionType:]   224
14 UIKitCore                          0x724260 __64-[UIScene scene:didUpdateWithDiff:transitionContext:completion:]_block_invoke.608   776
15 UIKitCore                          0x1e0c60 -[UIScene _emitSceneSettingsUpdateResponseForCompletion:afterSceneUpdateWork:]   256
16 UIKitCore                          0x224524 -[UIScene scene:didUpdateWithDiff:transitionContext:completion:]   288
17 UIKitCore                          0x1ae370 -[UIApplicationSceneClientAgent scene:handleEvent:withCompletion:]   492
18 FrontBoardServices                 0xd100 -[FBSScene updater:didUpdateSettings:withDiff:transitionContext:completion:]   528
19 FrontBoardServices                 0x25d4c __94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke_2   152
20 FrontBoardServices                 0xa6b4 -[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:]   240
21 FrontBoardServices                 0x10b10 __94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke   396
22 libdispatch.dylib                  0x4660 _dispatch_client_callout   20
23 libdispatch.dylib                  0x8118 _dispatch_block_invoke_direct   264
24 FrontBoardServices                 0xbf94 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__   48
25 FrontBoardServices                 0xb3d4 -[FBSSerialQueue _targetQueue_performNextIfPossible]   220
26 FrontBoardServices                 0xf9e4 -[FBSSerialQueue _performNextFromRunLoopSource]   28
27 CoreFoundation                     0xbb020 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__   28
28 CoreFoundation                     0xcbce0 __CFRunLoopDoSource0   208
29 CoreFoundation                     0x5fe8 __CFRunLoopDoSources0   268
30 CoreFoundation                     0xb7f4 __CFRunLoopRun   820
31 CoreFoundation                     0x1f3b8 CFRunLoopRunSpecific   600
32 GraphicsServices                   0x138c GSEventRunModal   164
33 UIKitCore                          0x5196a8 -[UIApplication _run]   1100
34 UIKitCore                          0x2987f4 UIApplicationMain   2092
35 App                                0x8500 main   5 (AppDelegate.swift:5)
36 ???                                0x101269a24 (Ausente)
 

Я не разработчик iOS, но я попытался исследовать ошибку, поэтому я открыл Plugin.swift файл, но строка 45 — это конец rotated метода, упомянутого в сообщении. Таким образом, я не смог найти причину проблемы. Во время тестирования на iPhone 11 с iOS 15.1.0 я успешно воспроизвел ошибку. Это происходит, когда пользователь нажимает, чтобы открыть камеру, и поворачивает устройство одновременно с инициализацией камеры. Если я открываю камеру уже в портретном режиме, она работает правильно, и если я открываю ее уже в альбомном режиме, она тоже работает. Если камера уже инициализирована и пользователь поворачивает устройство, оно адаптируется нормально. Проблема, похоже, возникает только тогда, когда пользователь открывает камеру при вращении устройства до его инициализации.

Plugin.swift Файл находится здесь, а код метода:

 @objc func rotated() {
        
    let height = self.paddingBottom != nil ? self.height! - self.paddingBottom!: self.height!;

    if UIDevice.current.orientation.isLandscape {
            
        self.previewView.frame = CGRect(x: self.y!, y: self.x!, width: height, height: self.width!)
        self.cameraController.previewLayer?.frame = self.previewView.frame
            
        if (UIDevice.current.orientation == UIDeviceOrientation.landscapeLeft) {
            self.cameraController.previewLayer?.connection?.videoOrientation = .landscapeRight
        }
            
        if (UIDevice.current.orientation == UIDeviceOrientation.landscapeRight) {
            self.cameraController.previewLayer?.connection?.videoOrientation = .landscapeLeft
        }
    }

    if UIDevice.current.orientation.isPortrait {
        self.previewView.frame = CGRect(x: self.x!, y: self.y!, width: self.width!, height: height)
        self.cameraController.previewLayer?.frame = self.previewView.frame
        self.cameraController.previewLayer?.connection?.videoOrientation = .portrait
    }
} // line 45
 

Некоторые устройства на панели мониторинга, у которых была эта ошибка:

 iOS 15.1.1 (iPhone 12 Mini)
iOS 15.1.0 (iPhone 8 Plus)
iOS 14.8.1 (iPhone 11)
iOS 14.6.0 (iPhone 8 Plus)
iOS 15.1.0 (iPhone 11) - Which I got to reproduce the error
 

Как я могу найти проблему CameraPreview.rotated() и исправить ее?

Комментарии:

1. Похоже, что класс, содержащий этот метод, имеет НЕОБЯЗАТЕЛЬНЫЕ (могут быть явными или неявными, я не уверен) свойства x, y, width, paddingBottom и height . Возможно, вам придется искать больше (например, self.y!). Это очень опасно использовать ‘! ‘ символ. Я предполагаю, что одно или несколько из этих свойств (x, y, widht, height) равны нулю. Можете ли вы изменить код? если это так, вы можете поставить ‘guard пусть x = x, пусть y = y, пусть height = height, пусть width = width, paddingBottom = paddingBottom else { return }