В iOS 10+ есть ли КАКОЙ-ЛИБО способ НАДЕЖНО разбудить приложение

Я занимаюсь этим более 3 месяцев и рву на себе волосы. Поэтому, пожалуйста, не отвечайте новичками.

Мне интересно, есть ли в 2017 году с iOS 10+ ЛЮБОЙ способ разбудить приложение из завершенного состояния ... предпочтительно с помощью периферийного устройства Bluetooth ... но я возьму то, что смогу!

Я считаю завершенным, когда пользователь пролистнул приложение в диспетчере задач или когда периферийное устройство включено/выключено, а приложение уже мертво

Мне нужны важные периферийные данные BT, связанные со здоровьем (записанные устройством BT), которые хранятся в приложении, поэтому мне нужно стабильное соединение или возможность пробуждения приложения и обработки данных. Я знаю, что об этом много спрашивают, поэтому я пытаюсь найти самое актуальное понимание или решения этой проблемы. Я прочитал ооочень много статей и С.О. сообщения об этом, поэтому я знаю, что Core Bluetooth в лучшем случае ненадежен. Я знаю, что общая концепция ненадежна, и с 2010 года люди говорят, что это невозможно. Однако в iOS многое постоянно меняется, поэтому я надеялся, что что-то изменится.

Для ясности:

Пробуждение по BT было бы здорово, но на самом деле оно ненадежно, поэтому... Я выберу ЛЮБОЙ надежный способ пробуждения (местоположение, звук, BT и т. д.... НЕ iBeacon, хотя, поскольку я подключен/сопряжен с устройством BT) . Если мне нужно «хакнуть» пробуждение, чтобы оно происходило на месте или по звуку, а затем каким-то образом быстро получить данные с периферии, я возьму это!

Я пытался:

(ПРОПУСТИТЕ ЭТО, ЕСЛИ ВАМ НЕ НУЖНО ИЛИ К ЭТОМ НЕ ПРИМЕНЯЕТСЯ)


  • Фоновый центральный режим включен в info.plist
  • Используя полное восстановление состояния, то есть этот код...

    self.centralManager = [[CBCentralManager alloc] initWithDelegate:self
                                                               queue:nil
                                                                 options:@{CBCentralManagerOptionShowPowerAlertKey: @(YES),
                                                                           CBCentralManagerOptionRestoreIdentifierKey:@"MyDevice"}];
    

    Чтобы зарегистрировать ключ-идентификатор и этот код...

    - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        NSLog(@"launch options found: %@", launchOptions);
        NSArray *centralManagerIdentifiers = launchOptions[UIApplicationLaunchOptionsBluetoothCentralsKey];
    
        NSLog(@"central managers found in launch options: %@", centralManagerIdentifiers);
        [self triggerLocalNotification:[NSString stringWithFormat:@"central managers found in launch options: %@", centralManagerIdentifiers]];
    
        if([centralManagerIdentifiers count] > 0) {
            for(NSString *identifier in centralManagerIdentifiers) {
                if([identifier isEqualToString:@"MyDevice"]) {
                    [self triggerLocalNotification:[NSString stringWithFormat:@"Identifier found: %@", identifier]];
                    self.bluetoothManager = [BluetoothMgr sharedInstance];
                }
            }
        }
    
        return YES;
    }
    
    - (void)centralManager:(CBCentralManager *)central
      willRestoreState:(NSDictionary<NSString *,id> *)state {
    
        NSLog(@"************** RESTORED STATE BT **************");
        [self triggerCustomLocalNotification:@"************** RESTORED STATE BT **************"];
    
        NSLog(@"central manager object: %@", central);
        NSLog(@"state dictionary: %@", state);
    
        [self triggerCustomLocalNotification:[NSString stringWithFormat:@"state dictionary: %@", state]];
    
    
        NSArray *restoredPeripherals = [state objectForKey:@"CBCentralManagerRestoredStatePeripheralsKey"];
    
        self.centralManager = central;
        self.centralManager.delegate = self;
    
        if([restoredPeripherals count] > 0) {
            for(CBPeripheral *peripheral in restoredPeripherals) {
                if([peripheral.name rangeOfString:@"mybox-"].location != NSNotFound) {
                    NSLog(@"Restoring mybox Box: %@", peripheral);
                    [self triggerCustomLocalNotification:[NSString stringWithFormat:@"Peripheral was found in WILL RESTORE STATE! it was: %@", peripheral]];
    
                    self.myPeripheral = peripheral;
                    self.myPeripheral.delegate = self;
    
                    [self connectToDevice];
    
                    return;
                }
            }
        }
    }
    

    Для восстановления состояния центрального менеджера. Это работает только тогда, когда приложение убито iOS или изменено состояние. Не работает, когда пользователь убивает приложение.

  • Подписка на уведомляющую характеристику в устройстве (я создал эту пользовательскую характеристику, и у меня есть полный контроль над программированием устройства)... это работает очень хорошо, но не всегда пробуждает приложение. Хотя в фоновом режиме работает хорошо. Только не прекращено.

  • Попытка полностью отключиться после завершения, чтобы я мог использовать iBeacon для пробуждения ... слишком много обручей, и в конце концов он вообще не работает надежно.
  • Значительные обновления местоположения ... крайне ненадежно
  • Аудиозапись... никакие методы не срабатывают, когда начинается запись (которые я все равно мог найти) или методы, которые периодически срабатывают во время записи.

person GoreDefex    schedule 17.08.2017    source источник


Ответы (1)


Наконец решил эту проблему! Решение состояло в том, чтобы использовать 2 чипа Bluetooth в моем решении. Один чип должен быть выделенным BT-Connected Paired/Auth/Bonded устройством, а другой — выделенным рекламодателем iBeacon. С помощью этого решения я смог как разбудить приложение, когда захочу (путем включения и выключения питания чипа iBeacon по желанию), так и подключиться для требуемых характеристик шифрования BT.

Используя метод didEnterRegion класса CLLocationManager в фоновом режиме, я могу запустить диспетчер Bluetooth... подключиться к устройству в фоновом режиме, а затем успешно получить данные через ранее сопряженное соединение.

ОБНОВЛЕНИЕ: в качестве примечания полезно отметить, что, хотя iBeacon достаточно надежен в пробуждении приложения в фоновом режиме, только метод didEnterRegion происходит немедленно, когда iBeacon найден или включен. Метод didExitRegion занимает у меня (в среднем) около 30 секунд, чтобы выстрелить после того, как я выключаю iBeacon или он больше не находится в пределах досягаемости.

person GoreDefex    schedule 21.08.2017
comment
@GoraDefex Мне нужна твоя помощь. Пожалуйста, посмотрите мой вопрос: stackoverflow.com/questions/47813624/ - person yusufonderd; 18.12.2017
comment
@GoreDefex Пожалуйста, посмотрите на вопрос. Мне также нужен ответ на тот же вопрос: stackoverflow.com/questions/47813624 - person Anmol Kukreja; 18.01.2018