# iOS Native Development Complete guide to iOS development with Swift and SwiftUI (2024-2025). ## Swift 6 Overview ### Key Features - **Data race safety**: Compile-time detection (default in Swift 6) - **Concurrency**: async/await, actors, @MainActor - **Macro system**: Code generation at compile time - **Move semantics**: Ownership optimization - **Enhanced generics**: More powerful type system ### Modern Swift Patterns **Async/Await:** ```swift func fetchUser(id: String) async throws -> User { let (data, _) = try await URLSession.shared.data(from: url) return try JSONDecoder().decode(User.self, from: data) } // Usage Task { do { let user = try await fetchUser(id: "123") self.user = user } catch { self.error = error } } ``` **Actors (Thread-safe classes):** ```swift actor UserCache { private var cache: [String: User] = [:] func get(_ id: String) -> User? { cache[id] } func set(_ id: String, user: User) { cache[id] = user } } ``` ## SwiftUI vs UIKit ### When to Use SwiftUI ✅ New projects (iOS 13+) ✅ Declarative UI preferred ✅ Fast iteration needed ✅ Cross-platform (macOS, watchOS, tvOS) ✅ 40% less code vs UIKit ### When to Use UIKit ✅ Legacy app maintenance ✅ Complex customizations ✅ Fine-grained control needed ✅ Specific UIKit features required ✅ Pre-iOS 13 support ### SwiftUI Basics ```swift struct ContentView: View { @State private var count = 0 var body: some View { VStack(spacing: 20) { Text("Count: \(count)") .font(.title) Button("Increment") { count += 1 } .buttonStyle(.borderedProminent) } .padding() } } ``` **Property Wrappers:** - `@State`: View-local state - `@Binding`: Two-way binding - `@StateObject`: Observable object owner - `@ObservedObject`: Observable object reference - `@EnvironmentObject`: Dependency injection - `@Published`: Observable property ## Architecture Patterns ### MVVM (Most Popular) ```swift // Model struct User: Identifiable, Codable { let id: String let name: String let email: String } // ViewModel @MainActor class UserViewModel: ObservableObject { @Published var users: [User] = [] @Published var isLoading = false @Published var error: Error? private let repository: UserRepository init(repository: UserRepository = UserRepository()) { self.repository = repository } func loadUsers() async { isLoading = true defer { isLoading = false } do { users = try await repository.fetchUsers() } catch { self.error = error } } } // View struct UserListView: View { @StateObject private var viewModel = UserViewModel() var body: some View { List(viewModel.users) { user in Text(user.name) } .task { await viewModel.loadUsers() } } } ``` ### TCA (The Composable Architecture) **When to use:** - Complex state management - Predictable state updates - Excellent testing - Enterprise apps **Trade-offs:** - Steeper learning curve - More boilerplate - Excellent for large teams ## Performance Optimization ### Compiler Optimizations **1. Use `final` classes:** ```swift final class FastClass { // Compiler can optimize (no dynamic dispatch) } ``` **2. Private methods:** ```swift private func optimize() { // Compiler can inline } ``` **3. Whole-module optimization:** ```bash # Build Settings SWIFT_WHOLE_MODULE_OPTIMIZATION = YES ``` ### Memory Management **ARC (Automatic Reference Counting):** ```swift class Parent { var child: Child? } class Child { weak var parent: Parent? // Weak to avoid retain cycle } ``` **Common Retain Cycles:** ```swift // ❌ Bad: Retain cycle class ViewController: UIViewController { var completion: (() -> Void)? func setup() { completion = { self.doSomething() // Strong capture } } } // ✅ Good: Weak self class ViewController: UIViewController { var completion: (() -> Void)? func setup() { completion = { [weak self] in self?.doSomething() } } } ``` ### SwiftUI Performance **1. Use const modifiers:** ```swift Text("Hello") // Recreated on every render vs Text("Hello") .font(.title) // Modifier creates new view // Better: Extract static views let titleText = Text("Hello").font(.title) ``` **2. Avoid expensive computations:** ```swift struct ExpensiveView: View { let data: [Item] // Computed every render var sortedData: [Item] { data.sorted() // ❌ Bad } // Better: Cache with @State or pass sorted } ``` ## Testing Strategies ### XCTest (Unit Testing) ```swift import XCTest @testable import MyApp final class UserViewModelTests: XCTestCase { var viewModel: UserViewModel! var mockRepository: MockUserRepository! override func setUp() { super.setUp() mockRepository = MockUserRepository() viewModel = UserViewModel(repository: mockRepository) } func testLoadUsers() async throws { // Given let expectedUsers = [User(id: "1", name: "Test", email: "test@example.com")] mockRepository.usersToReturn = expectedUsers // When await viewModel.loadUsers() // Then XCTAssertEqual(viewModel.users, expectedUsers) XCTAssertFalse(viewModel.isLoading) XCTAssertNil(viewModel.error) } } ``` ### XCUITest (UI Testing) ```swift import XCTest final class LoginUITests: XCTestCase { let app = XCUIApplication() override func setUp() { super.setUp() app.launch() } func testLoginFlow() { let emailField = app.textFields["emailField"] emailField.tap() emailField.typeText("test@example.com") let passwordField = app.secureTextFields["passwordField"] passwordField.tap() passwordField.typeText("password123") app.buttons["loginButton"].tap() XCTAssertTrue(app.staticTexts["Welcome"].waitForExistence(timeout: 5)) } } ``` **Target Coverage:** - Unit tests: 70-80%+ - Critical paths: 100% - UI tests: Key user flows only (slow) ## iOS-Specific Features ### WidgetKit ```swift import WidgetKit import SwiftUI struct SimpleWidget: Widget { var body: some WidgetConfiguration { StaticConfiguration(kind: "SimpleWidget", provider: Provider()) { entry in SimpleWidgetView(entry: entry) } .configurationDisplayName("My Widget") .description("This is my widget") .supportedFamilies([.systemSmall, .systemMedium, .systemLarge]) } } ``` ### Live Activities (iOS 16.1+) ```swift import ActivityKit struct OrderAttributes: ActivityAttributes { struct ContentState: Codable, Hashable { var status: String var estimatedTime: Date } var orderId: String } // Start activity let attributes = OrderAttributes(orderId: "123") let initialState = OrderAttributes.ContentState( status: "Preparing", estimatedTime: Date().addingTimeInterval(1800) ) let activity = try Activity.request( attributes: attributes, contentState: initialState ) ``` ### App Clips **Characteristics:** - <10MB size limit - Fast, lightweight experiences - No installation required - Invoked via NFC, QR, Safari, Maps ## Human Interface Guidelines (HIG) ### Navigation Patterns **Tab Bar:** - 2-5 top-level sections - Bottom placement - Always visible - Immediate navigation **Navigation Bar:** - Hierarchical navigation - Back button automatic - Title and actions - Large/inline title modes **Modal Presentation:** - Interrupting tasks - Self-contained flow - Clear dismiss action - Use sparingly ### Design Principles **Clarity:** - Legible text (minimum 11pt) - Sufficient contrast (WCAG AA) - Precise icons **Deference:** - Content first, UI second - Translucent backgrounds - Minimal UI elements **Depth:** - Layering (sheets, overlays) - Visual hierarchy - Motion provides meaning ### Colors **System Colors:** ```swift Color.primary // Adaptive black/white Color.secondary // Gray Color.accentColor // App tint color Color(uiColor: .systemBlue) Color(uiColor: .label) ``` **Dark Mode:** ```swift // Automatic Color.primary // Adapts to light/dark // Custom Color("CustomColor") // Define in Assets.xcassets ``` ### SF Symbols ```swift Image(systemName: "star.fill") .foregroundColor(.yellow) .font(.title) // Rendering modes Image(systemName: "heart.fill") .symbolRenderingMode(.multicolor) ``` ## App Store Requirements (2024-2025) ### SDK Requirements - **Current**: Xcode 15+ with iOS 17 SDK (required as of April 2024) - **Upcoming**: Xcode 16+ with iOS 18 SDK (recommended for 2025 submissions) ### Privacy - **Privacy manifest**: Required for third-party SDKs - **Tracking permission**: ATT framework for advertising - **Privacy nutrition labels**: Accurate data collection info - **Account deletion**: In-app deletion required ### Capabilities - **Sandbox**: All apps sandboxed - **Entitlements**: Request only needed capabilities - **Background modes**: Justify background usage - **HealthKit**: Privacy-sensitive, strict review ### Submission Checklist ✅ App icons (all required sizes) ✅ Screenshots (all device sizes) ✅ App description and keywords ✅ Privacy policy URL ✅ Support URL ✅ Age rating questionnaire ✅ Export compliance ✅ Test on real devices ✅ No crashes or major bugs ## Common Pitfalls 1. **Strong reference cycles**: Use `[weak self]` in closures 2. **Main thread blocking**: Use async/await, avoid sync operations 3. **Large images**: Resize before displaying 4. **Unhandled errors**: Always handle async throws 5. **Ignoring safe areas**: Use `.ignoresSafeArea()` intentionally 6. **Not testing dark mode**: Design for both appearances 7. **Hardcoded strings**: Use localization from start 8. **Memory leaks**: Profile with Instruments regularly ## Resources **Official:** - Swift Documentation: https://swift.org/documentation/ - SwiftUI Tutorials: https://developer.apple.com/tutorials/swiftui - HIG: https://developer.apple.com/design/human-interface-guidelines/ - WWDC Videos: https://developer.apple.com/videos/ **Community:** - Hacking with Swift: https://www.hackingwithswift.com/ - Swift by Sundell: https://www.swiftbysundell.com/ - objc.io: https://www.objc.io/ - iOS Dev Weekly: https://iosdevweekly.com/