Help us improve
Share bugs, ideas, or general feedback.
From everything-claude-code-mobile
Provides idiomatic Swift patterns for optionals, closures, capture lists, higher-order functions, computed properties, and protocols for safe iOS code.
npx claudepluginhub ahmed3elshaer/everything-claude-code-mobile --plugin everything-claude-code-mobileHow this skill is triggered — by the user, by Claude, or both
Slash command
/everything-claude-code-mobile:swift-patternsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Modern Swift idioms for clean, safe code.
Guides safe Swift optional handling with if-let/guard binding, chaining, nil coalescing, and modern patterns for SwiftUI, Combine, async/await, avoiding force unwrap pitfalls.
Applies modern Swift language patterns (if/switch expressions, typed throws, result builders, property wrappers, Codable, FormatStyle) for non-concurrency, non-SwiftUI code.
Enforces Swift code style conventions for clean, readable code: CamelCase naming, golden path with early guards, extensions for organization, spacing rules, and idiomatic patterns. Use when writing or reviewing Swift code.
Share bugs, ideas, or general feedback.
Modern Swift idioms for clean, safe code.
// ✅ Good: guard let for early exit
func processUser(_ user: User?) {
guard let user = user else {
print("User is nil")
return
}
// user is non-optional here
print(user.name)
}
// ✅ Good: if let for conditional
if let email = user.email {
sendEmail(to: email)
}
// ✅ Good: nil coalescing
let displayName = user.name ?? "Anonymous"
// ✅ Good: Optional chaining
let street = user.address?.street
// ❌ Bad: Force unwrap (crashes if nil)
let email = user.email! // Don't do this
// ✅ map for transformation
let uppercase = user.name?.map { $0.uppercased() }
// ✅ flatMap for chaining optionals
let domain = user.email?.flatMap { $0.split(separator: "@").last }
// ✅ Trailing closure syntax
viewModel.fetchUsers { users in
self.users = users
}
// Equivalent to
viewModel.fetchUsers { users in
self.users = users
}
// ✅ Shorthand argument names
viewModel.fetchUsers {
self.users = $0
}
// ✅ Capture lists to avoid retain cycles
class UserViewController: UIViewController {
private let viewModel: UserViewModel
func setupRefresh() {
viewModel.onRefresh = { [weak self] in
guard let self = self else { return }
self.tableView.reloadData()
}
}
// ✅ Or capture self explicitly when ownership is clear
func setupTimer() {
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [self] _ in
self.updateUI()
}
}
}
let numbers = [1, 2, 3, 4, 5]
// ✅ map - transform
let doubled = numbers.map { $0 * 2 } // [2, 4, 6, 8, 10]
// ✅ filter - select
let evens = numbers.filter { $0 % 2 == 0 } // [2, 4]
// ✅ reduce - combine
let sum = numbers.reduce(0) { $0 + $1 } // 15
// ✅ compactMap - filter out nils
let names = users.compactMap { $0.name }
// ✅ forEach - side effects
numbers.forEach { print($0) }
// ❌ Don't use forEach for transformation
// ❌ Bad: numbers.forEach { doubled.append($0 * 2) }
// ✅ Good: let doubled = numbers.map { $0 * 2 }
struct User {
let firstName: String
let lastName: String
// ✅ Computed property
var fullName: String {
"\(firstName) \(lastName)"
}
// ✅ With setter
var age: Int {
get { _age }
set {
guard newValue >= 0 else { return }
_age = newValue
}
}
private var _age: Int = 0
}
class Settings {
var theme: Theme = .light {
didSet {
saveSettings()
notifyThemeChanged()
}
}
var score: Int = 0 {
willSet {
print("Score will change from \(score) to \(newValue)")
}
didSet {
if oldValue > score {
print("Score decreased!")
}
}
}
}
struct DataProcessor {
// ✅ Lazy - created only when accessed
private lazy var formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
func process(date: Date) -> String {
formatter.string(from: date)
}
}
// ✅ Protocol with associated type
protocol Repository {
associatedtype Item
func fetch(id: String) async throws -> Item
func save(_ item: Item) async throws
}
// ✅ Generic where clause
extension Repository {
func fetchAll(ids: [String]) async throws -> [Item] {
try await withThrowingTaskGroup(of: Item.self) { group in
for id in ids {
group.addTask { try await fetch(id: id) }
}
return try await group.reduce(into: [Item]()) { $0.append($1) }
}
}
}
protocol Identifiable {
var id: String { get }
}
extension Identifiable {
func debugInfo() -> String {
"ID: \(id)"
}
}
struct User: Identifiable {
let id: String
let name: String
}
let user = User(id: "123", name: "John")
print(user.debugInfo()) // "ID: 123"
// ✅ Generic function
func first<T>(_ array: [T]) -> T? {
array.first
}
// ✅ With constraints
func sorted<T: Comparable>(_ array: [T]) -> [T] {
array.sorted()
}
// ✅ Multiple constraints
func process<T: Sequence & Sendable>(_ items: T) where T.Element: Hashable {
// Process items
}
protocol DataSource {
associatedtype Item
func getItems() async throws -> [Item]
}
class RemoteDataSource: DataSource {
typealias Item = User
func getItems() async throws -> [User] {
try await api.getUsers()
}
}
// ✅ Result for error handling
func fetchUser(id: String) async -> Result<User, Error> {
do {
let user = try await api.getUser(id)
return .success(user)
} catch {
return .failure(error)
}
}
// Usage
let result = await fetchUser(id: "123")
switch result {
case .success(let user):
displayUser(user)
case .failure(let error):
showError(error)
}
// ✅ map, flatMap on Result
let name = await fetchUser(id: "123").map(\.name)
// ✅ async let for concurrent work
func loadDashboard() async throws -> Dashboard {
async let user = getUser()
async let notifications = getNotifications()
async let stats = getStats()
return try await Dashboard(
user: user,
notifications: notifications,
stats: stats
)
}
// ✅ TaskGroup for dynamic concurrency
func fetchAllImages(urls: [URL]) async throws -> [Image] {
try await withThrowingTaskGroup(of: Image.self) { group in
for url in urls {
group.addTask {
try await downloadImage(from: url)
}
}
var images: [Image] = []
for try await image in group {
images.append(image)
}
return images
}
}
// ✅ MainActor for UI updates
@MainActor
class HomeViewModel: Observable {
@Published var users: [User] = []
func loadUsers() async {
// Already on main actor
let users = try? await api.getUsers()
self.users = users ?? []
}
}
// ✅ Explicit main actor dispatch
class NetworkService {
func fetch() async -> Data {
// Background work
let data = ...
// Dispatch to main if needed
await MainActor.run {
// UI work
}
return data
}
}
// ✅ Enum with associated values
enum NetworkError: Error {
case invalidURL
case noConnection
case serverError(code: Int, message: String)
case decodingError(Error)
}
func handle(_ error: NetworkError) {
switch error {
case .invalidURL:
print("Invalid URL")
case .noConnection:
print("No connection")
case .serverError(let code, let message):
print("Server error \(code): \(message)")
case .decodingError(let error):
print("Decoding failed: \(error)")
}
}
// ✅ Enum for exhaustive state
enum LoadState<T> {
case idle
case loading
case loaded(T)
case error(Error)
var isLoading: Bool {
if case .loading = self { return true }
return false
}
var value: T? {
if case .loaded(let value) = self { return value }
return nil
}
}
// Usage
@Published var state: LoadState<[User]> = .idle
switch state {
case .idle:
EmptyView()
case .loading:
ProgressView()
case .loaded(let users):
UserList(users: users)
case .error(let error):
ErrorView(error: error)
}
// ✅ Use explicit access control
public struct PublicAPI {
public var value: String
private init() {
value = "default"
}
// ✅ private for fileprivate only when needed
private var helper: String {
"helper"
}
// ✅ internal (default, same module)
var internalValue: String = "internal"
// ✅ fileprivate (same file)
fileprivate var fileOnly: String = "fileOnly"
}
// ✅ Key paths for type-safe references
struct User {
let name: String
let email: String
let age: Int
}
let nameKeyPath = \User.name
let users = [User(...)]
let names = users.map(\.name) // [String]
// ✅ With functions
func sort<T>(_ users: [T], by keyPath: KeyPath<T, String>) -> [T] {
users.sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }
}
let sorted = sort(users, by: \.name)
Remember: Swift is designed for safety. Use optionals, type inference, and value types to write robust code.