Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin doesn't work in iOS 18 #711

Open
gassssty opened this issue Nov 4, 2024 · 8 comments
Open

Plugin doesn't work in iOS 18 #711

gassssty opened this issue Nov 4, 2024 · 8 comments
Labels
bug Something isn't working iOS Impacts the iOS platform

Comments

@gassssty
Copy link

gassssty commented Nov 4, 2024

Hi guys,

I'm trying to add this plugin for use on iOS phones but I'm not having any success in implementing it. However, for Android phones, it works perfectly.
Actually, the code is the same for both platforms. Let me explain a little bit what's happening with images and functions in code:

  • In our app we have a button where the initialize() is done:
initializeBleClient(): Promise<boolean> {
    return new Promise(async (resolve, reject) => {
      try {
        await BleClient.initialize();
        resolve(true);
      } catch (error) {
        console.error(error);
        reject(false);
      }
    })
  }
  • Once initialized, it does this function (scan the devices):
scanDevicesByOperatorUUID(): Promise<BleDevice> {
    return new Promise(async (resolve, reject) => {
      try {
        const selectedDevice = await BleClient.requestDevice(
          {
            services: [this._serviceUUID]
          }
        );
        console.log("Selected device: ", selectedDevice);        
        this.setSelectedDevice(selectedDevice);
        resolve(selectedDevice);
      } catch (error) {
        reject(undefined)
      }
    });
  }

IMG_0952

  • We select the device shown in the list:
connectToPickio(): Promise<boolean> {
    return new Promise(async (resolve) => {
      try {
        if (this.getSelectedDevice()) {
          await BleClient.disconnect(this.getSelectedDevice()!.deviceId);
          BleClient.connect(this.getSelectedDevice()!.deviceId, () => this.disconnectActions()).then(() => { 
            this.trackDeviceRSSI();
            this.signalModalShowing = 0;  
            resolve(true);
          }).catch(() => resolve(false));
        } else {
          resolve(false);
        }
      } catch (error) {
        resolve(false);
      }
    });
  }
  • It is connecting at the operating system level and not the application level, making it impossible for us to connect and move forward:
    IMG_0953

And then, we have some logs that we saw in the Xcode App:
⚡️ To Native -> BluetoothLe removeListener 51121821
⚡️ To Native -> BluetoothLe addListener 51121822
⚡️ To Native -> BluetoothLe connect 51121823
⚡️ BluetoothLe - Connecting to peripheral <CBPeripheral: 0x3018109c0, identifier = 338676A7-6DF4-02F6-210B-A84762F07FA6, name = pickio-004-005, mtu = 517, state = connected>
⚡️ [error] - ERROR {"errorMessage":"Connection timeout"}
⚡️ BluetoothLe - Connected to device <CBPeripheral: 0x3018109c0, identifier = 338676A7-6DF4-02F6-210B-A84762F07FA6, name = pickio-004-005, mtu = 517, state = connected>
⚡️ BluetoothLe - Resolve connect|338676A7-6DF4-02F6-210B-A84762F07FA6 Successfully connected.
⚡️ BluetoothLe - Connected to peripheral. Waiting for service discovery.
⚡️ BluetoothLe - Reject connect Connection timeout
ERROR MESSAGE: {"message":"Connection timeout","errorMessage":"Connection timeout"}
⚡️ [error] - {"message":"Connection timeout","errorMessage":"Connection timeout"}

Captura de pantalla 2024-11-04 a las 10 41 38

iOS Version: 18.1
Angular: 18.0.0
Ionic: 8.0.0
Capacitor Community BLE: 6.0.0

Thank you very much, guys!! :D

@gassssty gassssty added the bug Something isn't working label Nov 4, 2024
@peitschie
Copy link
Collaborator

Hi @gassssty

Did this app work with previous versions of iOS?

I have found that iOS tends to be more timing sensitive than Android. Given this is timing out in the service discovery phase, I wonder if perhaps the device you're connecting to is taking too long to finish discovery.

Do you have any control over the peripheral itself? Do you know anything about it's connection interval, connection latency etc?
Some of these details can be discovered with the Android version of nrf Connect, and can be helpful here.

@gassssty
Copy link
Author

gassssty commented Nov 5, 2024

Hi!

No, it doesn't work on an older version, specifically 17.4. Actually on Android it always works on the first try and there's nothing wrong with the code, at least from what it seems.

Do you have any control over the peripheral itself?
Yes, it is a computer.

About the peripheral information, here you have:

  • Device Type -> Classic and LE
  • Advertising Interval -> 1288 ms.
  • Advertising Type -> Legacy

And we don't have more information in the app nrf Connect. FYI: in Android is never connecting as OS level and with iOS always, with different iOS versions.

Thanks!!

@peitschie
Copy link
Collaborator

Interesting.

That advertising interval is very slow. Do you have any details about the connection interval or latency? (I believe nrf Connect on Android can show this information too).

How many services/characteristics are exposed via this peripheral?

@gassssty
Copy link
Author

gassssty commented Nov 7, 2024

Well, there isn't more information than this. And we have 22 characteristics.

@peitschie
Copy link
Collaborator

22 characteristics is quite a lot!

Can you try adding a very long timeout to your connect call? E.g.,

await BleClient.connect(device.deviceId, (d) => console.log("disconnected"), { timeout: 120000 });

With nrf Connect, it's a little bit tricky, but if you swipe to the right on the bottom left of the connected screen... you'll see this console slide out with some additional debug info:

unnamed

@gassssty
Copy link
Author

gassssty commented Nov 7, 2024

Ahh great, so we are going to try to reduce this characteristics. Which number is the maximum (or recommendable) to put in?

Is true that with 2 characteristics in iOS 17 we can connect but never with 22. And then in iOS 18, not even with 2 or 22 characteristics... but it's weird that in Android works fine with 22.

Finally... thanks to say that because we don't know how to use the app properly hahaha. Here you have a screenshot of the latency and interval:
image

@peitschie
Copy link
Collaborator

Is true that with 2 characteristics in iOS 17 we can connect but never with 22. And then in iOS 18, not even with 2 or 22 characteristics... but it's weird that in Android works fine with 22.

This is strange. On Android, that discovery is taking only about 500ms... I wonder why it's taking so much longer on iOS.
The default iOS timeout is 10s.. were you able to test this with a very long timeout? (e.g., 60s or more)?

I can't answer for sure what the upper limit is. I've definitely used things with several services and 5-8 characteristics per service. Never 22 on a single service... but you're saying that this isn't working with 2 on iOS?

There are some subtle differences between iOS and Android's connection paths that I've occasionally hit where a peripheral connects on Android (usually) and not iOS. I can't really guess the cause in your case though. Do you get any debug logs from the PC side of the connection, to spot any differences?

@gassssty
Copy link
Author

Yes, we tried with 120000 ms in the timeout option and it did not success... but we are going to try to reduce this 22 characteristics to 2 or something like that.

Exactly, is not working in 2 differente iOS devices, with different versions.

In theory in Android Studio it shows the same logs as the XCode does. The strange 'thing' is that in iOS is connecting always as SO and never in Android.

@peitschie peitschie added the iOS Impacts the iOS platform label Nov 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working iOS Impacts the iOS platform
Projects
None yet
Development

No branches or pull requests

2 participants