我正在制作一个OSX应用来控制串口设备,我正在使用ORSSerialPort库。但我在编码方面遇到了一些麻烦。我(非常)对编码很新,我不知道如何正确编码,这在尝试使某些工作时会产生一些问题。我将展示我的三个“课程”,然后我会描述它们的功能,然后讨论我遇到的问题。
库代理连接到的主类,我从中与串行设备进行所有通信(AE20125Controller.swift)
import Cocoa
import ORSSerial
class AE20125Controller:NSObject, ORSSerialPortDelegate {
var buffer = String()
var dataProcessor = DataProcessor()
var availablePorts = ORSSerialPortManager.sharedSerialPortManager().availablePorts
@IBOutlet weak var selectedPort: NSPopUpButton!
@IBOutlet weak var connectButton: NSButton!
@IBOutlet weak var connectedLogo: NSStackView!
var serialPort: ORSSerialPort? {
didSet {
oldValue?.close()
oldValue?.delegate = nil
serialPort?.delegate = self
}
}
//Actions
@IBAction func onOpenOrClose(sender: AnyObject) {
if let port = self.serialPort {
if (port.open) {
closePort(port)
} else {
openPort(port)
}
}
}
//Functions
func sendData(command: String) -> Bool {
if let data = command.dataUsingEncoding(NSUTF8StringEncoding) {
self.serialPort?.sendData(data)
return true
}
return false
}
func closePort(port: ORSSerialPort){
port.close()
self.connectButton.title = "Verbinden"
self.connectedLogo.hidden = true
}
func openPort(port: ORSSerialPort){
port.baudRate = 9600
port.open()
sendData("201:T:0:;") //Gets all settings form the device
self.connectedLogo.hidden = false
self.connectButton.title = "Verbreken"
}
//Delegate
func serialPort(serialPort: ORSSerialPort, didReceiveData data: NSData) {
if let string = NSString(data: data, encoding: NSUTF8StringEncoding) {
var message: String
//Assemble the full data (Data come's in in parts)
buffer.appendContentsOf(string as String)
if(buffer.containsString(dataProcessor.endToken)){
let i = buffer.rangeOfString(dataProcessor.startToken)?.startIndex
let j = buffer.rangeOfString(dataProcessor.endToken)?.endIndex
if((i != nil) && (j != nil)){
message = buffer[Range(start: i!, end: j!)]
buffer.removeRange(Range(start: i!, end: j!))
if(message != "" /*message != "201:U:0:;"*/){
dataProcessor.sortIncomingData(message)
}
}
}
}
}
func serialPortWasRemovedFromSystem(serialPort: ORSSerialPort) {
serialPort.close()
}
}
数据处理器类,其中存储了所有可能的消息,并且我希望将其组合成发送数据和所有当前设置(DataProcessor.swift)
import Foundation
class DataProcessor {
enum dataType: String {
case frequency = "A"
case waveform = "B"
case mode = "C"
case pllReferenceEnabled = "D"
case pllFactor = "E"
case pllOffset = "F"
case startUpWavefrom = "G"
case startUpFrequency = "H"
case calibrationOffset = "I"
case sweepStartFrequency = "J"
case sweepStopFrequency = "K"
case sweepFrequency = "L"
case modulationType = "M"
case fskFrequency = "N"
case pskPhase = "O"
case modulationSource = "P"
case internalModulationFrequency = "Q"
case sweepMode = "R"
case getSettings = "T"
case keepAlive = "U"
case returnFromSweepMod = "V"
case hardwareRevison = "X"
case firmwareVersion = "Y"
case productID = "Z"
case present1Freq = "1"
case present1Waveform = "2"
case present2Freq = "3"
case present2Waveform = "4"
case present3Freq = "5"
case present3Waveform = "6"
case present4Freq = "7"
case present4Waveform = "8"
case present5Freq = "9"
case present5Waveform = "0"
func getWritable() -> Bool {
switch self {
case .frequency, .waveform, .mode, .pllReferenceEnabled, .pllFactor, .pllOffset, .startUpWavefrom, .startUpFrequency, .calibrationOffset, .sweepStartFrequency, .sweepStopFrequency, .sweepFrequency, .modulationType, .fskFrequency, .pskPhase, .modulationSource, .internalModulationFrequency,.sweepMode, .getSettings, .returnFromSweepMod, .present1Freq, .present1Waveform,.present2Freq,.present2Waveform, .present3Freq, .present3Waveform, .present4Freq, .present4Waveform, .present5Freq, .present5Waveform:
return true
default:
return false
}
}
func getReadable() -> Bool {
switch self {
case .frequency, .waveform, .mode, .pllReferenceEnabled, .pllFactor, .pllOffset, .startUpWavefrom, .startUpFrequency, .calibrationOffset, .sweepStartFrequency, .sweepStopFrequency, .sweepFrequency, .modulationType, .fskFrequency, .pskPhase, .modulationSource, .internalModulationFrequency, .sweepMode, .keepAlive, .hardwareRevison, .firmwareVersion, .productID:
return true
default:
return false
}
}
func getMaxValues() -> Int{
switch self {
case .frequency:
return 10000000
case .waveform:
return 3
case .mode:
return 3
case .pllReferenceEnabled:
return 2
case .pllFactor:
return 9999
case .pllOffset:
return 10000000
case .startUpWavefrom:
return 3
case .startUpFrequency:
return 10000000
case .calibrationOffset:
return 10000
case .sweepStartFrequency:
fallthrough
case .sweepStopFrequency:
return 10000000
case .sweepFrequency:
return 100
case .modulationType:
return 2
case .fskFrequency:
return 10000000
case .pskPhase:
return 3599
case .modulationSource:
return 2
case .internalModulationFrequency:
return 10000
case .sweepMode:
return 2
case .getSettings:
return 0
case .returnFromSweepMod, .present1Freq, .present2Freq, .present3Freq, .present4Freq, .present5Freq:
return 10000000
case .present1Waveform, .present2Waveform, .present3Waveform, .present4Waveform, .present5Waveform:
return 3
default:
return -1
}
}
}
let endToken = ":;"
let startToken = "201:"
var settings:[(dataType):(String)] = [:]
//Methodes
func sortIncomingData(data: String){
let i = data.rangeOfString(startToken)?.endIndex
let j = data.rangeOfString(endToken)?.startIndex
let sortedCode = data.substringWithRange(Range(start: i!, end: i!.advancedBy(1)))
let sortedData = data.substringWithRange(Range(start: i!.advancedBy(2), end: j! ))
settings[dataType(rawValue: sortedCode)!] = sortedData
}
func setData(data: dataType, value: Float){
settings.updateValue(String(value), forKey: data)
AE20125Controller.sendData(...) //<-- Is not working (Ignore the dots)
}
}
menuItems类,它应该处理GUI中的所有更改和操作。 (MenuItems.swift)
import Cocoa
class MenuItems:NSObject{
@IBOutlet weak var freqView: NSView!
@IBOutlet weak var test: NSTextField!
//Actions
@IBAction func setFreq(sender: AnyObject) {
}
}
我遗漏了AppDelegate,因为它没有任何内容,但是用于构建视图的设置(例如,将视图的背景更改为白色)。
我无法在类之间进行通信,例如我需要使用DataProcessor类中的AE20125Controller类中的sendData方法发送数据,但我需要启动它。但是DataProcessor类是在AE20125Controller类中启动的吗?这也适用于MenuItems类,当按下updateFreq按钮时,应调用DataProcessor类中的方法setData,但我需要启动它。
说实话,我不知道我在做什么,如何正确使用这个系统,以便一切正常,而不是将所有内容都放在一个文件中,这样我就可以保持整洁。再一次,我是编程的新手,但是(如果我可以这样说的话)我确实对编程有一定的了解。请帮我组织我的(糟糕的)代码并给我一些提示,告诉我将来如何避免这种情况。
(如果你知道一个好的高级Swift OSX编程指南/课程,请告诉我。(它不一定是免费的))
提前致谢
答案 0 :(得分:-1)
应用程序中不同部分之间的通信方式是使用NSNotificationCenter。点击此处查看文档: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/
编辑:在这种情况下,我建议为你的沟通制作一个单身人士:
class Communicator:NSObject, ORSSerialPortDelegate {
class let sharedInstance = Communicator()
}
所以你可以打电话:
Communicator.sharedInstance.sendData(...)