Writing reusable Swift extensions

Tram Ho

  • Swift one of Swift ‘s most powerful and most used features allows us to extend and develop new protocol and function . Not only do we adjust the language and library to suit different projects, we also have the opportunity to write extensions that can be reused across a variety of use cases and projects.
  • In this article let’s study this issue as well as the principles to be able to memorize the overview of the extension so that it can be used in many different contexts.

1 / Generalizing through abstractions:

  • For example, we will study the case when we need to improve performance, we write function that allow us to easily store articles on the hard drive:

  • Expanding the specific type with the above extension can be a good way to reduce code duplication while making it easier to perform normal tasks on source code. However, sometimes an extension also makes the code less flexible and more detached. In this case, it is likely that we will not only store Article but also other model .
  • Let’s study to improve the reusable extension :
    • Encode each value in JSON , we need any type that can be used in compliance with the library Encodable protocol .
    • We also need to match the id with type same type so that the unique file name can be calculated.
  • To accomplish the above two requirements we use Encodable and add a generic type constraint to specify our cache method that can be called on Identifiable , providing us with the id attribute we need:

2 / Define the correct protocol:

  • We rewrite the Article extension , this time we use the Result type to allow the result instance to carry an Article array so that it can be combined with an instance same type:

  • As with the caching method above, there is no requirement from the above code to know about Article . In this case, we need to combine 2 collection RangeReplaceableCollection into one with RangeReplaceableCollection .

3 / Avoid conflic and type polutiton:

  • In case we build a storage place for frameworks, we can allow different projects to save and account values ​​using Container . We define the DataConvertible protocol so that we can create several system types as follows:

  • The above approach can work well with an independent project, but if we are going to share this functionality with multiple projects, then perhaps these problems become cumbersome and cumbersome.
  • Because we have defined required property as data , there may be times when it will overlap with other definitions. The same is true for protocols that have generic names like DataConvertible . While the module name can use ModuleName.TypeName , attribute name cannot be used this way.
  • A good solution to this type of problem is to eliminate the protocol and add type-specific to the Container :

  • The above approach works well with a variety of type – what we want. The difficulty occurs when we want to add more configuration options and parameters to the API container .
  • For example we want to be licensed for the API of the user to specify the level of sustainability of use when using value somehow.

  • Our previous problem is that our protocol is prone to conflict with naming rules, to handle this we use a slightly more lengthy naming convention. Let’s also implement a function for the protocol that can avoid changes when converting UIImage to Data :

  • With the change on our extension will avoid making mistakes when reused in different projects. Let’s return to the problem of a Container with a write method that can handle any ContainerDataConvertible :

  • There is still a problem to solve, we need to define more static function protocol to make it easier to implement instead of adding every instance :

  • The above code allows us to change each write function without adding any complex instances, now we simply call makeContainerData directly on each value :

Share the news now

Source : Viblo