2017-09-20 29 views
2

Je suis tout à fait nouveau pour la programmation iOS et je travaille avec Core Bluetooth dans Swift 3 pour connecter et échanger des données vers un périphérique spécifique (fait sur mesure). Si l'utilisateur sélectionne un mode spécifique dans l'application, j'ai besoin d'envoyer des données (caractéristiques d'écriture) à l'appareil à intervalles réguliers (chaque minute) ou à un moment précis même si l'utilisateur ouvre une autre application ou tourne l'écran de. Si l'application est active, je peux le faire avec un SchedulerTimer mais il s'arrête dès que l'application est devenue inactive. Il y a un moyen de continuer à envoyer des données au périphérique si l'application va au premier plan? Est-ce possible?Comment envoyer des données à un périphérique BLE sur une application IOS (swift) en arrière-plan?

Modifier

Voici mes modes d'arrière-plan (comme décrit par Deepak Tagadiya): Background Modes

Et ci-dessous un code de mon contrôleur:

class MyDevice: UIViewController { 

var centralManager: CBCentralManager? 
var selectedPeripheral: CBPeripheral? 
var mRXCharacteristic: CBCharacteristic? 
var mTXCharacteristic: CBCharacteristic? 
var auto_timer = Timer() 


@IBOutlet weak var AutoSwitch: UISwitch! 
@IBAction func AutoSwitch(_ sender: UISwitch) { 
     if(sender.isOn == true){ 
      activateAutoModeTask() 
     } else { 
      disableAutoModeTask() 
     } 

} 

override func viewDidLoad() { 
    super.viewDidLoad() 

    centralManager = CBCentralManager(delegate: self, queue: nil) 
    (…) 
} 

func activateAutoModeTask(){ 


    auto_timer.invalidate() // just in case this button is tapped multiple times 

    // start the timer 
    auto_timer = Timer.scheduledTimer(timeInterval: 20, target: self, selector: #selector(updateTask), userInfo: nil, repeats: true) 

} 

func disableAutoModeTask(){ 
    auto_timer.invalidate() 
} 

func updateTask(){ 
    let new_value = getNewValue() //function that get the new value 


    send(text: new_value) 
} 

func send(text aText : String) { 
    (…) 
    self.selectedPeripheral?.writeValue(data, for: self.mRXCharacteristic!, type: .withResponse) 
} 

}

extension MyDevice: CBCentralManagerDelegate {

func centralManagerDidUpdateState(_ central: CBCentralManager) { 
    (…) 
} 

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { 
    (…) 
    peripheral.delegate = self 
    selectedPeripheral = peripheral 
} 

}

l'extension MyDevice: CBPeripheralDelegate {

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { 
    (...) 
} 


func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { 
    (…) 
} 

func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { 
    (…) 
} 

func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { 
    (…) 

    responseReceived(response: response_text) 
} 

}

donc je suis en mesure d'écrire sur le périphérique si l'application est active, mais pas quand l'application va en arrière-plan (si je clique sur le bouton Accueil par exemple). Peut-être qu'il manque encore quelque chose ...

Merci d'avance!

+0

Non, il n'est pas possible d'initier le transfert de la centrale (votre application) sur une base temporisée lorsqu'il est en arrière-plan. Votre périphérique pourrait émettre une notification chaque minute qui déclencherait votre application qui pourrait alors écrire une valeur. – Paulw11

+0

après 3 minutes, votre application n'est pas en mode vivant donc ce n'est pas possible. –

+0

@ Paulw11 pouvez-vous me donner de la documentation ou quelque chose où je peux trouver l'information qui prend en charge votre réponse? – sergio32

Répondre

2

Je faisais aussi face au même problème et je l'ai résolu en faisant cela. Activez les fonctions du mode Arrière-plan en fonction de vos besoins.

enter image description here

Espérons que cela vous aidera.

+0

Désolé Pooja Gupta mais pouvez-vous être plus précis s'il vous plaît? Parce que j'ai déjà activé le BackgroundMode pour "Utilise les accessoires Bluetooth LE" mais je crois que cela fonctionne si le périphérique envoie par exemple une notification (qui peut réveiller l'application) mais ne fonctionne pas dans l'autre sens .. – sergio32

0

Suivez étapes ci-dessous:

  1. projet Open.
  2. Sélectionnez la cible (sous le projet).
  3. Accédez à l'onglet "Capacités".
  4. Sélectionnez «Modes d'arrière-plan» (par défaut, il est désactivé)
  5. Sélectionnez «Utilise les accessoires Bluetooth LE» et «Agit comme un accessoire Bluetooth LE» (les deux).
  6. Exécuter le projet. enter image description here
+0

Hi Deepak, merci pour votre réponse, mais je suis toujours coincé sur cela. J'ai mis à jour ma question, pouvez-vous me donner des commentaires s'il vous plaît? – sergio32

0

Oui, dans des étapes spéciales et uniquement lorsque vous contrôlez des périphériques. Envoie un message au périphérique avec les informations de retard au prochain réveil.

Au premier plan, vous l'envoyez à peripheral = wakeme=30s App allez fond et attendez. Après 30s périphérique demande des données et envoie des données propres plus le prochain délai ...