title: Swift 3 data not sending to bluetooth device from iPhone app
body: <p>I am trying to send data from my iPhone to bluetooth device which is connected to an Arduino. I know the bluetooth device works fine because I used the app nRF connect and sent data from there to the bluetooth which the Arduino read.</p>
  
  <p>I think the way my app is organised is creating some problems.
  As it stands there are three view controllers.</p>
  
  <p>The first view controller  is a homepage screen which does not have much on it. You can connect the the second an third view controller from the homepage.
  The second view controller is a connection screen for the bluetooth
  The third view controller is an action screen with buttons</p>
  
  <p>The second view controller is a table view with a scan option to look for the available bluetooth devices. i use this code:</p>
  
  <pre><code>import UIKit
  import CoreBluetooth
  
  class ViewController: UIViewController, CBCentralManagerDelegate, UITableViewDataSource, UITableViewDelegate
  {
  
  //MARK: Variables
      //central manager
      var manager: CBCentralManager?
  
      //peripheral manager
      var peripheral: CBPeripheral?
  
      //HM-10 service code
      let HMServiceCode = CBUUID(string: "0xFFE0")
  
      //HM-10 characteristic code
      let HMCharactersticCode = CBUUID(string: "0xFFE1")
  
      //array to store the peripherals
      var peripheralArray:[(peripheral: CBPeripheral, RSSI: Float)] = []
  
      //for timing..obvs
      var timer: Timer!
  
  //MARK: IBOutlets
      //if cancel is pressed go back to homepage
      @IBAction func cancelButton(_ sender: Any)
      {
          performSegue(withIdentifier: "segueBackwards", sender: nil)
      }
  
      //this is for the tableview so that you can reference it
      @IBOutlet var tableView: UITableView!
  
      //allow for disabling the scanning button whilst scanning
      @IBOutlet var scanningButton: UIBarButtonItem!
  
      //loads the centralmanager delegate in here
      override func viewDidLoad()
      {
          manager = CBCentralManager(delegate: self, queue: nil)
          tableView.delegate = self
          tableView.dataSource = self
          super.viewDidLoad()
          if(peripheral != nil)
              {
                  disconnectPeripheral()
              }
      }
  
      //nothing
      override func didReceiveMemoryWarning()
      {
          super.didReceiveMemoryWarning()
      }
  
  //MARK: cancel any preexisting connection - this still needs to be done
      func disconnectPeripheral()
      {
          manager?.cancelPeripheralConnection(peripheral!)
      }
  
  //MARK: Bluetooth central
  
      //required centralmanager component. Text for what power state currently is
      func centralManagerDidUpdateState(_ central: CBCentralManager)
      {
          var consoleMsg = ""
          switch (central.state)
          {
          case.poweredOff:
              consoleMsg = "BLE is Powered Off"
              scanningButton.isEnabled = false
              alert()
  
          case.poweredOn:
              consoleMsg = "BLE is Powered On"
              scanningButton.isEnabled = true
  
          case.resetting:
              consoleMsg = "BLE is resetting"
  
          case.unknown:
              consoleMsg = "BLE is in an unknown state"
  
          case.unsupported:
              consoleMsg = "This device is not supported by BLE"
  
          case.unauthorized:
              consoleMsg = "BLE is not authorised"
          }
          print("\(consoleMsg)")
      }
  
  //MARK: Alert if Bluetooth is not turned on
      func alert ()
      {
          //main header
          let title = "Bluetooth Power"
  
          //the little debrief below the main title
          let message = "Please turn on Bluetooth to use this app"
  
          //text in the text box
          let text = "OK"
  
          //this says what the title and message is
          let alert = UIAlertController(title: title, message: message , preferredStyle: UIAlertControllerStyle.alert)
  
          //add button for the answer
          let okayButton = UIAlertAction(title: text, style: UIAlertActionStyle.cancel, handler: nil)
          alert.addAction(okayButton)
  
          //show the alert
          present(alert, animated: true, completion: nil)
          print("said ok on button to turning on bluetooth")
      }
  
  //MARK: Connection to bluetooth
      //once scanned this will say what has been discovered - add to peripheralArray
      func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber)
      {
          for existing in peripheralArray
          {
              if existing.peripheral.identifier == peripheral.identifier {return}
          }
          //adding peripheral to the array
          let theRSSI = RSSI.floatValue 
          peripheralArray.append(peripheral: peripheral, RSSI: theRSSI)
          peripheralArray.sort { $0.RSSI &lt; $1.RSSI }
          print("discovered peripheral")
          tableView.reloadData()
          print("There are \(peripheralArray.count) peripherals in the array")
      }
  
      //create a link/connection to the peripheral
      func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral)
      {
          peripheral.discoverServices(nil) //may need to remove this not sure it does much
          print("connected to peripheral")
      }
  
      //disconnect from the peripheral
      func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?)
      {
          print("disconnected from peripheral")
          stopScanning()
      }
  
      //if it failed to connect to a peripheral will tell us (although not why)
      func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?)
      {
          print("failed to connect to peripheral")
          stopScanning()
      }
  
  //MARK: scanning
      //press scan button to initiate scanning sequence
      @IBAction func scanButton(_ sender: Any)
      {
          startTimer()
      }
  
      //start scanning for 5 seconds
      func startTimer()
      {
          //after 5 seconds this goes to the stop scanning routine
          timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(ViewController.stopScanning), userInfo: nil, repeats: true)
          print("Start Scan")
          manager?.scanForPeripherals(withServices: [HMServiceCode], options: nil)
          scanningButton.isEnabled = false
      }
      //stop the scanning and re-enable the scan button so you can do it again
      func stopScanning()
      {
          timer?.invalidate()
          print("timer stopped")
          manager?.stopScan()
          print("Scan Stopped")
          print("array items are: \(peripheralArray)")
          print("peripheral items are: \(peripheral)")
          print("manager items are: \(manager)")
  
          scanningButton.isEnabled = true
  
      }
  
  //MARK: Table View
      //number of sections the table will have
      func numberOfSections(in tableView: UITableView) -&gt; Int
      {
          return 1
      }
  
      //number of rows each section of the table will have
      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int
      {
          return peripheralArray.count
      }
  
      //the way the data will be displayed in each row for the sections
      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell
      {
          let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
          let BluetoothNaming = peripheralArray[indexPath.row].peripheral.name
          cell.textLabel?.text = BluetoothNaming
  
          return cell
      }
  
      //what happens when we select an item from the bluetooth list
      func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
      {
          //tableView.deselectRow(at: indexPath, animated: true)
          stopScanning()
          peripheral = peripheralArray[(indexPath as NSIndexPath).row].peripheral
          print ("connecting to peripheral called \(peripheral)")
  
          //store the name of the connected peripeheral
          let connectedPeripheral = peripheral
          manager?.connect(connectedPeripheral!, options: nil)
          performSegue(withIdentifier: "segueBackwards", sender: nil)
      }
  
  //MARK: change label name
      override func prepare(for segue: UIStoryboardSegue, sender: Any?)
      {
          if segue.identifier == "segueBackwards"
          {
              if let indexPath = self.tableView.indexPathForSelectedRow
              {
                  //storing the name of the peripheral and then saving to send to Homepage
                  let peripheral = peripheralArray[indexPath.row].peripheral.name
                  let vc = segue.destination as! HomepageViewController
                  vc.selectedName = peripheral
  
                  //this is to unselect the row in the table
                  tableView.deselectRow(at: indexPath, animated: true)
              }
          }
      }
  
  //MARK: end
  }
  </code></pre>
  
  <p>All in all the second page I can connect to a bluetooth device. I then return to the the home screen. From here I then go to the third view controller which is to control actions for my app. I have it set so that you click a button and then that allows you to send data to the bluetooth. However for whatever reason it is, I am unable to send data. the button click works, but data is not sent.</p>
  
  <p>Here is my code for the third view controller:</p>
  
  <pre><code>    import UIKit
      import CoreBluetooth
  
      class SelectionViewController: UIViewController, CBPeripheralDelegate
      {
  
      //MARK: Variables
          var mainPeripheral: CBPeripheral?
          let UuidSerialService = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
          let UuidTx =            "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
          let UuidRx =            "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
          let txCharacteristicUUID =  "0000ffe0-0000-1000-8000-00805f9b34fb"
          let txServiceUUID =         "0000ffe1-0000-1000-8000-00805f9b34fb"
  
          /// Whether to write to the HM10 with or without response.
          /// Legit HM10 modules (from JNHuaMao) require 'Write without Response',
          /// while fake modules (e.g. from Bolutek) require 'Write with Response'.
          var writeType: CBCharacteristicWriteType = .withoutResponse
          var writeCharacteristic: CBCharacteristic?
  
      //MARK: IBOutlets
  
          @IBOutlet var whiteButtonControl: UIButton!
  
          @IBAction func doneButton(_ sender: Any)
          {
              performSegue(withIdentifier: "segueControltoHome", sender: nil)
          }
  
      //MARK: preset buttons
          @IBAction func whiteButton(_ sender: Any)
          {
              let value : UInt8 = 75
              let data = Data([value])
              mainPeripheral?.writeValue(data, for: writeCharacteristic!, type: writeType)
              print("Button pressed")
          }
  
  //MARK: Peripheral Control
      func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager)
      {
          var consoleMsg = ""
          switch (peripheral.state)
          {
          case.poweredOff:
              consoleMsg = "Peripheral is Powered Off"
  
          case.poweredOn:
              consoleMsg = "Peripheral is Powered On"
  
          case.resetting:
              consoleMsg = "Peripheral is resetting"
  
          case.unknown:
              consoleMsg = "Peripheral is in an unknown state"
  
          case.unsupported:
              consoleMsg = "This device is not supported by Peripheral"
  
          case.unauthorized:
              consoleMsg = "Peripheral is not authorised"
          }
          print("\(consoleMsg)")
      }
  
      func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?)
      {
          // discover the 0xFFE1 characteristic for all services (though there should only be one)
          for service in peripheral.services!
          {
              peripheral.discoverCharacteristics([CBUUID(string: "FFE1")], for: service)
          }
      }
  
      func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?)
      {
          // check whether the characteristic we're looking for (0xFFE1) is present - just to be sure
          print("reading this part")
          for characteristic in service.characteristics!
  
          {
              if characteristic.uuid == CBUUID(string: "FFE1")
              {
                  // subscribe to this value (so we'll get notified when there is serial data for us..)
                  peripheral.setNotifyValue(true, for: characteristic)
                  print ("subscribed to this value")
  
                  // keep a reference to this characteristic so we can write to it
                  writeCharacteristic = characteristic
                  print("characteristic is fine")
              }
          }
      }
  </code></pre>
  
  <p>I think part of the problem is that the peripheral  service and characteristic are not connecting to the central? Does this sound right?
  At the moment I am looking to send the value 75 to the bluetooth which the Arduino  can then read.
  Have i done something wrong with the peripheral delegate?
  What do i need to do to make it be able to send data</p>
  
  <p>thanks</p>