This means Swift emphasizes the use of protocols as a fundamental way to structure and organize code, promoting flexibility and reusability. While Swift also supports object-oriented programming (OOP), POP is a core part of its design philosophy
Here’s a comprehensive set of practical examples demonstrating all key use cases for protocols in Swift, with complete implementations:
protocol PaymentMethod {
    func process(amount: Double)
}
class CreditCard: PaymentMethod {
    func process(amount: Double) {
        print("Charging ₹\(amount) to credit card")
    }
}
struct UPI: PaymentMethod {
    func process(amount: Double) {
        print("Processing UPI payment for ₹\(amount)")
    }
}
let payments: [PaymentMethod] = [CreditCard(), UPI()]
payments.forEach { $0.process(amount: 999) }
protocol Logger {
    func log(_ message: String)
}
class ConsoleLogger: Logger {
    func log(_ message: String) {
        print("[LOG] \(message)")
    }
}
class ApiService {
    private let logger: Logger
    
    init(logger: Logger = ConsoleLogger()) {
        self.logger = logger
    }
    
    func fetchData() {
        logger.log("Fetching data...")
    }
}
let service = ApiService()  // Uses ConsoleLogger by default
protocol Cacheable: Codable {
    var cacheKey: String { get }
}
struct UserProfile: Cacheable {
    let id: String
    var cacheKey: String { "user_\(id)" }
}
class CacheManager<T: Cacheable> {
    private var storage = [String: T]()
    
    func cache(_ item: T) {
        storage[item.cacheKey] = item
    }
}
protocol Tappable {
    func handleTap()
}
protocol Swipable {
    func handleSwipe()
}
class ImageView: Tappable, Swipable {
    func handleTap() { print("Image tapped") }
    func handleSwipe() { print("Image swiped") }
}
func configure(interactive: Tappable & Swipable) {
    interactive.handleTap()
}
protocol Renderable {
    func render()
}
extension Renderable {
    func render() {
        print("Default rendering logic")
    }
}
class PDFDocument: Renderable {}  // Inherits default render()
class VideoPlayer: Renderable {
    func render() {
        print("Custom video rendering")
    }
}
protocol Repository {
    associatedtype T
    func save(_ item: T)
    func get(id: String) -> T?
}
class UserRepository: Repository {
    typealias T = User
    
    func save(_ item: User) {
        print("Saving user \(item.name)")
    }
    
    func get(id: String) -> User? {
        return User(name: "John")
    }
}
protocol DownloadManagerDelegate: AnyObject {
    func downloadDidFinish(fileURL: URL)
}
class DownloadManager {
    weak var delegate: DownloadManagerDelegate?
    
    func startDownload() {
        delegate?.downloadDidFinish(fileURL: URL(string: "file://report.pdf")!)
    }
}
class ReportViewer: DownloadManagerDelegate {
    func downloadDidFinish(fileURL: URL) {
        print("Opening downloaded file at \(fileURL)")
    }
}
protocol Premium {
    var isPremium: Bool { get }
}
extension Array: Premium where Element: Premium {
    var isPremium: Bool {
        contains { $0.isPremium }
    }
}
struct Article: Premium {
    var isPremium: Bool
}
let articles = [Article(isPremium: false), Article(isPremium: true)]
print(articles.isPremium)  // true
protocol Database {
    func getUsers() -> [String]
}
class RealDatabase: Database {
    func getUsers() -> [String] {
        return ["Admin"]  // Real DB call
    }
}
class MockDatabase: Database {
    func getUsers() -> [String] {
        return ["TestUser"]  // Fake data
    }
}
func testUserCount(database: Database) {
    let count = database.getUsers().count
    assert(count > 0)
}
protocol ValidationError: LocalizedError {
    var field: String { get }
}
struct EmailError: ValidationError {
    let field = "email"
    var errorDescription: String? {
        "Invalid \(field) format"
    }
}
func validateEmail(_ email: String) throws {
    if !email.contains("@") {
        throw EmailError()
    }
}
protocol Theme {
    var backgroundColor: UIColor { get }
}
struct DarkTheme: Theme {
    let backgroundColor = UIColor.black
}
struct LightTheme: Theme {
    let backgroundColor = UIColor.white
}
enum ThemeFactory {
    static func create(for style: UIUserInterfaceStyle) -> Theme {
        switch style {
        case .dark: return DarkTheme()
        default: return LightTheme()
        }
    }
}
protocol Validatable {
    func isValid() -> Bool
}
@propertyWrapper
struct Validated<T: Validatable> {
    private var value: T
    
    var wrappedValue: T {
        get { value }
        set { if newValue.isValid() { value = newValue } }
    }
}
struct Age: Validatable {
    let value: Int
    func isValid() -> Bool { value >= 18 }
}
struct User {
    @Validated var age: Age
}
protocol ViewBuilder {
    associatedtype V: View
    func build() -> V
}
struct HomeScreenBuilder: ViewBuilder {
    func build() -> some View {
        Text("Home")
            .padding()
    }
}
| Pattern | Protocol Benefit | When to Use | 
|---|---|---|
| Collections | Unified interface | Payment processors | 
| Dependency Injection | Swappable implementations | Testing, Services | 
| Generics | Type-safe abstractions | Repositories, Caches | 
| Default Implementations | Code reuse | Shared behaviors | 
| Delegation | Loose coupling | UIKit callbacks | 
| Associated Types | Flexible generic constraints | Abstract data operations | 
Golden Rule: