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.
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
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
