Заполнение textField из глобальной переменной завершается неудачно - PullRequest
0 голосов
/ 24 апреля 2019

Я довольно новичок в Swift и использую приложение Ad Chatruit Basic Chat для iOS https://github.com/adafruit/Basic-Chat, которое использует BLE, и я добавляю свой собственный viewController и добавляю его вместо того, который предоставляет Adafruit. Мой ViewController (ServoViewController) выглядит как ожидалось.

Я связываюсь с Arduino через BLE и получаю данные от Arduino и анализирую соответствующую часть (и печатаю на терминал) данные в файле BLECentralViewController.

Я установил строковую переменную вне класса BLECentralViewController (поэтому, насколько я понимаю, она должна быть глобальной). Я считал данные в эту переменную в BLECentralViewController и снова успешно их распечатал.

Затем я пытаюсь использовать эту переменную String для заполнения textField в моем viewController, однако textField никогда не записывается.

В файле BLECentralViewController у меня есть переменные, объявленные вне класса следующим образом:

var dataReceived: String = ""
public var batteryVal: String = "" // global variable

Я проверяю входящие данные с Arduino. Если он содержит строку «Батарея», я знаю, что это данные батареи. Я могу получить и получить подстроку (% заряда батареи) и распечатать ее на терминал.

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

        if characteristic == rxCharacteristic {
            if let ASCIIstring = NSString(data: characteristic.value!, encoding: String.Encoding.utf8.rawValue) {
                characteristicASCIIValue = ASCIIstring
                print("Value Received: \((characteristicASCIIValue as String))")
                dataReceived = (characteristicASCIIValue as String)

                if dataReceived.contains("Battery:")    {
                    print ("Battery value: ", dataReceived)
                    print("Substring: ", dataReceived.substring(from: 8))
                    batteryVal = dataReceived.substring(from: 8)
                    print("Printing batteryVal: ", batteryVal)

                }
                NotificationCenter.default.post(name:NSNotification.Name(rawValue: "Notify"), object: nil)
                cvcrd.reportValvePosition()

            }
        }
    }

В моем viewController (ServoViewController) у меня есть следующая функция

func reportBatteryPercent() {
        // print battery value here
        batteryField.text = batteryVal
        print("Reporting Battery Percentage here...", batteryVal)
    }

Для начала я просто хотел заполнить textField при первой загрузке ServoViewController, поэтому я вызвал reportBatteryPercent () в viewDidLoad (). В окне вывода терминала я вижу, что появляется «Отчет о проценте батареи здесь ...», но на выходной клемме не выводится значение для batteryVal и batteryField.text пуст.

Поскольку я запускаю свой ServoViewController, никакого перехода нет, поэтому я решил, что глобальная переменная будет простым способом доступа к этим данным. Что я делаю не так с доступом к глобальной переменной из моего viewController?

РЕДАКТИРОВАТЬ: В соответствии с рекомендациями я поместил reportBatteryPercent () в viewWillAppear следующим образом:

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        reportBatteryPercent()
    }

Однако данные все еще не распечатываются в ServoViewController. Я попытался изменить объявление строки с:

public var batteryVal: String = ""

до:

public var batteryVal: String = "999"

и теперь он печатает 999 в текстовом поле. Таким образом, проблема теперь заключается в том, что ServoViewController читает строку batteryVal после того, как он был обновлен BLECentralViewController

РЕДАКТИРОВАТЬ 2: Я подтвердил вышеупомянутое, возвращаясь к первому viewController (BLECentralViewController), а затем возвращаясь ко второму viewController (ServoViewController). Теперь отображается правильное значение.

Я сейчас далеко от своего компьютера Apple, но, возможно, я мог бы это исправить, когда я нажал на второй ViewController, я мог видеть, является ли значение интереса пустой строкой и спит секунду? Будет ли это спать основной поток? Если это так, как бы я спал поток, который делает push viewController?

Ответы [ 3 ]

0 голосов
/ 24 апреля 2019

Так как я нажимаю на ServoViewController, нет никакого перехода, поэтому я решил, что глобальная переменная будет простым способом доступа к этим данным

Нет, вы все еще можете отправить значение на следующий виртуальный канал, как

let vc = stroybard.....
vc.someProperty = // value
self.navigationController?.push

плюс вам не рекомендуется использовать глобальные переменные, поскольку они сбивают с толку


didUpdateValueFor - это асинхронный метод, поэтому вам нужно убедиться, что varaible, который вы объявляете как глобальный, имеет правильное значение при нажатии

0 голосов
/ 24 апреля 2019

Глобальные переменные ленивы, поэтому вы не можете зависеть от них. Вы должны иметь переменную как статическую в структуре или в классе с одноэлементной ссылкой.

См. Как создать глобальную переменную? для получения дополнительной информации.

0 голосов
/ 24 апреля 2019

Попробуйте позвонить reportBatteryPercent в viewWillAppear. И вы получите то, что хотите.

Здесь могут быть некоторые проблемы: глобальные переменные пусты до viewDidLoad, или просто ваш контроллер не готов обработать эти переменные.

Чтобы проверить это, установите начальные значения глобальных переменных равными непустые строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...