0

ORSSerialPort ライブラリを使用しているシリアル経由でデバイスを制御する OSX アプリを作成しています。しかし、コーディングにはいくつかの問題があります。私はコーディングが初めてで、適切にコーディングする方法がわからないため、何かを機能させようとすると問題が発生します。3 つの「クラス」を示し、それらの機能と、遭遇した問題について説明します。

ライブラリデリゲートが接続され、シリアルデバイスとのすべての通信を行うメインクラス (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)

    }
}

GUI でのすべての変更とアクションを処理する menuItems クラス。(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 が呼び出されるはずですが、それを開始する必要があります。

正直なところ、私は自分が何をしているのか、このシステムを適切に機能させる方法がわからないので、すべてを 1 つのファイルにまとめずに、整理しておくことができます。繰り返しますが、私はプログラミングは初めてですが、(自分でそう言うかもしれませんが)プログラミングの知識はある程度あります。私の(くだらない)コードを整理するのを手伝ってください。また、今後これを回避する方法についてのヒントを教えてください。

(良い Advanced Swift OSX プログラミング ガイド/コースを知っている場合は、教えてください。(無料である必要はありません))

前もって感謝します

4

1 に答える 1