Mobile Development 16 min read

Swift Protocols and Associated Types

This article explains Swift protocols with associated types, discusses their limitations compared to plain protocols, demonstrates how to resolve related compile‑time errors through generic constraints, protocol composition, and associated‑type constraints, and provides practical code examples for customizing UITabBar items.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Swift Protocols and Associated Types

In Swift, both generics and protocols are core language features that enable flexible, reusable code. This article focuses on protocols that declare associated types (often called "associated protocols") and compares them with plain protocols.

Problem : When customizing UITabBar items, two concrete classes ( SNSTabBarItem and SNSTabBarLotItem) need a common interface for their label and image view, but the image view type differs (static UIImageView vs. animated HYLotSwitchView). A protocol with an associatedtype is introduced to abstract the image view type:

public protocol SNSTabBarItemProtocol {
    var itemLabel: UILabel! { get }
    associatedtype itemImageViewType: UIView
    var itemImageView: itemImageViewType! { get }
    // create UI elements
    func createElements(superView: UIView, position: CGRect, backgroundImage: UIImage?)
}

Attempting to cast a tab‑bar item to this protocol triggers the compiler error "Protocol 'SNSTabBarItemProtocol' can only be used as a generic constraint because it has Self or associated type requirements" , because protocols with associated types cannot be used as existential types.

Limitations of Associated Protocols

They must be used as generic constraints, requiring a generic redesign of the surrounding code.

Using them removes dynamic dispatch; you can no longer store heterogeneous conforming types in a single collection.

The article illustrates these points with simple examples, showing how a plain protocol works as a type, while adding an associatedtype forces the protocol to be used only in generic contexts.

Relationship Between Associated Protocols and Generics

From the outside, an associated protocol behaves similarly to a generic parameter, but internally it provides a placeholder type that can be constrained or given a default. The article compares a protocol with an associated type to a generic struct and discusses why Swift does not yet support true generic protocols.

Solutions

Protocol Composition (Combination Scheme)

Split the original protocol into two: one for required properties and one for required methods, then compose them:

public protocol SNSTabBarItemElements {
    var itemLabel: UILabel! { get }
    associatedtype itemImageViewType: UIView
    var itemImageView: itemImageViewType! { get }
}

public protocol SNSTabBarItemFunctions {
    func createElements(superView: UIView, position: CGRect, backgroundImage: UIImage?)
}

public protocol SNSTabBarItemProtocol: SNSTabBarItemElements & SNSTabBarItemFunctions {}

Now the iteration code can cast to SNSTabBarItemFunctions, avoiding the associated‑type restriction.

Generic Helper Function

Define a generic function that accepts any SNSTabBarItemProtocol conformer:

func loopElements<E: SNSTabBarItemProtocol>(item: E, superView: UIView, position: CGRect, backgroundImage: UIImage?) {
    item.createElements(superView: superView, position: position, backgroundImage: backgroundImage)
}

However, because the items array in UITabBar is typed as UITabBarItem, the generic function still cannot be called directly without further redesign.

Adding Constraints to Associated Types

The article shows how to constrain associated types (e.g., requiring Comparable), provide default types, and add default method implementations via extensions. Example:

protocol MySequence: Comparable {
    associatedtype Element: Comparable = Int
    var storage: [Element] { get set }
}

extension MySequence where Element == Int {
    func summed() -> Element {
        return storage.reduce(0, +)
    }
}

This demonstrates that constraints and default implementations can make associated‑type protocols more powerful while keeping the code concise.

Conclusion

The article concludes that using associated types in protocols provides a way to express sophisticated type relationships similar to generics, but it forces generic redesign and loses dynamic dispatch. Developers should weigh these trade‑offs and consider protocol composition or generic helper functions when appropriate.

References

Swift Protocols with Associated Types and Generics

知乎文章

Hacking with Swift – fixing the associated‑type error

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

iOSGenericsProtocolsSwiftAssociated TypesProtocol CompositionUITabBar
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.