Jump to content
Sign in to follow this  
Rollo62

Has the relevance of UIRequiredDeviceCapabilities changed since IOS13 ?

Recommended Posts

Posted (edited)

Hi there,

 

I'm using Bluetooth-LE, and I can see that apps might crash in RELEASE under TestFlight,
while they work well in DEBUG.

This happened never on older iOS versions, so I still try to find the real reason for crashing.

 

What I think is that the bluetooth-le flag not only controls the download from AppStore,
but maybe also might cause internal crash's, if not defined.

 

I use bluetooth, with UIBackgroundModes "location", "bluetooth-cetral" and "audio" background modes,

which worked well before (and still does in DEBUG), but now shows the typical permission crashes, all on modern phones and iPads with iOS13.4.1.

My configuration: Rx10.3.3, XCode 11.4.1, iOS13.4.1.

 

Maybe I need to define bluetooth-le in the UIRequiredDeviceCapabilities, or does that doesn't make any difference in apps behaviour ?

Edited by Rollo62

Share this post


Link to post
15 hours ago, Rollo62 said:

shows the typical permission crashes,

You'll need to be more specific.

Share this post


Link to post
Posted (edited)
12 hours ago, Dave Nottage said:

You'll need to be more specific.

Ok, I will try, but the real reason where any why it crashes I cannot tell.
I found by heavy logging in the sources that it crashes when calling the GetConnectionState method: (I added a lot of Logs around the problem zone).

(System.Mac.Bluetooth)

 

In DEBUG,

After first start, Location "when using" appears, and the selection is visible in the settings: All OK

the app doesn't crash, and when touching GetConnectionState first time, the Bluetooth alert appears.  : All OK

After first start, the Bluetooth switch is visible in the apps settings: All OK

 

In RELEASE (only via TestFlight, not in debug w/ run),

After first start, Location "when using" appears, and the selection is visible in the settings: All OK
the app crashes, when touching GetConnectionState first time, no Bluetooth alert appears.  : not OK

After start and crash, the Bluetooth switch is NOT visible in the apps settings: not OK

 

I use the audio, location, bluetooth-central background modes, (but the problem occurs in Foreground, )

I have set all necessary strings

NSLocationAlwaysUsageDescription, NSLocationWhenInUseUsageDescription, NSLocationAlwaysAndWhenInUseUsageDescription

NSBluetoothPeripheralUsageDescription , NSBluetoothAlwaysUsageDescription

 

 

Here are some parts

function TMacBluetoothLEManager.GetConnectionState: TBluetoothConnectionState;
var
  LTotal: Single;
begin
  if FAdapter = nil then
    FAdapter := TMacBluetoothLEAdapter.Create(Self);
    LMacBluetoothLEAdapter := TMacBluetoothLEAdapter(FAdapter);

  if LMacBluetoothLEAdapter.FLEManager.FCentralManager.state = CBCentralManagerStatePoweredOn then
     Result := TBluetoothConnectionState.Connected;
  else
  begin

    LTotal := 0;
    repeat

      InternalWaitMessage(0.05);

      LTotal := LTotal + 0.05;

    until (LTotal >= 1) or 
          //<====== FATAL CRASH happens here, see Logs below for DEBUG/RELEASE, the request of state seems to crash in RELEASE    
          (LMacBluetoothLEAdapter.FLEManager.FCentralManager.state = CBCentralManagerStatePoweredOn);

    if LMacBluetoothLEAdapter.FLEManager.FCentralManager.state = CBCentralManagerStatePoweredOn then
      Result := TBluetoothConnectionState.Connected
    else
      Result := TBluetoothConnectionState.Disconnected;
      
  end;


end;

The LOG enhanced code is

function TMacBluetoothLEManager.GetConnectionState: TBluetoothConnectionState;
var
  LTotal: Single;
  LMacBluetoothLEAdapter: TMacBluetoothLEAdapter;
  LCurrAdp : TMacBluetoothLEAdapter;  //S4: 22.04.20
begin
  if FAdapter = nil then
    FAdapter := TMacBluetoothLEAdapter.Create(Self);
  LMacBluetoothLEAdapter := TMacBluetoothLEAdapter(FAdapter);

  //#######
  //##
  //S4: 22.04.20   wait until central manager fully created
  // PREVENT FATAL CRASH
  //
  LTotal := 0;
  repeat
      InternalWaitMessage(0.05);  // Give a little delay to finish EnableBluetooth
      LTotal := LTotal + 0.05;

      // CurrentManager just reads the FManager variable
      LCurrAdp := LMacBluetoothLEAdapter;

      if Assigned( LCurrAdp ) then
      begin   // if available, maybe still not ready yet
          if Assigned( LCurrAdp.FLEManager ) then
          begin
              if Assigned( LCurrAdp.FLEManager.FCentralManager ) then
              begin
                  InternalWaitMessage(0.05);  // Give a little more safety delay

                  break;
              end;

          end;

      end;

  until (LTotal > 1.5 );
  //This loop doesn't really cause the crash, as considered first, always leaving directly

  if LTotal <= 1.5 then
  begin
      S4Log.d(   'TMacBluetoothLEManager.GetConnectionState'
               + ' (1a) BLE State OK: '   + Format( '%2.2f', [LTotal]) );
  end
  else
  begin
      S4Log.d(   'TMacBluetoothLEManager.GetConnectionState'
               + ' (1b) BLE State FAIL: ' + Format( '%2.2f', [LTotal]) );
  end;
  //
  //S4: 22.04.20   try wait until central manager fully created
  //##
  //#######

  S4Log.d(   'TMacBluetoothLEManager.GetConnectionState'
           + ' (2a) Check state' );

                 
  if LMacBluetoothLEAdapter.FLEManager.FCentralManager.state = CBCentralManagerStatePoweredOn then
  begin
      S4Log.d(   'TMacBluetoothLEManager.GetConnectionState'
               + ' (3a) state is connected' );

     Result := TBluetoothConnectionState.Connected;
  end
  else
  begin
      S4Log.d(   'TMacBluetoothLEManager.GetConnectionState'
               + ' (3b) state is NOT connected' );

    LTotal := 0;
    repeat
      S4Log.d(   'TMacBluetoothLEManager.GetConnectionState'
               + ' (4a) repeat before wait' );

      InternalWaitMessage(0.05);    

      S4Log.d(   'TMacBluetoothLEManager.GetConnectionState'
               + ' (4b) repeat after wait' );

      LTotal := LTotal + 0.05;

      //LMacBluetoothLEAdapter.FLEManager.

    until (LTotal >= 1) or 
          //<====== FATAL CRASH happens here, see Logs below for DEBUG/RELEASE, the request of state seems to crash in RELEASE
          (LMacBluetoothLEAdapter.FLEManager.FCentralManager.state = CBCentralManagerStatePoweredOn);
          

    S4Log.d(   'TMacBluetoothLEManager.GetConnectionState'
             + ' (3c) before result' );

    if LMacBluetoothLEAdapter.FLEManager.FCentralManager.state = CBCentralManagerStatePoweredOn then
    begin
      Result := TBluetoothConnectionState.Connected;

      S4Log.d(   'TMacBluetoothLEManager.GetConnectionState'
               + ' (3c) result CONN' );

    end
    else
    begin
      Result := TBluetoothConnectionState.Disconnected;

      S4Log.d(   'TMacBluetoothLEManager.GetConnectionState'
               + ' (3d) result DISCONN' );

    end;
  end;


end;

 

Here are the logs for DEBUG:

Quote

10:28:46.481 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (1a) BLE State OK: 0,05
10:28:46.481 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (2a) Check state
10:28:46.481 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (3b) state is NOT connected
10:28:46.481 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:46.481 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:46.481 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:46.543 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:46.543 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:46.543 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:46.543 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:46.543 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:46.543 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:46.593 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:46.593 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:46.645 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:46.645 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:46.696 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:46.696 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:46.747 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:46.747 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:46.798 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:46.798 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:46.849 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:46.849 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:46.901 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:46.901 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:46.953 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:46.953 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:47.005 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:47.005 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:47.056 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:47.057 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:47.108 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:47.108 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:47.160 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:47.160 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:47.212 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:47.212 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:47.263 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:47.264 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:47.315 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:47.315 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
10:28:47.366 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
10:28:47.367 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (3c) before result
10:28:47.367 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (3d) result DISCONN

<========================= AT LEAST NO CRASH IN DEBUG
 

and for RELEASE

Quote

11:57:30.826 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (1a) BLE State OK: 0,05
11:57:30.826 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (2a) Check state
11:57:30.826 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (3b) state is NOT connected
11:57:30.826 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait
11:57:30.832 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4b) repeat after wait
11:57:30.832 - TS4Log: BLE_C: TMacBluetoothLEManager.GetConnectionState (4a) repeat before wait

<========= ALRADY HERE A FATAL CRASH IN RELEASE (via TestFlight)

 

The strange thing is that is eeems to crash in the timer delay, not really the state request,

but I won't rely on the logs in this fatal crah situation.

The logs may be cutted in the crash.

 

      S4Log.d(   'TMacBluetoothLEManager.GetConnectionState'
               + ' (4a) repeat before wait' );                 <===== LOG IS STILL HERE

      InternalWaitMessage(0.05);

      S4Log.d(   'TMacBluetoothLEManager.GetConnectionState'
               + ' (4b) repeat after wait' );                 <===== LOG IS NOT HERE (CRASHED)

 

Its very strange, because it was working well for years before, and now crashes, but only in RELEASE, DEBUG works fine.

 

What wonders me is that even in DEBUG the state doesn't return as CONNECTED, but as disconnected.

 

I'm pretty sure I'm missing a minor piece in the puzzle, but I cannot spot it.

 

 

 

 

 

Edited by Rollo62
  • Like 1

Share this post


Link to post
Posted (edited)

I've tried some back and forth, but it still keeps same.

Crash happens at sampe place in RELEASE, when touching the GetConnectionState.

 

In DEBUG it shows BLE authorization alert, in settings BLE switch is visible, and also it didn't crash at GetConnectionState.

In RELEASE it didn't show BLE authorization alert, also not visible switch in the settings, of coarse logically the BLE might crash.

 

The problem seems to be that only in RELEASE the Bluetooth alert didn't appear when touching the CBManager, also no Bluetooth switch in the settings.
I have here iOS13.4.1, use Rx10.3.3 w/ all relevant hotfixes, and XCode 11.4.1, and SDK-Manager was updated to the current debug images.

It should work with that configuration, all other stuff wors as well.

 

Seems that there have been changes to the authorization system in iOS, since iOS13.

I know that there have been changes and deprecated functions in the CBManager and CBManagerAuthorization,

but that shouldbe be the reason.

 

The problem seems to be that the BLE alert is not popping up, so what would be the right way to enforce that ?

Apple says somewhere that any touch of CBManager would cause that, but I double it.

Maybe there is a special operation which should be used to popup BLE alert, I used ConnectionState in the past (working well).

 

The CoreBluetooth is somewhat hacked into the units, there is no separate CoreBluetooth I have found.
I haven't used the header conversions from Eli's FmxExpress yet, not sure if they reflect the latest iOS13 changes,

but I hope that I don't have to rewrite the whole thing to make it workable under iOS13, its already massivly troubled now.

 

Any ideas ?

 

P.S.: All version info settings are same in debug, release, also info.plist is OK as far as I can tell (checked 100 times).

 

 

Edited by Rollo62

Share this post


Link to post
Posted (edited)

I've managed to remove this strange crash by re-creating the project from another, existing working project.

Since I'm very sure that all settings in the project before were OK (I checked all of them them 100 times), I suspect that
these project settings maybe be changed or get corrupt in a way that cannot be seen.

Unfortunately the .dproj file cannot nicely be checked or compared, to find that out.

 

I lost already a few days by finding that nasty "ghost", by searching the issue in codebase, and I will try to check and find the real reason later, I hope.

To reset the settings with some tools I've never really tried productive, I feel more save to recreate them new from a checklist instead,

this seems more reliable to me.

Since these messy options issue allready happened several times in different ways in the past years, which is always a headache,
I hope that options setting, comparing, resetting them could be a little improved in the future versions.

Edited by Rollo62

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×