iOS CoreBluetooth: centralManager:didConnectPeripheral / didFailToConnectPeripheral: не се извиква

Скубя си косата от тези проблеми. Опитвам се да свържа с BLE устройства, но не виждам какво съм направил грешно в кода си по-долу.

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    _cm = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

+ (NSString*)UUIDString:(CFUUIDRef)uuid {
    CFStringRef string = CFUUIDCreateString(NULL, uuid);
    return (__bridge_transfer NSString*)string;
}

- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    if (central.state == CBCentralManagerStatePoweredOn) {
        [self scanForPeripherals];
    }
}

- (void)centralManager:(CBCentralManager *)central
 didDiscoverPeripheral:(CBPeripheral *)peripheral
     advertisementData:(NSDictionary *)advertisementData
                  RSSI:(NSNumber *)RSSI {
//    NSLog(@"Received peripheral : \n%@", peripheral);
//    NSLog(@"Adv data : %@", advertisementData);

    [peripheral setDelegate:self];
    [central connectPeripheral:peripheral options:nil];
    [peripheral readRSSI];
}

- (int)scanForPeripherals {
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:NO], CBCentralManagerScanOptionAllowDuplicatesKey,
                             nil];

    [_cm scanForPeripheralsWithServices:nil options:options];
    return 0;
}

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    NSLog(@"didConnectPeripheral");
}

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    NSLog(@"didDisconnectPeripheral");
}

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    NSLog(@"failed to connect");
}

- (void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(NSError *)error {
    NSLog(@"didReadRSSI");
}

Тези устройства не са мои. Не знам неговия UUID за близост, но доколкото знам, няма да е необходим при свързване чрез CoreBluetooth, нали?

Всички устройства са открити в didDiscoverPeripheral:, в селектора се опитах да ги свържа. Но след това нищо не идва.

Трябва ли да очаквам диалогов прозорец с искане за парола за сдвояване, когато се обадя на didDiscoverPeripheral:? Ако е така, не виждам никакъв диалог, защо е така?

От документите на Apple ясно се посочва, че след като се опитате да се свържете с устройство, трябва да получите обаждане до didConnectPeripheral или didFailToConnectPeripher, но не получих нито едно.

някакви мисли? Опитвам се вече почти седмица. Оценявам всяка помощ, благодаря.


person Mysteltainn    schedule 15.10.2014    source източник
comment
Получавате ли обаждане до didDiscoverPeripheral? Опитахте ли да премахнете обаждането до [peripheral readRSSI], което веднага следва вашата заявка за свързване? Не трябва да подавате тази заявка, докато не сте свързани. Винаги предлагам на хората да изпробват безплатното приложение LightBlue от магазина за приложения като тест, за да видят дали устройството им рекламира и дали може да се свърже   -  person Paulw11    schedule 15.10.2014
comment
Да, опитах, имаше първата версия на този код, където той не прави нищо, освен открива и се опитва да се свърже, но след изпълнението на connectPeripheral нищо не се случва.   -  person Mysteltainn    schedule 15.10.2014
comment
Опитайте LightBlue - по този начин можете поне да потвърдите, че хардуерът може да се свърже. Също така опитайте да съхраните периферното устройство, към което се свързвате, в свойство, така че да не бъде освободено   -  person Paulw11    schedule 15.10.2014
comment
Опитах, всички се показват в LightBlue, не се показват услуги за нито едно устройство. Има 2 от The Estimotes BLE и още 2 от моя персонализиран BLE*. Запитването на оценките BLE води до успешна връзка, но след няколко секунди LightBlue казва Прекъснато предупреждение и има червен текст, казващ, че данните са остарели, за други 2 запитвания на устройства, разкриващи друга страница като оценките и нищо повече   -  person Mysteltainn    schedule 15.10.2014
comment
Може да помогне: stackoverflow.com/questions/28167804/   -  person oOEric    schedule 12.08.2015


Отговори (2)


Ако по някакъв начин не запазите обекта peripheral, който е доставен на didDiscoverPeripheral, той се освобождава, след като този метод на делегиране излезе и няма да получите връзка.

Предлагам да добавите свойство за проследяване на открити периферни устройства

@property (strong,nonatomic) NSMutableArray *peripherals;

инициализирайте това в viewDidLoad или init

self.peripherals=[NSMutableArray new];

И след това добавете периферното устройство към него в didDiscoverPeripheral

-(void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
    NSLog(@"Discovered peripheral %@",peripheral.identifier.UUIDString);
    [self.peripherals addObject:peripheral];
    [central connectPeripheral:peripheral options:nil];
}
person Paulw11    schedule 15.10.2014
comment
да!!! Това върши работа, благодаря ти много @Paulw11. Не знаех, че периферното устройство, предадено от didDiscoverPeripheral, е слабо реферирано. Също така не намирам нищо красноречиво за това в документите на Apple или аз пропуснах тази част? Както и да е, много благодаря!!!. - person Mysteltainn; 15.10.2014
comment
Не знам как го намерих - мисля, че трябваше да го разбера по трудния начин. Както и да е, сравних приложението си с вашия код и това беше разликата - person Paulw11; 15.10.2014
comment
Добро хващане. Също така уведомих току-що, след вашия отговор, че всички учебни пособия, след които работя, поддържат препратка към свързаните устройства. Малък въпрос, но със сигурност благодаря много, отново. @Paulw11 - person Mysteltainn; 15.10.2014
comment
@Paulw11 Приложението ми не се стартира на заден план, когато изключа bluetooth.. Зададох въпрос тук: stackoverflow.com/questions/ 48030480/ - person Saleh; 01.01.2018
comment
@Paulw11 извиква ли се методът centralManagerDidUpdateState, когато потребителят включи bluetooth след няколко часа? Заседнал съм там, където centralManagerDidUpdateState не се извиква, ако изключа радиото и го включа след няколко часа. - person Saleh; 03.01.2018
comment
Не вярвам, че didUpdateState се извиква във фонов режим; Трябва да проверя. - person Paulw11; 03.01.2018
comment
@Paulw11, когато изключа bluetooth, докато приложението е свързано, и го включа след няколко минути, изглежда нищо не се извиква в приложението. И когато ръчно стартирам приложението, периферното устройство е заседнало в състояние на свързване. Как мога да се възстановя от тази ситуация. Зададох подробен въпрос тук: stackoverflow.com/questions/48030480/ - person Saleh; 08.01.2018
comment
@Paulw11 Трябва да остана свързан с приложението през цялото време във фонов режим. Работи перфектно, докато не изключа радиото, докато съм в свързано състояние. При включване никога не уведомява приложението. - person Saleh; 08.01.2018
comment
@Paulw11 Може ли, моля, да погледнете това. stackoverflow.com/questions/53321747/ - person va05; 16.11.2018
comment
@paulw11 Можете ли да ми кажете едно нещо. Когато отида във фонов режим на func centralManager(_ central: CBCentralManager, willRestoreState dict: [String: Any]) методът ще се извика от моя страна и ще ми даде състояние на услуга. Как сканирам нови устройства в фон, използващ централно управление ?Можете ли да ми дадете идея? - person sarit bahuguna; 09.06.2020

var peripherals = [CBPeripheral]()

func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
    peripherals.append(peripheral)
    bleManager.connectPeripheral(peripheral, options: nil)
}

Това е версията на Swift.

person Antony Wong    schedule 05.01.2016