DEV Community

Cover image for Swift: Associated types. Example.
Sergey Leschev
Sergey Leschev

Posted on

 

Swift: Associated types. Example.

The defined colors had to be available for both UIColor in UIKit and Color in SwiftUI. Obviously, we did not want to define all colors twice as that would be hard to maintain and result in a lot of duplicate code.

We already had a convenient way of defining colors using a custom convenience initializer on UIColor that takes a hexadecimal input:

let color = UIColor(hex: "FF7217")
Enter fullscreen mode Exit fullscreen mode

We decided to reuse that method and define a protocol around it:

public protocol BrandColorSupporting {
    associatedtype ColorValue
    static func colorFor(hex: String, alpha: CGFloat) -> ColorValue
}
Enter fullscreen mode Exit fullscreen mode

Some colors also required to be defined with a specific alpha value which we included in this protocol too. We then added support for this protocol for both UIColor and Color:

extension UIColor: BrandColorSupporting {
    public static func colorFor(hex: String, alpha: CGFloat) -> UIColor {
        return UIColor(hex: hex).withAlphaComponent(alpha)
    }
}

@available(iOS 13.0, *)
extension Color: BrandColorSupporting {
    public static func colorFor(hex: String, alpha: CGFloat) -> Color {
        return Color(UIColor.colorFor(hex: hex, alpha: alpha))
    }
}
Enter fullscreen mode Exit fullscreen mode

As you can see, we reuse the logic of UIColor in our Color protocol adoption. This allowed us to reuse the convenience initializer of UIColor to create colors using a hexadecimal value.

As not all colors required to define an alpha component we added a default extension to our BrandColorSupporting protocol:

extension BrandColorSupporting {
    static func colorFor(hex: String) -> ColorValue {
        return colorFor(hex: hex, alpha: 1.0)
    }
}
Enter fullscreen mode Exit fullscreen mode

Defining static colors

Both UIColor and Color now conform to the BrandColorSupporting protocol which means that we can define extensions that become available to both.

We started defining colors:

public extension BrandColorSupporting {

    static var orangeCollectHero: ColorValue {
        colorFor(hex: "FF7217")
    }
}
Enter fullscreen mode Exit fullscreen mode

The best thing of using associated types is that we can make use of the same logic while the result type is changed based on context:

let colorForSwiftUI: Color = Color.orangeCollectHero
let colorForUIKit: UIColor = UIColor.orangeCollectHero
Enter fullscreen mode Exit fullscreen mode

As you can imagine this is a great way to work with brand colors.


Associated types in Swift Protocols.
Declaration
Example
Contraints
Conforming a protocol to a protocol


Contacts
I have a clear focus on time-to-market and don't prioritize technical debt. And I took part in the Pre-Sale/RFX activity as a System Architect, assessment efforts for Mobile (iOS-Swift, Android-Kotlin), Frontend (React-TypeScript) and Backend (NodeJS-.NET-PHP-Kafka-SQL-NoSQL). And I also formed the work of Pre-Sale as a CTO from Opportunity to Proposal via knowledge transfer to Successful Delivery.

๐Ÿ›ฉ๏ธ #startups #management #cto #swift #typescript #database
๐Ÿ“ง Email: sergey.leschev@gmail.com
๐Ÿ‘‹ LinkedIn: https://www.linkedin.com/in/sergeyleschev/
๐Ÿ‘‹ LeetCode: https://leetcode.com/sergeyleschev/
๐Ÿ‘‹ Twitter: https://twitter.com/sergeyleschev
๐Ÿ‘‹ Github: https://github.com/sergeyleschev
๐ŸŒŽ Website: https://sergeyleschev.github.io
๐Ÿ–จ๏ธ PDF Design Patterns: Download

Top comments (0)

An Animated Guide to Node.js Event Loop

Node.js doesnโ€™t stop from running other operations because of Libuv, a C++ library responsible for the event loop and asynchronously handling tasks such as network requests, DNS resolution, file system operations, data encryption, etc.

What happens under the hood when Node.js works on tasks such as database queries? We will explore it by following this piece of code step by step.