0

I have a framework built in Objetive-C. That framework is to connect and interact with a Bluetooth device.

In the demo code, the Objetive-C delegate function looks like. The demo code was provided by the creator of the framework.

-(void)babyScaleManagerScanDevices:(NSArray<ELBabyScaleDeviceModel *> *)babyScaleDevices{
    NSLog(@"babyScaleManagerScanDevices = %@",babyScaleDevices);
    ELBabyScaleDeviceModel *model = babyScaleDevices.firstObject;
}

I've included the framework in my swift project and imported the headers. I'm trying to obtain the same result by doing:

func babyScaleManagerScanDevices(_ babyScaleDevices: [ELBabyScaleDeviceModel]?) {
    guard let device = babyScaleDevices?.first else {
      print("Error unwrapping first device")
      return
    }
    print("Device: \(String(describing: device))")
  }

I get the following exception:

Thread 1: Precondition failed: NSArray element failed to match the Swift Array Element type
Expected ELBabyScaleDeviceModel but found ELPeripheralModel

Precondition failed: NSArray element failed to match the Swift Array Element type
Expected ELBabyScaleDeviceModel but found ELPeripheralModel: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1100.2.274.2/swift/stdlib/public/core/ArrayBuffer.swift, line 354

Inspecting babyScaleDevices array show:

babyScaleDevices    [ELBabyScaleDeviceModel]?   1 value some
[0] ELPeripheralModel * 0x281cae100 0x0000000281cae100

This result is the same in the demo code in Objetive-C and my Swift project.

The class ELBabyScaleDeviceModel.h looks like:

#import "ELPeripheralModel.h"

NS_ASSUME_NONNULL_BEGIN

@interface ELBabyScaleDeviceModel : ELPeripheralModel

@end

NS_ASSUME_NONNULL_END

Can you explain me what is happening?

  • From error it seems that you should have `func babyScaleManagerScanDevices(_ babyScaleDevices: [ELPeripheralModel]?) {`. Maybe there is a bug inside a framework. Try to change it to this if your compiler will let you. – Matic Oblak Nov 28 '19 at 11:49
  • Change `func babyScaleManagerScanDevices(_ babyScaleDevices: [ELBabyScaleDeviceModel]?)` to `func babyScaleManagerScanDevices(_ babyScaleDevices: [ELPeripheralModel]?)`, but clearly there is a mistake in the framework. I hope there is a quick way to create a `ELBabyScaleDeviceModel` from a `ELPeripheralModel`. – Larme Nov 28 '19 at 11:49

3 Answers3

0

You have to specify Array to NSArray

Add this line to your code

let devices = babyScaleDevices as NSArray

You can try this

func babyScaleManagerScanDevices(_ babyScaleDevices: [ELBabyScaleDeviceModel]?) {
let devices = babyScaleDevices as NSArray
guard let device = devices.firstObject else {
    print("Error unwrapping first device")
    return
}
print("Device: \(String(describing: device))")

}

And after then check this -> Array vs NSArray

0

Try to change

func babyScaleManagerScanDevices(_ babyScaleDevices: [ELBabyScaleDeviceModel]?)

to

func babyScaleManagerScanDevices(_ babyScaleDevices: [Any]?)

and cast specific elements to ELBabyScaleDeviceModel, for example, in for. It seems like the creator of this framework put ELPeripheralModel in the array instead of ELBabyScaleDeviceModel

AntiVIRUZ
  • 342
  • 1
  • 14
0

I think its just the way that the code is bridged to Swift.

Could you try to specify the type as [ELPeripheralModel] and then cast it?

func babyScaleManagerScanDevices(_ babyScaleDevices: [ELPeripheralModel]?) {

    guard let devices = devices = babyScaleDevices as? [ELBabyScaleDeviceModel], 
          let device = devices?.first else {
      print("Error unwrapping first device")
      return
    }
    print("Device: \(String(describing: device))")
}
Scriptable
  • 19,402
  • 5
  • 56
  • 72