2016-03-01 54 views
0

这个类的体面代码我正在制作一个OSX应用程序来控制串行设备,为此我使用ORSSerialPort库。但是我在编码方面遇到了一些麻烦。我对编码非常陌生,并且我不知道如何正确编写代码,这在尝试创建某些工作时会导致一些问题。我会展示我的三个'班',我会描述他们的功能,然后描述我遇到的问题。如何让这些[[Swift]

主类中,向其中库委托被连接并从其中我做与串行设备(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.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方法,但我需要启动它。老实说,我不知道我在做什么,如何正确地使用这个系统,以便一切正常,没有把所有东西放在一个文件中,这样我就可以保持它的组织。再次,我是编程新手,但是(如果我可以自己这样说),我对编程有一定的了解。请帮助我组织我的(糟糕的)代码,并提供一些有关如何避免这种情况的提示。

(如果你知道一个好的高级斯威夫特OSX编程指南/课程,请告诉我。(它并不必须是免费的))提前

感谢

回答

-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(...) 
+0

如何任何解释?如示例 – sloeberGJ

+0

NSNotificationCenter可能不是正确的选择。例如:https://davidnix.io/post/stop-using-nsnotificationcenter/ –

+1

您可能是对的,我用更好的方式编辑了我的帖子。 –