0

我正在制作一个 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 编程指南/课程,请告诉我。(它不一定是免费的))

提前致谢

4

1 回答 1

-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(...)
于 2016-03-01T19:48:34.710 回答