• Good Swift, Bad Swift — Part 2
  • Kristian Andersen
  • The Nuggets translation Project
  • Translator: Zheaoli
  • Proofread by: Owenlyn, Yifili09

Not long ago, in my article Good and Bad, Swift Parts 1, I covered some tips on how to write good code in Swift. In the two years since Swift was released, IT has taken me a long time to get a firm grasp of best practices. For more information, see this article: good and bad, Swift looks at Part1.

In this series of articles, I’ll try to dissect what I think is good and bad about the Swift language. Well, I also hope to have a good Swift to help me conquer Swift in the future (well, young man, don’t look at it, the center has decided it’s you, quick read two lines of poetry). If you have any thoughts, or if you want to tell me something about your life as a developer, please contact me on Twitter at Ksmandersen.

Well, without further ado, let’s begin today’s lesson.

guardDafa good, intoguardBe safe

In Swift 2.0, Swift has added a new set of features that are a little unfamiliar to developers. The Guard statement comes in handy for defensive programming. Defensive programming is a form of Defensive design designed to ensure that any unforeseen use of a program will not cause functional damage. It can be seen as an idea to reduce or eliminate the effect of Murphy’s Law. Defensive programming is primarily used for programs that can be misused, mischievous, or unintentionally disastrous. From Wikipedia). Every Objective-C developer is probably familiar with defensive programming. By using this technique, you can be sure in advance that your code will not fail to handle unexpected input data.

The Guard statement allows you to set conditions and rules for the rest of the code, and of course you must specify what to do if the conditions (or rules) are not met. In addition, guard statements must return a value. In early Swift programming, you might have used if-else statements to preprocess these cases. However, if you use guard statements, the compiler will handle exception data for you if you don’t think about it.

The following example is a bit long, but it’s a good example of guard in action. The didPressLogIn function is called when the button on the screen is clicked. We expect this function to be called without generating additional logs if the program makes additional requests. Therefore, we need to do some work on the code ahead of time. Then we need to validate the log. If the log is not what we need, then we do not need to send the log. But more importantly, we need to return an executable statement to make sure we don’t send this log. Guard will throw an exception if we forget to return.

    @objc func didPressLogIn(sender: AnyObject?) {
            guard! isPerformingLogInelse { return }
            isPerformingLogIn = true

            let email = contentView.formView.emailField.text
            let password = contentView.formView.passwordField.text

            guard validateAndShowError(email, password: password) else {
                isPerformingLogIn = false
                return
            }

            sendLogInRequest(ail, password: password)
    }
Copy the code

Let works wonders when combined with guard. In the following example, we will bind the result of the request to a variable user, which is then used by the finishSignUp method function. If result.okValue is null, guard will take effect; if not, the value will be assigned to user. We restrict guard by using WHERE.

currentRequest? .getValue { [weak self] result in
      guard let user = result.okValue where result.errorValue == nil else {
        self? .showRequestError(result.errorValue)self? .isPerformingSignUp =false
        return
      }

      self? .finishSignUp(user) }Copy the code

To be fair, guard is very powerful. Well, if you haven’t already, you should really think twice.

In the use ofsubviewsDeclare and configure at the same time.

As mentioned in the previous series of articles, WHEN I was developing Viwe, I was more used to code generation. Because I am very familiar with the configuration routine of view, I can always quickly locate the wrong place when there are layout problems or improper configuration problems.

During development, I found it important to keep the different configuration processes together. In my early Swift programming experiences, I used to declare a configureView function and then put the configuration process there during initialization. But in Swift we can configure a view with a property declaration block (actually I don’t know what this thing is called hula).

Well, in this example, there is an AwesomeView that contains two subviews, bestTitleLabel, and otherTitleLabel. Both subviews are configured in one place. We integrate the configuration process into the configureView method. So, if I want to change the textColor property of a label, I know exactly where to go.

    cclass AwesomeView: GenericView {
        let bestTitleLabel = UILabel().then {
            $0.textAlignment = .Center
            $0.textColor = .purpleColor()tww
        }

        let otherTitleLabel = UILabel().then {
            $0.textAlignment = .
            $0.textColor = .greenColor()
        }

        override func configureView(a) {
            super.configureView()

            addSubview(bestTitleLabel)
            addSubview(otherTitleLabel)

            // Configure constraints}}Copy the code

One thing I don’t like about the above code is the type label that is declared with the label and then initialized in the code block to return the value. By using the Then library, we can make a slight improvement. You can use this little function to associate code blocks with object declarations in your projects. This reduces the number of duplicate declarations.

    class AwesomeView: GenericView {
        let bestTitleLabel = UILabel().then {
            $0.textAlignment = .Center
            $0.textColor = .purpleColor()tww
        }

        let otherTitleLabel = UILabel().then {
            $0.textAlignment = .
            $0.textColor = .greenColor()
        }

        override func configureView(a) {
            super.configureView()

            addSubview(bestTitleLabel)
            addSubview(otherTitleLabel)

            // Configure constraints}}Copy the code

Class members are classified by different access levels.

Well, one of the most important things that happened to me recently was that I used a special way to combine the members of a class and a structure. This is a habit I picked up when I was developing in Objective-C. I usually put the private methods at the bottom and the public and initialization methods in the middle. The properties are then placed at the top of the code in the order from public to private. Well, you can organize your code as follows.

  • Public attribute
  • Inline attribute
  • Private property
  • Initialize the container
  • Public methods
  • Inline methods
  • Private methods

You can also sort by static/class attributes/fixed values. Maybe different people will add different things to it. But for me, I’m always programming the same way.

Well, that’s the end of this programme. If you have any good ideas or anything you want to say, please feel free to contact me through the contact information at the bottom of the screen. Of course you are welcome to throw a coin, throw a banana tip and subscribe to my article (fog).

Next time: will continue to talk about Swift dribs and drabs, don’t go away, the next time is more exciting.

About Climbing the Wall (Hard wide)

This is just a friendship recommendation, I am using a aes, ipv4, ipv6 line full coverage, well, the webmaster is also very nice, basic your reasonable needs, the webmaster can meet. I suggest you try.