0

On devices with iOS 13, when calling the GeneXus.SD.Media.Camera.TakePhoto() method for the first time takes about 10 to 15 seconds to continue program execution.

Execution of any other option or button is suspended until the camera control has been shown, otherwise the application stops working.

Note: This behavior only happens the first time GeneXus.SD.Media.Camera.TakePhoto() method is called.

The apparent problem is that Genexus is making a call to a thread in the background without using the following statement:

DispatchQueue.main.async {
//Do UI Code here. 
//Call Google maps methods.}

The log that the application shows when it is waiting to show the control of the camera is the following:

Log en XCODE 11.3

Main Thread Checker: UI API called on a background thread: -[UIApplication userInterfaceLayoutDirection]

PID: 268, TID: 5281, Thread name: (none), Queue name: com.apple.camera.zoom-dial-image-generation, QoS: 21

Backtrace:
4  GXUIApplication           0x000000010c674170 $s15GXUIApplicationAAC28userInterfaceLayoutDirectionSo06UIUsercdE0VvgTo + 212

5  UIKitCore              0x000000019fea34fc AA897CA9-8D15-3DD7-BB4F-8D90F9A28571 + 15566076

6  UIKitCore              0x000000019f6bdc8c AA897CA9-8D15-3DD7-BB4F-8D90F9A28571 + 7285900

7  UIKitCore              0x000000019f6bda18 AA897CA9-8D15-3DD7-BB4F-8D90F9A28571 + 7285272

8  UIKitCore              0x000000019f64a848 AA897CA9-8D15-3DD7-BB4F-8D90F9A28571 + 6813768

9  CameraUI              0x00000001bdfee5a8 91E5E69E-0F28-35E3-86F9-7AA8B1D7F726 + 1369512

10 UIKitCore              0x000000019f63ee94 AA897CA9-8D15-3DD7-BB4F-8D90F9A28571 + 6766228

11 UIKitCore              0x000000019f63ecb0 AA897CA9-8D15-3DD7-BB4F-8D90F9A28571 + 6765744

12 UIKitCore              0x000000019f63c464 AA897CA9-8D15-3DD7-BB4F-8D90F9A28571 + 6755428

13 CameraUI              0x00000001bdfee2c0 91E5E69E-0F28-35E3-86F9-7AA8B1D7F726 + 1368768

14 CameraUI              0x00000001bdfed65c 91E5E69E-0F28-35E3-86F9-7AA8B1D7F726 + 1365596

15 AssetsLibraryServices        0x00000001b0462d3c 31232DEC-0B77-3A8B-B80A-A51A16204F8E + 228668

16 libdispatch.dylib          0x000000010d091e1c _dispatch_call_block_and_release + 32

17 libdispatch.dylib          0x000000010d09327c _dispatch_client_callout + 20

18 libdispatch.dylib          0x000000010d09a90c _dispatch_lane_serial_drain + 720

19 libdispatch.dylib          0x000000010d09b4fc _dispatch_lane_invoke + 408

20 libdispatch.dylib          0x000000010d0a64dc _dispatch_workloop_worker_thread + 1344

21 libsystem_pthread.dylib       0x000000019b62b6d0 _pthread_wqthread + 280

22 libsystem_pthread.dylib       0x000000019b6319e8 start_wqthread + 8

2020-02-03 16:52:16.618996-0500 Routik[268:5281] [reports] Main Thread Checker: UI API called on a background thread: -[UIApplication userInterfaceLayoutDirection]

PID: 268, TID: 5281, Thread name: (none), Queue name: com.apple.camera.zoom-dial-image-generation, QoS: 21

Backtrace:
4  GXUIApplication           0x000000010c674170 $s15GXUIApplicationAAC28userInterfaceLayoutDirectionSo06UIUsercdE0VvgTo + 212

5  UIKitCore              0x000000019fea34fc AA897CA9-8D15-3DD7-BB4F-8D90F9A28571 + 15566076

6  UIKitCore              0x000000019f6bdc8c AA897CA9-8D15-3DD7-BB4F-8D90F9A28571 + 7285900

7  UIKitCore              0x000000019f6bda18 AA897CA9-8D15-3DD7-BB4F-8D90F9A28571 + 7285272

8  UIKitCore              0x000000019f64a848 AA897CA9-8D15-3DD7-BB4F-8D90F9A28571 + 6813768

9  CameraUI              0x00000001bdfee5a8 91E5E69E-0F28-35E3-86F9-7AA8B1D7F726 + 1369512

10 UIKitCore              0x000000019f63ee94 AA897CA9-8D15-3DD7-BB4F-8D90F9A28571 + 6766228

11 UIKitCore              0x000000019f63ecb0 AA897CA9-8D15-3DD7-BB4F-8D90F9A28571 + 6765744

12 UIKitCore              0x000000019f63c464 AA897CA9-8D15-3DD7-BB4F-8D90F9A28571 + 6755428

13 CameraUI              0x00000001bdfee2c0 91E5E69E-0F28-35E3-86F9-7AA8B1D7F726 + 1368768

14 CameraUI              0x00000001bdfed65c 91E5E69E-0F28-35E3-86F9-7AA8B1D7F726 + 1365596

15 AssetsLibraryServices        0x00000001b0462d3c 31232DEC-0B77-3A8B-B80A-A51A16204F8E + 228668

16 libdispatch.dylib          0x000000010d091e1c _dispatch_call_block_and_release + 32

17 libdispatch.dylib          0x000000010d09327c _dispatch_client_callout + 20

18 libdispatch.dylib          0x000000010d09a90c _dispatch_lane_serial_drain + 720

19 libdispatch.dylib          0x000000010d09b4fc _dispatch_lane_invoke + 408

20 libdispatch.dylib          0x000000010d0a64dc _dispatch_workloop_worker_thread + 1344

21 libsystem_pthread.dylib       0x000000019b62b6d0 _pthread_wqthread + 280

22 libsystem_pthread.dylib       0x000000019b6319e8 start_wqthread + 8

2020-02-03 16:52:26.217529-0500 Routik[268:5081] [Common] _BSMachError: port fe03; (os/kern) invalid capability (0x14) "Unable to insert COPY_SEND"
sebagomez
  • 9,501
  • 7
  • 51
  • 89

1 Answers1

1

Actually, it's a false positive in Apple's Main Thread Checker tool. Let me explain:

Main Thread Checker works by at app launch, dynamically replaces the implementations of methods that should only be called on the main thread with a version that prepends the check. Methods known to be safe for use on background threads are excluded from this check.

The method called from a background thread is -[UIApplication userInterfaceLayoutDirection]. GeneXus applications use a subclass of UIApplication (GXUIApplication) which overrides this method (userInterfaceLayoutDirection) in order to support SetLanguage function of Right to Left languages on Left to Right configured devices at runtime (or the other way around). Inside this override, [super userInterfaceLayoutDirection] is called, and this is where Main Thread Checker raises the warning.

This method is called in the background internally from Apple's frameworks implementations as you can see in the Backtrace you posted, everything except GXUIApplication userInterfaceLayoutDirection method itself is not GeneXus code.

The problem is Main Thread Checker raises the [UIApplication userInterfaceLayoutDirection] call warning only when the call is explicit, and ignored when it's called internally from another Apple framework. In this case, it's considered explicit because the method is overwritten in the subclass even though it's called internally from another Apple framework.

You can check this by replacing in the source file main.m, in the line:

return UIApplicationMain(argc, argv, NSStringFromClass([GXUIApplication class]), NSStringFromClass([GXAppDelegate class]));

with:

return UIApplicationMain(argc, argv, NSStringFromClass([UIApplication class]), NSStringFromClass([GXAppDelegate class]));

With this change (not using the subclass with the override), Main Thread Checker won't raise the warning, even though the same method is still being called internally from a background thread.

We will look for a workaround for this Main Thread Checker issue in the upcoming GeneXus upgrades (thanks for the report) and also notify Apple about the issue with Main Thread Checker. Meanwhile, you can disable Main Thread Checker from Xcode:

Product -> Scheme -> Edit Scheme...

Run -> Diagnostics -> Main Thread Checker

Also, you don't have to worry about this being an issue for your users, as Main Thread Checker is only active when the app is launched from Xcode (with Main Thread Checker diagnostic enabled).