Function builder in Swift

Tram Ho

  • Function buidler is the most popular feature since its release with SwiftUI in Swift 5.1 . It is immediately an important part of SwiftUI implementation while it has not been fully developed by Apple .
  • In this article we will take a closer look at this function buidler to see how it benefits us in implementing code in SwiftUI .
  • Note: We need to make it clear to each other that the function buidler was introduced in Swift 5.1 . Using the Function buidler in a production environment depends largely on what Swift version the project you are developing is supporting to use. Make sure the Swift version of the project you are developing before applying the function buidler .

1: Setting:

  • The best way for me to learn how the Swift feature works is to practice some example code so we will need an example with the full set of setting , we will use Setting as follows:

  • We use the associated type for the values of enum to ensure for the instance setting will have full type different.
  • Through group we can create nested setting like this:

2: Use the builder for the function:

  • The core of the Function builder in Swift is to help build the content in the function into single value values. In SwiftUI we use on the transform of the content of one or more container ( HStack or VStack ) in a view using type(of:) :

  • SwiftUI uses different function in implementations such as ViewBuilder and SceneBuilder . But since we cannot refer to the source code for these type , we will build Function buidler for the settings in this API :
  • Like the property-wrappers-in-swift feature , a function buidler will take care of implement normal Swift is introduced with the @_functionBuilder syntax. Special method have been used to implement Function Builder work case . We refer to how to use the following buildBlock :

  • The above return type in the function ([Setting]) must specify additional type that the builder can use. We’ll choose to implement API as a global function to use the SettingsBuilder for any closure passed to:

  • With the above code we can call makeSettings with an empty trailing closure and get an empty array :

  • Our new API is not really useful yet, it just shows us a few of its capabilities and how it works Function Builder . We’ll take a closer look at the next section:

3: Build the values:

  • To enable our SettingsBuilder to accept input our job is to declare additional buildBlock with the argument match the input for the result we want to receive. We will implement a method with list of value Setting and return an array :

  • With the newly declared buildBlock , we’ll let the fill makeSettings call the Setting makeSettings and the function builder will integrate for the makeSettings in the array and return :

  • We’ve made a slight improvement here, so let’s get back to SwiftUI and add function builder with a powerful ability in group definition work. We will need to add a type SettingGroup have annotates is @SettingsBuilder to connect to function buidler :

  • How to implement the above allows us to define group in the same way we define the setting by connecting each Setting with closure as follows:

  • If we insist on using the makeSettings closure then we get an error because the method function builder will be waiting for a lot of Setting values ​​and SettingGroup new SettingGroup is of a completely different type .
  • To handle the above error we need to add prototol that can be shared between Setting and SettingGroup :

  • The next thing to do is modify the function buidler buildBlock function buidler to accept the SettingsConvertible are initialized rather than using the value that Setting are returned via map :

  • We now have the means to fully utilize the SwiftUI functionality supported by setting the group as follows:

4: Conditions for using Function Builder:

  • We can add conditional to aid in using the Function Builder . Swift itself supports all types of conditional we need to use, but in case with SettingsBuilder currently implement we will get an error if we try to do the following:

  • The above code shows us how the executed of the annotated function builder not executed in the same way as we normally use because the processing processes need to be explicitly defined by the builder including conditional as if statement :
  • We need to add statement to sort and handle the problem. We have one more method introduced in the API called buidlIf . Its effect is to map each if statement :

  • if statement above should now work exactly as we expected, but we still need to add more if/else so we can append the method buildEither with argument matching the if/else statement :

  • We add else to our first if statement from before so we have an example of user request for setting that weren’t shown before:

  • Until Swift 5.3 , the method buildEither was supported with the swift statement to be used for the build context without the need for additional build method .
  • We’ll try to refine the above code a little more for the shouldShowExperimental variable in the enum by supporting access multiple levels. We can simply switch back and forth in the enum with the makeSettings closure and the compiler will automatically pass the method buildEither :

  • One additional note is that the type Setting.Empty for each switch statement in the case`.restricted case will probably need to use additional break keywork with the function builder using the switch statement . Like using EmptyView in SwiftUI , the new Setting API have added Setting.Empty for this case:

Share the news now

Source : Viblo