Current Working Swift Code:

//
//  ScanCompleteViewController.swift
//  Clutch-IDS
//
//  Created by Joshua Dinkin on 16/4/2024.
//

import Foundation
import UIKit
import CoreBluetooth
import QuartzCore

enum ReceivedMessageOption: String {
    case none,
         newline
}

class ScanCompleteViewController: UIViewController, BluetoothSerialDelegate {

    @IBOutlet weak var mainTextView: UITextView!

    @IBOutlet weak var mainLabel: UILabel!

    @IBOutlet weak var barButton: UIButton!
    
    @IBOutlet weak var titleLabel: UILabel!

    var messageReceivedText = &#34;Waiting for message...&#34;
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // init serial
        serial = BluetoothSerial(delegate: self)

        
        // UI
        //mainTextView.text = &#34;&#34;
        //mainTextView.numberOfLines = 0
        //reloadView()

        NotificationCenter.default.addObserver(self, selector: #selector(ScanCompleteViewController.reloadView), name: NSNotification.Name(rawValue: &#34;reloadStartViewController&#34;), object: nil)
        
    }
    
    @objc func reloadView() {
        // in case we&#39;re the visible view again
        serial.delegate = self
        
        if serial.isReady {
            titleLabel.text = serial.connectedPeripheral!.name
            barButton.setTitle(&#34;Disconnect&#34;, for: .normal)
            barButton.setTitleColor(.red, for: .normal)
            barButton.isEnabled = true
        } else if serial.centralManager.state == .poweredOn {
            titleLabel.text = &#34;Bluetooth Serial&#34;
            barButton.setTitle(&#34;Connect&#34;, for: .normal)
            barButton.setTitleColor(view.tintColor, for: .normal)
            barButton.isEnabled = true
        } else {
            titleLabel.text = &#34;Bluetooth Serial&#34;
            barButton.setTitle(&#34;Connect&#34;, for: .normal)
            barButton.setTitleColor(view.tintColor, for: .normal)
            barButton.isEnabled = false
        }
    }
    
    func textViewScrollToBottom() {
        let range = NSMakeRange(NSString(string: mainTextView.text).length - 1, 1)
        mainTextView.scrollRangeToVisible(range)
    }

    //MARK: BluetoothSerialDelegate
    
    func serialDidReceiveString(_ message: String) {
        
//        print(&#34;Received message: \(message)&#34;)
//        DispatchQueue.main.async {
//            self.mainTextView.text = &#34;Message Received: \(message)\n&#34;
//            //self.mainTextView.text! += message + &#34;\n&#34;
//            //self.textViewScrollToBottom()
//            
//        }
        
        print(&#34;Received message: \(message)&#34;)
          messageReceivedText = &#34;Message Received: \(message)\n&#34;
          DispatchQueue.main.async {
              self.mainTextView.text = self.messageReceivedText
          }
        
    }
    
    func serialDidDisconnect(_ peripheral: CBPeripheral, error: NSError?) {
        reloadView()
        let hud = MBProgressHUD.showAdded(to: view, animated: true)
        hud?.mode = MBProgressHUDMode.text
        hud?.labelText = &#34;Disconnected&#34;
        hud?.hide(true, afterDelay: 1.0)
    }
    
    func serialDidChangeState() {
        reloadView()
        if serial.centralManager.state != .poweredOn {
            let hud = MBProgressHUD.showAdded(to: view, animated: true)
            hud?.mode = MBProgressHUDMode.text
            hud?.labelText = &#34;Bluetooth turned off&#34;
            hud?.hide(true, afterDelay: 1.0)
        }
    }
    
//    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
//        if let error = error {
//                print(&#34;Error reading characteristics: \(error)&#34;)
//                return
//            }
//
//            if let value = characteristic.value {
//                if let dataBLE = String(data: value, encoding: .utf8) {
//                    print(&#34;Data from Arduino: \(dataBLE)&#34;)
//                    DispatchQueue.main.async {
//                        self.mainLabel.text! += dataBLE + &#34;\n&#34;
//                        self.textViewScrollToBottom()
//                    }
//                } else {
//                    print(&#34;Failed to convert data to string&#34;)
//                }
//            }
//        }
    
    @IBAction func buttonPressed(_ sender: Any) {
        if serial.connectedPeripheral == nil {
            performSegue(withIdentifier: &#34;ShowScanner&#34;, sender: self)
        } else {
            serial.disconnect()
            reloadView()
        }
    }
}