SOLID principles for Swift 6 and SwiftUI (iOS 26+). Apple recommended patterns, @Observable, actors, Preview-driven development.
/plugin marketplace add fusengine/agents/plugin install fuse-swift-apple-expert@fusengine-pluginsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Today: January 2026 - ALWAYS use the current year for your searches. Search with "2025" or "2026", NEVER with past years.
CRITICAL: Check today's date first, then search documentation and web BEFORE writing any code.
WORKFLOW:
1. Check date → 2. Research docs + web (current year) → 3. Apply latest patterns → 4. Code
Search queries (replace YYYY with current year):
Swift [feature] YYYY best practicesSwiftUI [component] YYYY new APIsApple WWDC YYYY [topic]Never assume - always verify current APIs and patterns exist for the current year.
Before ANY implementation:
Continue implementation by:
Before writing ANY new code:
Core/Extensions/, Core/Utilities/, Core/Protocols/When creating new code:
Core/Utilities////Sources/
├── Protocols/ # Protocols ONLY
│ ├── UserServiceProtocol.swift
│ └── AuthProviderProtocol.swift
├── Services/ # Implementations
│ └── UserService.swift
├── ViewModels/ # @Observable classes
│ └── UserViewModel.swift
└── Views/ # SwiftUI Views
└── UserView.swift
/// Fetches user by ID from remote API.
///
/// - Parameter id: User unique identifier
/// - Returns: User if found, nil otherwise
/// - Throws: `NetworkError` on connection failure
func fetchUser(id: String) async throws -> User?
Every View MUST have a #Preview:
#Preview {
UserProfileView(user: .preview)
}
#Preview("Loading State") {
UserProfileView(user: nil)
}
Sources/
├── App/
│ └── MyApp.swift
├── Features/ # Feature modules
│ ├── Auth/
│ │ ├── Views/
│ │ ├── ViewModels/
│ │ ├── Services/
│ │ └── Protocols/
│ └── Profile/
├── Core/ # Shared
│ ├── Services/
│ ├── Models/
│ ├── Protocols/
│ └── Extensions/
└── Resources/
// ❌ OLD - ObservableObject
class UserViewModel: ObservableObject {
@Published var user: User?
}
// ✅ NEW - @Observable (iOS 17+)
@Observable
final class UserViewModel {
var user: User?
var isLoading = false
private let service: UserServiceProtocol
init(service: UserServiceProtocol) {
self.service = service
}
}
1 type = 1 purpose
// ❌ BAD - View does everything
struct UserView: View {
@State private var user: User?
var body: some View {
// fetching, validation, formatting, rendering...
}
}
// ✅ GOOD - Separation
struct UserView: View {
@State private var viewModel: UserViewModel
var body: some View {
UserContent(user: viewModel.user)
}
}
Protocols for extensibility
// Protocols/AuthProviderProtocol.swift
protocol AuthProviderProtocol: Sendable {
func signIn(credentials: Credentials) async throws -> Session
func signOut() async
}
// Services/AppleAuthProvider.swift
final class AppleAuthProvider: AuthProviderProtocol { }
// Services/GoogleAuthProvider.swift
final class GoogleAuthProvider: AuthProviderProtocol { }
All implementations respect contracts
// Any provider works
let auth: AuthProviderProtocol = AppleAuthProvider()
// or
let auth: AuthProviderProtocol = GoogleAuthProvider()
// Both work identically
try await auth.signIn(credentials: creds)
Small, focused protocols
// ❌ BAD - Too broad
protocol UserProtocol {
func fetch() async
func update() async
func delete() async
func sendNotification() async
}
// ✅ GOOD - Separated
protocol Fetchable { func fetch() async }
protocol Updatable { func update() async }
protocol Deletable { func delete() async }
Depend on protocols, inject implementations
// ViewModel depends on protocol
@Observable
final class UserViewModel {
private let service: UserServiceProtocol
init(service: UserServiceProtocol) {
self.service = service
}
}
// Injection at app level
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.environment(UserViewModel(service: UserService()))
}
}
}
actor UserCache {
private var users: [String: User] = [:]
func get(_ id: String) -> User? {
users[id]
}
func set(_ user: User) {
users[user.id] = user
}
}
@MainActor
@Observable
final class UserViewModel {
var user: User?
var isLoading = false
func load() async {
isLoading = true
defer { isLoading = false }
user = try? await service.fetchUser()
}
}
// Models must be Sendable for concurrency
struct User: Codable, Sendable {
let id: String
let name: String
let email: String
}
// ✅ GOOD - Task groups
func loadDashboard() async throws -> Dashboard {
async let user = fetchUser()
async let stats = fetchStats()
async let notifications = fetchNotifications()
return Dashboard(
user: try await user,
stats: try await stats,
notifications: try await notifications
)
}
import SwiftUI
/// User profile view displaying user information.
struct UserProfileView: View {
let user: User?
var body: some View {
Group {
if let user {
UserContent(user: user)
} else {
ProgressView()
}
}
.navigationTitle("profile.title")
}
}
// MARK: - Subviews
private struct UserContent: View {
let user: User
var body: some View {
VStack {
Text(user.name)
Text(user.email)
}
}
}
// MARK: - Preview
#Preview {
UserProfileView(user: .preview)
}
import Foundation
/// ViewModel for user profile screen.
@MainActor
@Observable
final class UserProfileViewModel {
// MARK: - State
var user: User?
var isLoading = false
var error: Error?
// MARK: - Dependencies
private let service: UserServiceProtocol
// MARK: - Init
init(service: UserServiceProtocol) {
self.service = service
}
// MARK: - Actions
/// Loads user profile from API.
func load() async {
isLoading = true
defer { isLoading = false }
do {
user = try await service.fetchCurrentUser()
} catch {
self.error = error
}
}
}
import Foundation
/// Protocol for user-related operations.
protocol UserServiceProtocol: Sendable {
/// Fetches the current authenticated user.
func fetchCurrentUser() async throws -> User
/// Updates user profile.
func updateUser(_ user: User) async throws -> User
}
import Foundation
/// Implementation of UserServiceProtocol using URLSession.
final class UserService: UserServiceProtocol {
private let session: URLSession
init(session: URLSession = .shared) {
self.session = session
}
func fetchCurrentUser() async throws -> User {
let url = URL(string: "https://api.example.com/me")!
let (data, _) = try await session.data(from: url)
return try JSONDecoder().decode(User.self, from: data)
}
func updateUser(_ user: User) async throws -> User {
// Implementation...
return user
}
}
All user-facing text MUST use String Catalogs:
// ✅ GOOD - Localized
Text("profile.welcome.title")
Button("button.save") { }
// With interpolation
Text("profile.greeting \(user.name)")
// ❌ BAD - Hardcoded
Text("Welcome!")
Button("Save") { }
Key naming: module.screen.element
.glassBackgroundEffect()
.liquidGlass()
SpatialLayout {
Model3D(named: "object")
}
This skill should be used when the user asks to "create a hookify rule", "write a hook rule", "configure hookify", "add a hookify rule", or needs guidance on hookify rule syntax and patterns.
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.