Ich habe eine App, die ein UILabel hat, dass ich gerne von einer anderen Swift-Klasse aktualisiert würde? Die Klasse ist eine Serviceklasse und hat keine Beziehung zum View-Controller mit dem UILabel, aber ich möchte trotzdem, dass diese Serviceklasse das Label aktualisieren kann.Update UILabel von einer anderen Klasse (ohne Bezug zum View-Controller)
Ich glaube, dass this Antwort war, was ich brauchte, aber es funktioniert nicht für Swift 3 und der Text, den die Beschriftung ändert, ist hardcodiert, was nicht das ist, was ich auch wollte. Ich konnte nichts anderes dazu finden.
BTService.swift:
import Foundation
import CoreBluetooth
let BLEServiceUUID = CBUUID(string: "025A7775-49AA-42BD-BBDB-E2AE77782966")
let PositionCharUUID = CBUUID(string: "A9CD2F86-8661-4EB1-B132-367A3434BC90") //RX let
let WriteCharUUID = CBUUID(string: "F38A2C23-BC54-40FC-BED0-60EDDA139F47") //TX let F38A2C23-BC54-40FC-BED0-60EDDA139F47
let BLEServiceChangedStatusNotification = "kBLEServiceChangedStatusNotification"
class BTService: NSObject, CBPeripheralDelegate {
var peripheral: CBPeripheral?
var positionCharacteristic: CBCharacteristic?
var writeCharacteristic: CBCharacteristic?
init(initWithPeripheral peripheral: CBPeripheral) {
super.init()
self.peripheral = peripheral
self.peripheral?.delegate = self
}
deinit{
self.reset()
}
func startDiscoveringServices() {
self.peripheral?.discoverServices([BLEServiceUUID])
}
func reset() {
if peripheral != nil {
peripheral = nil
}
// Deallocating therefore send notification
self.sendBTServiceNotificationWithIsBluetoothConnected(false)
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
let uuidsForBTService: [CBUUID] = [PositionCharUUID]
let uuidsForBTService1: [CBUUID] = [WriteCharUUID]
if (peripheral != self.peripheral) { // Wrong Peripheral
return
}
if (error != nil) {
return
}
if ((peripheral.services == nil) || (peripheral.services?.count == 0)) {
// No Services
return
}
for service in peripheral.services! {
if service.uuid == BLEServiceUUID {
peripheral.discoverCharacteristics(uuidsForBTService, for: service
)
peripheral.discoverCharacteristics(uuidsForBTService1, for: service)
} }
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
if (peripheral != self.peripheral) { // Wrong Peripheral
return }
if (error != nil) {
return
}
for characteristic in service.characteristics! { if characteristic.uuid == PositionCharUUID {
self.positionCharacteristic = (characteristic)
peripheral.setNotifyValue(true, for: characteristic)
self.sendBTServiceNotificationWithIsBluetoothConnected(true)
}
else if characteristic.uuid == WriteCharUUID {
self.writeCharacteristic = (characteristic)
peripheral.setNotifyValue(true, for: characteristic)
self.sendBTServiceNotificationWithIsBluetoothConnected(true)
}
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?){
let it = NSString(data: characteristic.value!, encoding: String.Encoding.utf8.rawValue)
if(it != nil){
print("Val: \(it)") //Stackoverflow: This is what needs to be sent to the ViewController to be updated!!!
}
}
func writePosition(position: UInt8) {
if self.writeCharacteristic == nil {
return
}
var positionValue = position
let data = NSData(bytes: &positionValue, length: MemoryLayout<UInt8>.size)
self.peripheral?.writeValue(data as Data, for: self.writeCharacteristic!, type: CBCharacteristicWriteType.withResponse)
}
func readPosition() -> NSString? {
if self.positionCharacteristic == nil {
return nil }
self.peripheral?.readValue(for: self.positionCharacteristic!)
if ((self.positionCharacteristic?.value) != nil) {
print(self.positionCharacteristic!.value!)
return NSString(data: self.positionCharacteristic!.value!, encoding:
String.Encoding.utf8.rawValue) }
return nil
}
func sendBTServiceNotificationWithIsBluetoothConnected(_ isBluetoothConnected: Bool) {
let connectionDetails = ["isConnected": isBluetoothConnected]
NotificationCenter.default.post(name: Notification.Name(rawValue: BLEServiceChangedStatusNotification), object: self, userInfo: connectionDetails)
}
}
Der Viewcontroller:
import UIKit
import AVFoundation
class ViewController: UIViewController {
@IBOutlet weak var imgBluetoothStatus: UIImageView!
@IBOutlet weak var positionSlider: UISlider!
@IBOutlet weak var BottomLabel: UILabel!
var timerTXDelay: Timer?
var allowTX = true
var lastPosition: UInt8 = 255
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Rotate slider to vertical position
// Watch Bluetooth connection
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.connectionChanged(_:)), name: NSNotification.Name(rawValue: BLEServiceChangedStatusNotification), object: nil)
// Start the Bluetooth discovery process
_ = btDiscoverySharedInstance
}
deinit {
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: BLEServiceChangedStatusNotification), object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.stopTimerTXDelay()
}
@IBAction func positionSliderChanged(_ sender: UISlider) {
self.sendPosition(UInt8(sender.value))
}
func connectionChanged(_ notification: Notification) {
// Connection status changed. Indicate on GUI.
let userInfo = (notification as NSNotification).userInfo as! [String: Bool]
DispatchQueue.main.async(execute: {
// Set image based on connection status
if let isConnected: Bool = userInfo["isConnected"] {
if isConnected {
self.imgBluetoothStatus.image = UIImage(named: "Bluetooth_Connected")
// Send current slider position
self.sendPosition(UInt8(self.positionSlider.value))
} else {
self.imgBluetoothStatus.image = UIImage(named: "Bluetooth_Disconnected")
}
}
});
}
func sendPosition(_ position: UInt8) {
// Valid position range: 0 to 180
if !allowTX {
return
}
// Validate value
if position == lastPosition {
return
}
else if ((position < 0) || (position > 180)) {
return
}
// Send position to BLE Shield (if service exists and is connected)
if let bleService = btDiscoverySharedInstance.bleService {
bleService.writePosition(position: position)
lastPosition = position;
// Start delay timer
allowTX = false
if timerTXDelay == nil {
timerTXDelay = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(ViewController.timerTXDelayElapsed), userInfo: nil, repeats: false)
}
}
}
func timerTXDelayElapsed() {
self.allowTX = true
self.stopTimerTXDelay()
// Send current slider position
self.sendPosition(UInt8(self.positionSlider.value))
}
func stopTimerTXDelay() {
if self.timerTXDelay == nil {
return
}
timerTXDelay?.invalidate()
self.timerTXDelay = nil
}
}
Im BTService gibt es eine didUpdateValueFor
Funktion und ich würde die it
Variable wie zum Viewcontroller gesendet werden und es haben als BottomLabel festgelegt.
@JoeBlow Die Datei ist "BTService.swift" – Matt
Wie liest du diese "Servicedatei"? Ist das eine statische Datei, etwas periodisch aktualisiert oder sehr dynamisch? Es sollte ziemlich einfach sein, eine Datei in eine Zeichenkette zu lesen, aber ohne weitere Details ist es schwer, ihnen zu helfen. Welchen Code hast du ausprobiert? Das wäre auch hilfreich. Wie eine andere Person fragt - bitte poste mehr Code. Vielen Dank. – dfd
@dfd Ich habe meine Frage mit Code und einer besseren Erklärung aktualisiert – Matt