Swift 具有多个 NSDateFormatter 的代码 - 优化

Swift code with multiple NSDateFormatter - optimization

出于 swift 学习目的,我正在从事个人核心数据项目。到目前为止一切正常,但我不知道如何优化代码。优化我的意思只是视觉优化,性能是不同的故事,对我来说还为时过早。 在下面的 class 中,我经常使用 dateFormatter,所以我尽量避免使用它。似乎我错过了编程中的一些基本知识,这对于绝对的初学者和业余爱好者来说并不奇怪。

import UIKit
import CoreData

class AddEditViewController: UIViewController {

    @IBOutlet weak var startDateTextField: UITextField!
    @IBOutlet weak var endDateTextField: UITextField!
    @IBOutlet weak var shipNameTextField: UITextField!
    @IBOutlet weak var positionOnBoardTextField: UITextField!
    @IBOutlet weak var workingDaysLabel: UILabel!

    var startDatePassedFromTable: NSDate!
    var endDatePassedFromTable: NSDate!
    var shipNamePassedFromTable: String!
    var positionOnBoardPassedFromTable: String!
    var workingDaysPassedFromTable: Int!

    var exsistingContract: NSManagedObject!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Load the view with the data passed from the table
        if (exsistingContract != nil) {

            self.title = "Edit Contract"

            var dateFormatter = NSDateFormatter()
            dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
            dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
            dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT+0:00")
            dateFormatter.dateFormat = "dd-MM-yyyy"

            startDateTextField.text = dateFormatter.stringFromDate(startDatePassedFromTable)
            endDateTextField.text = dateFormatter.stringFromDate(endDatePassedFromTable)
            shipNameTextField.text = shipNamePassedFromTable
            positionOnBoardTextField.text = positionOnBoardPassedFromTable
            workingDaysLabel.text = "\(workingDaysPassedFromTable)"

        } else {
            self.title = "Add Contract"
        }
    }

    // Start Date Text Field- action and format for DatePicker
    @IBAction func startDateTextFieldEditing(sender: UITextField) {
        var datePickerView:UIDatePicker = UIDatePicker()
        datePickerView.datePickerMode = UIDatePickerMode.Date
        sender.inputView = datePickerView
        datePickerView.addTarget(self, action: Selector("startDatePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)
    }

    func startDatePickerValueChanged(sender: UIDatePicker) {
        var dateformatter = NSDateFormatter()
        dateformatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
        dateformatter.dateStyle = NSDateFormatterStyle.MediumStyle
        dateformatter.dateFormat = "dd-MM-yyyy"
        startDateTextField.text = dateformatter.stringFromDate(sender.date)

        return calculateWorkingDays()
    }

    // End Date Text Field - action and format for DatePicker
    @IBAction func endDateTextFieldEditing(sender: UITextField) {
        var datePickerView:UIDatePicker = UIDatePicker()
        datePickerView.datePickerMode = UIDatePickerMode.Date
        sender.inputView = datePickerView
        datePickerView.addTarget(self, action: Selector("endDatePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)
    }

    func endDatePickerValueChanged(sender: UIDatePicker) {
        var dateformatter = NSDateFormatter()
        dateformatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
        dateformatter.dateStyle = NSDateFormatterStyle.MediumStyle
        dateformatter.dateFormat = "dd-MM-yyyy"
        endDateTextField.text = dateformatter.stringFromDate(sender.date)

        return calculateWorkingDays()
    }

    // Hide keyboard or DatePicker
    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        self.view.endEditing(true)
    }

    // Calculate the working days from String -> NSDate of startDateTextField and endDateTextField
    func calculateWorkingDays() {

        // Check if the startDateTextField AND endDateTextField are not empty
        if !startDateTextField.text.isEmpty && !endDateTextField.text.isEmpty {

            // Date format and localisation
            let calendar = NSCalendar.currentCalendar()
            let unit: NSCalendarUnit = .CalendarUnitDay
            var dateFormatter = NSDateFormatter()
            dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
            dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT+0:00")
            dateFormatter.dateFormat = "dd-MM-yyyy"
            let startDatePicker: NSDate = dateFormatter.dateFromString(startDateTextField.text)!
            let endDatePicker: NSDate = dateFormatter.dateFromString(endDateTextField.text)!

            // Calculate the diference and set the workingDays Label to Days -> String from Int + 1
            let components = calendar.components(unit, fromDate: startDatePicker, toDate: endDatePicker, options: nil)
            workingDaysLabel.text = "\(components.day + 1)"
        }
    }

    @IBAction func buttonSavePressed(sender: UIBarButtonItem) {
        // Check for empty TextField
        if startDateTextField.text.isEmpty || endDateTextField.text.isEmpty || shipNameTextField.text.isEmpty || positionOnBoardTextField.text.isEmpty {
            // Allert message with OK button
            let alertController = UIAlertController(title: "Error Save Contract", message: "Start and End Date are required", preferredStyle: UIAlertControllerStyle.Alert)
            let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel, handler: nil)
            alertController.addAction(okAction)
            presentViewController(alertController, animated: true, completion: nil)

        } else {
            // Save data and return to the root controller
            // Check if contract is exsisting and EDIT or NEW for save new contract
            var appDelegate: AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
            var context: NSManagedObjectContext = appDelegate.managedObjectContext!
            let entity = NSEntityDescription.entityForName("Contract", inManagedObjectContext: context)!

            var dateFormatter = NSDateFormatter()
            dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
            dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT+0:00")
            dateFormatter.dateFormat = "dd-MM-yyyy"

            // Check if contract exsist
            if (exsistingContract != nil) {

                // Edit exsisting contract
                exsistingContract.setValue((dateFormatter.dateFromString(startDateTextField.text)), forKey: "startdate")
                exsistingContract.setValue((dateFormatter.dateFromString(endDateTextField.text)), forKey: "enddate")
                exsistingContract.setValue(shipNameTextField.text, forKey: "ship")
                exsistingContract.setValue(positionOnBoardTextField.text, forKey: "position")
                exsistingContract.setValue(workingDaysLabel.text?.toInt(), forKey: "workingdays")

            } else {

                // Create new contract
                var newContractData = Contract(entity: entity, insertIntoManagedObjectContext: context)
                newContractData.startdate = dateFormatter.dateFromString(startDateTextField.text)!
                newContractData.enddate = dateFormatter.dateFromString(endDateTextField.text)!
                newContractData.ship = shipNameTextField.text
                newContractData.position = positionOnBoardTextField.text
                newContractData.workingdays = workingDaysLabel.text!.toInt()!

            }

            // Save and return to root
            context.save(nil)
            self.navigationController?.popToRootViewControllerAnimated(true)

        }

    }

    @IBAction func cancelButtonPressed(sender: UIBarButtonItem) {
        self.navigationController?.popToRootViewControllerAnimated(true)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

您只能在 NSDateFormatter 上创建一个实例并在需要的地方使用它:

lazy var dateFormatter: NSDateFormatter = {
    let f = NSDateFormatter()
    f.locale = NSLocale(localeIdentifier: "en_US_POSIX")
    f.timeZone = NSTimeZone(abbreviation: "GMT+0:00")
    f.dateFormat = "dd-MM-yyyy"
    return f
}()

你也可以创建一个单例并在你需要的地方使用它:

import UIKit

class Dater: DateFormatter {

    static var shared = Dater()

    private override init() {
        super.init()
        self.locale = NSLocale(localeIdentifier: "en_US") as Locale!
    }

    func date(from string: String, format: String) -> Date? {
        self.dateFormat = format
        return date(from: string)
    }

    func string(from date: Date, format: String) -> String? {
        self.dateFormat = format
        return string(from: date)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

你可以这样使用它:

Dater.shared.string(from: Date(), format: "MM/dd/yyyy")

Dater.shared.date(from: "14/02/2012", format: "MM/dd/yyyy")