Polidea / RxBluetoothKit

iOS & OSX Bluetooth library for RxSwift
Apache License 2.0
1.41k stars 372 forks source link

Support iOS 15 SDK #398

Open bspinner opened 3 years ago

bspinner commented 3 years ago

Is your feature request related to a problem? Please describe. Apps using RxBluetoothKit with iOS 15 SDK cannot be built.

Describe the solution you'd like Fix issues related to CoreBluetooth api changes (compiler complains about optionals that need to be unwrapped).

Describe alternatives you've considered None.

Additional context None.

tylerjames commented 3 years ago

They seem to have abandoned this library so I don't know if this issue will be resolved any time soon. Though someone may already have forked the library and made the changes

XabierGoros commented 3 years ago

So, new API changes have come with iOS 15 into the CoreBluetooth framework, and those causes the library to fail the compilation. The changes are related to nullability:

iOS 14.X

CBService
unowned(unsafe) var peripheral: CBPeripheral { get }

CBCharacteristic
unowned(unsafe) var service: CBService { get }

CBDescriptor
unowned(unsafe) var characteristic: CBCharacteristic { get }

iOS 15.X

CBService
weak var peripheral: CBPeripheral? { get }

CBCharacteristic
weak var service: CBService? { get }

CBDescriptor
weak var characteristic: CBCharacteristic? { get }

The main affected classes are:

Source/CentralManagerRestoredState.swift

public var services: [Service] {
    let objects = restoredStateData[CBCentralManagerRestoredStateScanServicesKey] as? [AnyObject]
    guard let arrayOfAnyObjects = objects else { return [] }
    #if swift(>=4.1)
    let cbServices = arrayOfAnyObjects.compactMap { $0 as? CBService }
    #else
    let cbServices = arrayOfAnyObjects.flatMap { $0 as? CBService }
    #endif

    return cbServices.map { Service(peripheral: centralManager.retrievePeripheral(for: $0.peripheral),
                                    service: $0) }
}

This one could be solved by filtering the ones that are not nil:

public var services: [Service] {
    let objects = restoredStateData[CBCentralManagerRestoredStateScanServicesKey] as? [AnyObject]
    guard let arrayOfAnyObjects = objects else { return [] }
    #if swift(>=4.1)
    let cbServices = arrayOfAnyObjects.compactMap { $0 as? CBService }
    #else
    let cbServices = arrayOfAnyObjects.flatMap { $0 as? CBService }
    #endif

    return cbServices
        .filter { $0.peripheral != nil }
        .map {
            Service(peripheral: centralManager.retrievePeripheral(for: $0.peripheral!), service: $0)
        }
}

Source/Characteristic.swift

convenience init(characteristic: CBCharacteristic, peripheral: Peripheral) {
    let service = Service(peripheral: peripheral, service: characteristic.service)
    self.init(characteristic: characteristic, service: service)
}

Source/Descriptor.swift

convenience init(descriptor: CBDescriptor, peripheral: Peripheral) {
    let service = Service(peripheral: peripheral, service: descriptor.characteristic.service)
    let characteristic = Characteristic(characteristic: descriptor.characteristic, service: service)
    self.init(descriptor: descriptor, characteristic: characteristic)
}

These last two might be a little bit trickier since we require not nullable parameters in Service and Characteristic. Making them optional have some side effects.

What do you think about that @mpiechocki?

XabierGoros commented 3 years ago

Adding @minixT to please the issue to shed us some light here.

chamira-at commented 3 years ago

@minixT or @mpiechocki are you able to have a look at the PR?

mpiechocki commented 3 years ago

@chamira-at I don't know if I will have time to look at it thoroughly, sorry. I think it's not clear if we will be able to maintain this library whatsoever, unfortunately :( I can try to take a look in some spare time but I cannot guarantee if it's going to be this week, next week or ever :(

DaBs commented 3 years ago

@mpiechocki Understandable that you guys will not be able to promise anything. Could this be considered grounds to move the project to the @abandonware organisation, so that the community may more effectively be able to solve the issues? iOS 15 is probably right around the corner (read: 7-14 days), so even a start of defaulting to moving it to abandonware would be helpful to a lot of people.

I highly appreciate you guys' work on this! It's been amazing using the project, and I'd hate to see it die, hence the suggestion.

eddy93 commented 3 years ago

What’s the workaround? How can we fix this just for our code to compile?

tylerjames commented 3 years ago

There are forks that have already applied the necessary changes for you to use in the meantime. You could fork from one of those and come back to the original if/when it's ever updated:

Try this one pod 'RxBluetoothKit', :git => 'https://github.com/i-mobility/RxBluetoothKit.git', :tag => '7.0.2'

hwikang commented 3 years ago

@tylerjames I tried to update pod with 7.0.2 tag but couldn't install

`

Pre-downloading: `RxBluetoothKit` from `https://github.com/i-mobility/RxBluetoothKit.git`, tag `7.0.2`
[!] CocoaPods could not find compatible versions for pod "RxSwift":
  In snapshot (Podfile.lock):
    RxSwift (= 5.1.3, ~> 5, ~> 5.0, ~> 5.1)

  In Podfile:
    RxBluetoothKit (from `https://github.com/i-mobility/RxBluetoothKit.git`, tag `7.0.2`) was resolved to 7.0.0, which depends on
      RxSwift (~> 6.0)

    RxSwift

Specs satisfying the `RxSwift, RxSwift (= 5.1.3, ~> 5, ~> 5.0, ~> 5.1), RxSwift (~> 6.0)` dependency were found, but they required a higher minimum deployment target.

`

I changed platform :ios, '10.0' to 11 ,12,13,14,15 but didn't work

XabierGoros commented 3 years ago

Hello @mpiechocki, have you guys considered what @DaBs suggested about moving the project to the community? It's been a while since iOS 15 came out, and it's pretty bad not to keep great projects like this up to date with blocker issues like this among other things. As he also mentions, I'd also thank a lot Polidea for what it did opening this great library to us.

odemiral commented 3 years ago

@hwikang

You need to make sure your other dependencies like RxSwift is also on 6.0+

you can use pod 'RxSwift', '>= 6.0' instead of pod 'RxSwift'

You might also need to update your other dependencies that relies on RxSwift (RxSwiftExt, RxCocoa, etc..) to the latest version.

gzzlit commented 3 years ago

so bad

Serg-Pogrebnyak commented 2 years ago

@mpiechocki any updates?

yusufonderd commented 2 years ago

Any updates ?

Serg-Pogrebnyak commented 2 years ago

@minixT @mpiechocki