如何用这个 [Swift] 的类制作出像样的代码



我正在制作一个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类,其中存储了所有可能的消息,并形成了我想要组装要发送的数据和所有当前设置的形式(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 中的所有更改和操作。(菜单项.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类是在AE20125控制器类中启动的?这也适用于 MenuItems 类,当按下 updateFreq 按钮时,应该调用 DataProcessor 类中的方法 setData,但我需要启动它。

老实说,我不知道我在做什么,如何正确使用这个系统,以便一切正常,而无需将所有内容放在一个文件中,以便我可以保持井井有条。同样,我是编程新手,但是(如果我自己可以这么说的话)我确实有一些编程知识。请帮助我组织我的(蹩脚的)代码,并给我一些提示,说明如何在将来的事情中避免这种情况。

(如果你知道一个好的高级 Swift OSX 编程指南/课程,请告诉我。(它不一定是免费的))

提前致谢

在应用中不同部分之间进行通信的一种方法是使用 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(...)

最新更新