Nativescript: [Bluetooth plugin question] Class "CBCentralManager" referenced by type encoding not found at runtime

Created on 31 Oct 2020  Â·  13Comments  Â·  Source: NativeScript/NativeScript

Environment
Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):

  • CLI: 6.8.0
  • Cross-platform modules:
  • Android Runtime:
  • iOS Runtime: 6.5.2
  • XCode Version: xcode 12
  • Plugin(s):

Describe the bug
Our app is crashing when I do NS upgrade to 6.5.2. It has been crashing in production after ios 14 release on certain ios devices (please refer to the original issue that I had created https://github.com/NativeScript/NativeScript/issues/8962 for production crash details). This is the error that I am seeing in my logs when I do a tns run ios. I know where the error is coming from but I am not sure which CB dependency should I include in our dependency so that it doesn't complain about CBCentralManager. Is this something that you can help us in?

JavaScript error:
file: node_modules/nativescript-bluetooth/bluetooth.ios.js:247:0: JS ERROR Error: Class "CBCentralManager" referenced by type encoding not found at runtime.
(CoreFoundation) *** Terminating app due to uncaught exception 'NativeScript encountered a fatal error: Error: Class "CBCentralManager" referenced by type encoding not found at runtime.
at
new(file: node_modules/nativescript-bluetooth/bluetooth.ios.js:247:0)
at file: node_modules/nativescript-bluetooth/bluetooth.ios.js:247:0
at file: node_modules/nativescript-bluetooth/bluetooth.ios.js:335:0
at ../node_modules/nativescript-bluetooth/bluetooth.js(file: node_modules/nativescript-bluetooth/bluetooth.ios.js:340:1)
at __webpack_require__(file: app/webpack/bootstrap:750:0)

To Reproduce
tns run ios with above-mentioned ns versions

Expected behavior
The app should come up correctly.

Sample project

Additional context

  1. If I open the code in xcode and include CoreBluetooth.framework dependency in xcode, the app works just fine with ns upgrade. It is with the command tns run ios, I get the above exception and the app crashes. Please help. Thanks.

Most helpful comment

Thanks @NathanWalker for lending a hand... It seems to be working on my local setup with simulator. Let me submit my app in test flight and see if the upgrade and fix go all the way.

All 13 comments

I believe you are using an incompatible CLI-Xcode build combination see the following update article.

https://nativescript.org/blog/nativescript-6-7-xcode-compatibility/

Additionally as @jcarolus mentioned below the recent tns-ios version fix may have some problems.

https://github.com/NativeScript/NativeScript/issues/8867#issuecomment-716450165

Apologies if this reply is insufficient or ill formatted new to posting on GitHub, but having torn my hair out over the recent Xcode update figured I could provide useful input!

edited for grammer and additional detail.

Hey @jburrowsPro thanks for replying. I am using xcode 12, ns6 cli, with tns-core-modules 6.5.20 and tns-ios 6.5.2. nativescript mentioned this and so I am hoping that the combination that I gave in my description, will work with xcode 12:

Most of the TSC members have already upgraded to Xcode 12 and are using it daily to build both NS 6 & NS 7 applications.
That said, if I use the latest ns version with the 7.0 combination, it gives all kinds of app errors and my app is not even starting.

@vguptapq hi, you don't have to update core modules to 7.0. Just the cli. To clarify:

  • npm i -g nativescript@latest <-- this is just the cli
  • Modify your package.json: tns-ios: 6.5.3 <-- This is important as it contains iOS 14 compliance.
  • Leave everything else the same in your package.json including tns-core-modules: 6.5.20
  • Then ns clean
  • Then run your project.

You'll see a orange warning/note about nativescript.config which is normal. This is just a friendly reminder that {N} 7 provides a new consolidated config but allows your {N} 6 based project to run as usual.

Hi, @NathanWalker thanks for the steps. That's what I meant. I had updated the cli to 7.0.11 but earlier today evening, I had done ns migrate to let things migrate to see if that will make any difference and that caused so many issues in my repo. With your steps, run was so much cleaner although I had to do ns run ios --force to run my project.

Anyhow, with your steps as well, I am getting a crash that I mentioned in this ticket's main description. To summarize, my cli version is 7.0.11, tns-ios is at 6.5.3 and tns-core-modules is at 6.5.20. I am sending the crash log again. As I said earlier, if I enable CoreBluetooth.framework in xcode, my app seems to be running fine. I am not able to run tns run ios or tns debug ios though and that's concerning to me.

file: node_modules/nativescript-bluetooth/bluetooth.ios.js:247:0: JS ERROR Error: Class "CBCentralManager" referenced by type encoding not found at runtime. (CoreFoundation) *** Terminating app due to uncaught exception 'NativeScript encountered a fatal error: Error: Class "CBCentralManager" referenced by type encoding not found at runtime. at new(file: node_modules/nativescript-bluetooth/bluetooth.ios.js:247:0) at file: node_modules/nativescript-bluetooth/bluetooth.ios.js:247:0 at file: node_modules/nativescript-bluetooth/bluetooth.ios.js:335:0 at ../node_modules/nativescript-bluetooth/bluetooth.js(file: node_modules/nativescript-bluetooth/bluetooth.ios.js:340:1) at __webpack_require__(file: app/webpack/bootstrap:750:0) at fn(file: app/webpack/bootstrap:120:0) at ./devices/shared/gatt/gatt.service.ts(file:///app/bundle.js:2136:99) at __webpack_require__(file: app/webpack/bootstrap:750:0) at fn(file: app/webpack/bootstrap:120:0) at ./devices/shared/preferredDevices/preferredDevices.service.ts(file:///app/bundle.js:2599:110) at __webpack_require__(file: app/webpack/bootstrap:750:0) at fn(file: app/webpack/bootstrap:120:0) at ./devices/shared/index.ts(file: app/devices/shared/index.ts:1:0) at __webpack_require__(file: app/webpack/bootstrap:750:0) at fn(file: app/webpack/bootstrap:120:0) at ./app.module.ts(file:///app/bundle.js:436:92) at _<…> NativeScript caught signal 6. Native Stack: 1 0x1031be171 sig_handler(int) 2 0x7fff5dccf5fd _sigtramp 3 0x1 4 0x7fff200fabd4 abort 5 0x7fff20250818 abort_message 6 0x7fff20241e7d demangling_unexpected_handler() 7 0x7fff201781d1 _objc_terminate() 8 0x7fff2024fc47 std::__terminate(void (*)()) 9 0x7fff202523d0 __cxa_get_exception_ptr 10 0x7fff20252397 __cxxabiv1::exception_cleanup_func(_Unwind_Reason_Code, _Unwind_Exception*) 11 0x7fff2017809c _objc_exception_destructor(void*) 12 0x10316db6f NativeScript::reportFatalErrorBeforeShutdown(JSC::ExecState*, JSC::Exception*, bool) 13 0x1031bf524 -[TNSRuntime executeModule:referredBy:] 14 0x1029c2153 main 15 0x7fff20257415 start JS Stack:

@vguptapq yep I had just noticed your original post had mentioned you were trying to use CLI 6.8.0 with Xcode 12 which appear to be incompatible with one another.

Using Xcode 12 - You need to use NS 7.0.10+ CLI

I only have experience with the: CLI 6.8.0, tns-ios 6.5.3, Xcode 11 configuration, so best of luck with the upgrade!

@vguptapq possible to copy/paste contents of your package.json here?

@NathanWalker here it is:

{
  "description": "NativeScript Application",
  "license": "SEE LICENSE IN <your-license-filename>",
  "readme": "NativeScript Application",
  "repository": {
    "type": "git",
    "url": "https://github.com/XXX"
  },
  "nativescript": {
    "id": "com.XXX",
    "tns-ios": {
      "version": "6.5.3"
    },
    "tns-android": {
      "version": "6.1.2"
    }
  },
  "scripts": {
    "lint": "tslint \"src/**/*.ts\""
  },
  "dependencies": {
    "@angular/animations": "~8.2.0",
    "@angular/common": "~8.2.0",
    "@angular/compiler": "~8.2.0",
    "@angular/core": "~8.2.0",
    "@angular/forms": "~8.2.0",
    "@angular/http": "8.0.0-beta.10",
    "@angular/platform-browser": "~8.2.0",
    "@angular/platform-browser-dynamic": "~8.2.0",
    "@angular/router": "~8.2.0",
    "@ngrx/effects": "^8.5.1",
    "@ngrx/store": "^8.5.1",
    "@nstudio/nativescript-cardview": "^1.0.0",
    "@nstudio/nativescript-pulltorefresh": "^1.0.1",
    "SmartMedBackgrounder": "https://github.com/ConcordanceHealth/SmartMedBackgrounder.git#01.00.79",
    "moment": "^2.17.1",
    "nativescript-angular": "^8.20.3",
    "nativescript-bluetooth": "https://github.com/ConcordanceHealth/nativescript-bluetooth.git#01.00.40_androidXFix",
    "nativescript-chs-utils": "https://github.com/ConcordanceHealth/nativescript-chs-utils.git#01.00.72",
    "nativescript-contacts-lite": "~0.2.6",
    "nativescript-exit": "^1.0.1",
    "nativescript-feedback": "^1.3.9",
    "nativescript-fingerprint-auth": "~7.0.2",
    "nativescript-iqkeyboardmanager": "1.3.0",
    "nativescript-local-notifications": "4.0.1",
    "nativescript-localstorage": "~2.0.1",
    "nativescript-modal-datetimepicker": "1.0.3",
    "nativescript-orientation": "2.2.0",
    "nativescript-permissions": "1.3.0",
    "nativescript-secure-storage": "~2.6.0",
    "nativescript-theme-core": "~1.0.4",
    "nativescript-ui-calendar": "^6.0.0",
    "nativescript-ui-gauge": "^6.0.0",
    "nativescript-ui-sidedrawer": "8.0.0",
    "nativescript-windowed-modal": "~6.0.0",
    "reflect-metadata": "~0.1.12",
    "rxjs": "^6.4.0",
    "tns-core-modules": "^6.5.20",
    "uint48be": "^1.0.2",
    "zone.js": "^0.9.1"
  },
  "devDependencies": {
    "@angular/compiler-cli": "~8.2.0",
    "@ngtools/webpack": "~8.2.0",
    "@phenomnomnominal/angular-lazy-routes-fix": "^0.1.5",
    "codelyzer": "~4.5.0",
    "nativescript-dev-webpack": "^1.3.0",
    "node-sass": "4.12.0",
    "tns-ios": "6.5.3",
    "tns-platform-declarations": "6.0.1",
    "tslint": "^5.20.1",
    "typescript": "~3.5.3"
  }
}

Thanks @vguptapq sounds like you are able to run the app now correct?

if I enable CoreBluetooth.framework in xcode, my app seems to be running fine.

That is correct that in order to use bluetooth features you need it enabled and need the usage description as noted here:
https://developer.apple.com/documentation/corebluetooth

Your app will crash if its Info.plist doesn’t include usage description keys for the types of data it needs to access. To access Core Bluetooth APIs on apps linked on or after iOS 13, include the NSBluetoothAlwaysUsageDescription key. In iOS 12 and earlier, include NSBluetoothPeripheralUsageDescription to access Bluetooth peripheral data.

Also note it only works in device and not simulator:
https://developer.apple.com/forums/thread/74567

Lemme know if anything else is still pending or have further question?

No @NathanWalker I am not able to run the app using tns run ios command. It crashes on me with the above-mentioned crash log. I am able to run the app only in xcode. I hope I am able to bring out the difference. Additionally, my info.plist has those keys present in the main app which is MobilePatient.
To give more context, we have been running this app for 3 years now in production and this crash has started appearing after ios 14 upgrade.
How do I prevent this crash when I run my app using tns run ios? Thanks.

@vguptapq thanks. Lemme confirm a couple additional things as I think a few things have gotten a bit confusing.

  1. Are you using tns run ios with simulator or device?
  2. If using with simulator you cannot use bluetooth features and thus would need to guard those areas to not be called when developing on simulator
  3. When you mention 'not able to run the app using tns run ios' command. What exactly does that mean? It crashes right when it starts? On simulator and device? This is related to 1.

For others than run into this issue I talked with @vguptapq and found that CoreBluetooth framework must be included in the app. {N} bluetooth plugins which use that framework can add this to their own xcconfig's to help user's however without waiting on any plugin author update, each app developer intending to use bluetooth features via plugins that rely on that framework can modify:

  • App_Resources/iOS/build.xcconfig

To add the following line at end of that file to ensure this is added (which makes it happy in device and simulator):

OTHER_LDFLAGS = $(inherited) -framework CoreBluetooth
  • Then ns clean

Bluetooth via nativescript-bluetooth or other plugins which rely on that framework will now work properly.

published a new version of the plugin but only for N 7.
if still on 6.x i advice the fix presented by @NathanWalker

Thanks @NathanWalker for lending a hand... It seems to be working on my local setup with simulator. Let me submit my app in test flight and see if the upgrade and fix go all the way.

Was this page helpful?
0 / 5 - 0 ratings