āļ„āļģāļ–āļēāļĄāļŠāļąāļĄāļ āļēāļĐāļ“āđŒ SwiftUI NavigationStack: āļĢāļđāļ›āđāļšāļšāļāļēāļĢāļ™āļģāļ—āļēāļ‡ 2026

āđ€āļ•āļĢāļĩāļĒāļĄāļ•āļąāļ§āļŠāļąāļĄāļ āļēāļĐāļ“āđŒ iOS āļ”āđ‰āļ§āļĒāļ„āļģāļ–āļēāļĄāļŠāļģāļ„āļąāļāđ€āļāļĩāđˆāļĒāļ§āļāļąāļš NavigationStack, NavigationPath āđāļĨāļ°āļĢāļđāļ›āđāļšāļšāļāļēāļĢāļ™āļģāļ—āļēāļ‡āļŠāļĄāļąāļĒāđƒāļŦāļĄāđˆāđƒāļ™ SwiftUI

āļ„āļģāļ–āļēāļĄāļŠāļąāļĄāļ āļēāļĐāļ“āđŒ SwiftUI NavigationStack āļŠāļģāļŦāļĢāļąāļšāļ™āļąāļāļžāļąāļ’āļ™āļē iOS

āļāļēāļĢāļ™āļģāļ—āļēāļ‡āđ€āļ›āđ‡āļ™āđ€āļŠāļēāļŦāļĨāļąāļāļŠāļģāļ„āļąāļāļ‚āļ­āļ‡āđāļ­āļ›āļžāļĨāļīāđ€āļ„āļŠāļąāļ™ iOS āļ—āļļāļāļ•āļąāļ§ āļ•āļąāđ‰āļ‡āđāļ•āđˆ iOS 16 āđ€āļ›āđ‡āļ™āļ•āđ‰āļ™āļĄāļē NavigationStack āđ„āļ”āđ‰āđ€āļ‚āđ‰āļēāļĄāļēāđāļ—āļ™āļ—āļĩāđˆ NavigationView āđāļĨāļ°āļĄāļ­āļšāļāļēāļĢāļ„āļ§āļšāļ„āļļāļĄāđ€āļŠāļīāļ‡āđ‚āļ›āļĢāđāļāļĢāļĄāđ€āļ•āđ‡āļĄāļĢāļđāļ›āđāļšāļšāđ€āļŦāļ™āļ·āļ­āļŠāđāļ•āđ‡āļāļāļēāļĢāļ™āļģāļ—āļēāļ‡ āļ™āļēāļĒāļˆāđ‰āļēāļ‡āļĄāļąāļāļˆāļ°āļ—āļ”āļŠāļ­āļšāļ„āļ§āļēāļĄāđ€āļŠāļĩāđˆāļĒāļ§āļŠāļēāļāđƒāļ™āđāļ™āļ§āļ„āļīāļ”āđ€āļŦāļĨāđˆāļēāļ™āļĩāđ‰āđƒāļ™āļĢāļ°āļŦāļ§āđˆāļēāļ‡āļāļēāļĢāļŠāļąāļĄāļ āļēāļĐāļ“āđŒāļ—āļēāļ‡āđ€āļ—āļ„āļ™āļīāļ„āđ€āļ›āđ‡āļ™āļ›āļĢāļ°āļˆāļģ

āđ‚āļ„āļĢāļ‡āļŠāļĢāđ‰āļēāļ‡āļ‚āļ­āļ‡āļ„āļđāđˆāļĄāļ·āļ­

āđāļ•āđˆāļĨāļ°āļ„āļģāļ–āļēāļĄāļˆāļģāļĨāļ­āļ‡āļĢāļđāļ›āđāļšāļšāļ‚āļ­āļ‡āļāļēāļĢāļŠāļąāļĄāļ āļēāļĐāļ“āđŒāļ—āļēāļ‡āđ€āļ—āļ„āļ™āļīāļ„āļˆāļĢāļīāļ‡ āļžāļĢāđ‰āļ­āļĄāļ„āļģāļ•āļ­āļšāđ‚āļ”āļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”āđāļĨāļ°āđ‚āļ„āđ‰āļ”āļ—āļĩāđˆāđƒāļŠāđ‰āļ‡āļēāļ™āđ„āļ”āđ‰ āđ€āļ™āļ·āđ‰āļ­āļŦāļēāļˆāļ°āļ„āđˆāļ­āļĒ āđ† āđ€āļžāļīāđˆāļĄāļ„āļ§āļēāļĄāļ‹āļąāļšāļ‹āđ‰āļ­āļ™āļˆāļēāļāļĢāļ°āļ”āļąāļšāļžāļ·āđ‰āļ™āļāļēāļ™āđ„āļ›āļ–āļķāļ‡āļĢāļ°āļ”āļąāļšāļŠāļđāļ‡

āļžāļ·āđ‰āļ™āļāļēāļ™āļ‚āļ­āļ‡ NavigationStack

āļ„āļģāļ–āļēāļĄāļ—āļĩāđˆ 1: NavigationView āđāļĨāļ° NavigationStack āļ•āđˆāļēāļ‡āļāļąāļ™āļ­āļĒāđˆāļēāļ‡āđ„āļĢ?

NavigationView (āđ€āļĨāļīāļāđƒāļŠāđ‰āļ•āļąāđ‰āļ‡āđāļ•āđˆ iOS 16) āļŠāļĢāđ‰āļēāļ‡āļāļēāļĢāļ™āļģāļ—āļēāļ‡āđāļšāļšāđ‚āļ”āļĒāļ›āļĢāļīāļĒāļēāļĒāđ‚āļ”āļĒāļ­āļīāļ‡āļˆāļēāļ NavigationLink āļ—āļĩāđˆāļ‹āđ‰āļ­āļ™āļāļąāļ™ āļŠāđˆāļ§āļ™ NavigationStack āđāļ™āļ°āļ™āļģāđāļ™āļ§āļ—āļēāļ‡āđāļšāļšāđ€āļŠāļīāļ‡āļ›āļĢāļ°āļāļēāļĻāļžāļĢāđ‰āļ­āļĄāļŠāđāļ•āđ‡āļāļāļēāļĢāļ™āļģāļ—āļēāļ‡āļ—āļĩāđˆāļŠāļąāļ”āđ€āļˆāļ™āđāļĨāļ°āļŠāļēāļĄāļēāļĢāļ–āļ›āļĢāļąāļšāđ€āļ›āļĨāļĩāđˆāļĒāļ™āđ„āļ”āđ‰āļ”āđ‰āļ§āļĒāđ‚āļ›āļĢāđāļāļĢāļĄ

NavigationComparison.swiftswift
// ❌ Old pattern with NavigationView (deprecated)
struct OldNavigation: View {
    var body: some View {
        NavigationView {
            NavigationLink("Details", destination: DetailView())
        }
    }
}

// ✅ New pattern with NavigationStack
struct ModernNavigation: View {
    // Navigation stack is explicit and controllable
    @State private var path = NavigationPath()

    var body: some View {
        NavigationStack(path: $path) {
            List {
                // NavigationLink with typed value
                NavigationLink("User 1", value: User(id: 1, name: "Alice"))
                NavigationLink("User 2", value: User(id: 2, name: "Bob"))
            }
            // Destination defined by value type
            .navigationDestination(for: User.self) { user in
                UserDetailView(user: user)
            }
        }
    }
}

āļ‚āđ‰āļ­āđ„āļ”āđ‰āđ€āļ›āļĢāļĩāļĒāļšāļŦāļĨāļąāļāļ„āļ·āļ­āļāļēāļĢāđāļĒāļāļāļēāļĢāļ›āļĢāļ°āļāļēāļĻāļĨāļīāļ‡āļāđŒāļ­āļ­āļāļˆāļēāļāļ›āļĨāļēāļĒāļ—āļēāļ‡ āļ‹āļķāđˆāļ‡āļŠāđˆāļ§āļĒāđƒāļŦāđ‰āļāļēāļĢāļ™āļģāļ—āļēāļ‡āđ€āļ›āđ‡āļ™āđāļšāļšāļĢāļ§āļĄāļĻāļđāļ™āļĒāđŒāđāļĨāļ°āļ—āļ”āļŠāļ­āļšāđ„āļ”āđ‰

āļ„āļģāļ–āļēāļĄāļ—āļĩāđˆ 2: NavigationPath āļ—āļģāļ‡āļēāļ™āļ­āļĒāđˆāļēāļ‡āđ„āļĢ?

NavigationPath āļ„āļ·āļ­āļ„āļ­āļ™āđ€āļ—āļ™āđ€āļ™āļ­āļĢāđŒāđāļšāļšāļĨāļšāļ›āļĢāļ°āđ€āļ āļ— (type-erased) āļ—āļĩāđˆāļˆāļąāļ”āđ€āļāđ‡āļšāļ„āđˆāļēāļāļēāļĢāļ™āļģāļ—āļēāļ‡ āļŠāļēāļĄāļēāļĢāļ–āļˆāļąāļ”āļāļēāļĢāļŠāđāļ•āđ‡āļāđ„āļ”āđ‰āđ‚āļ”āļĒāđ„āļĄāđˆāļˆāļģāđ€āļ›āđ‡āļ™āļ•āđ‰āļ­āļ‡āļĢāļđāđ‰āļ›āļĢāļ°āđ€āļ āļ—āļ—āļĩāđˆāđāļ™āđˆāļ™āļ­āļ™āļ‚āļ­āļ‡āļŦāļ™āđ‰āļēāļˆāļ­ āļ‚āļ“āļ°āđ€āļ”āļĩāļĒāļ§āļāļąāļ™āļāđ‡āļ„āļ‡āļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒāļ‚āļ­āļ‡āļ›āļĢāļ°āđ€āļ āļ—āđ„āļ§āđ‰āđƒāļ™āđ€āļ§āļĨāļēāļ„āļ­āļĄāđ„āļžāļĨāđŒ

NavigationPathBasics.swiftswift
struct ContentView: View {
    // NavigationPath can contain different Hashable types
    @State private var path = NavigationPath()

    var body: some View {
        NavigationStack(path: $path) {
            VStack(spacing: 20) {
                Button("View user profile") {
                    // Adds a User to the stack
                    path.append(User(id: 1, name: "Alice"))
                }

                Button("View settings") {
                    // Adds a Settings enum to the stack
                    path.append(SettingsRoute.notifications)
                }

                Button("Back to root") {
                    // Clears the entire stack
                    path.removeLast(path.count)
                }
            }
            .navigationDestination(for: User.self) { user in
                UserDetailView(user: user)
            }
            .navigationDestination(for: SettingsRoute.self) { route in
                SettingsView(route: route)
            }
        }
    }
}

// Types must be Hashable
struct User: Hashable {
    let id: Int
    let name: String
}

enum SettingsRoute: Hashable {
    case notifications
    case privacy
    case account
}
āļĨāļšāļ›āļĢāļ°āđ€āļ āļ—āđāļ•āđˆāļĒāļąāļ‡āļ›āļĨāļ­āļ”āļ āļąāļĒāļ—āļēāļ‡āļ›āļĢāļ°āđ€āļ āļ—

NavigationPath āđƒāļŠāđ‰āļāļēāļĢāļĨāļšāļ›āļĢāļ°āđ€āļ āļ—āļ āļēāļĒāđƒāļ™āđāļ•āđˆāļ•āļĢāļ§āļˆāļŠāļ­āļšāļ›āļĢāļ°āđ€āļ āļ—āđƒāļ™āđ€āļ§āļĨāļēāļ„āļ­āļĄāđ„āļžāļĨāđŒāļœāđˆāļēāļ™ navigationDestination āļ„āđˆāļēāļ—āļĩāđˆāđ„āļĄāđˆāļĄāļĩāļ›āļĨāļēāļĒāļ—āļēāļ‡āļ—āļĩāđˆāļŠāļ­āļ”āļ„āļĨāđ‰āļ­āļ‡āļāļąāļ™āļˆāļ°āļ—āļģāđƒāļŦāđ‰āđ€āļāļīāļ”āļ‚āđ‰āļ­āļœāļīāļ”āļžāļĨāļēāļ”āđ€āļ‡āļĩāļĒāļšāđƒāļ™āđ€āļ§āļĨāļēāļĢāļąāļ™

āļ„āļģāļ–āļēāļĄāļ—āļĩāđˆ 3: āļˆāļ°āļ™āļģāļāļēāļĢāļ™āļģāļ—āļēāļ‡āđ€āļŠāļīāļ‡āđ‚āļ›āļĢāđāļāļĢāļĄāļ—āļĩāđˆāļŠāļĄāļšāļđāļĢāļ“āđŒāđ„āļ›āđƒāļŠāđ‰āļ­āļĒāđˆāļēāļ‡āđ„āļĢ?

āļāļēāļĢāļ™āļģāļ—āļēāļ‡āđ€āļŠāļīāļ‡āđ‚āļ›āļĢāđāļāļĢāļĄāļŠāđˆāļ§āļĒāđƒāļŦāđ‰āļ„āļ§āļšāļ„āļļāļĄāļŠāđāļ•āđ‡āļāđ„āļ”āđ‰āļˆāļēāļāļˆāļļāļ”āđƒāļ”āļāđ‡āđ„āļ”āđ‰āđƒāļ™āđ‚āļ„āđ‰āļ” āđ‚āļ”āļĒāđ„āļĄāđˆāļ•āđ‰āļ­āļ‡āļ­āļēāļĻāļąāļĒāļāļēāļĢāļāļĢāļ°āļ—āļģāļ‚āļ­āļ‡āļœāļđāđ‰āđƒāļŠāđ‰āđ‚āļ”āļĒāļ•āļĢāļ‡ āļŠāļīāđˆāļ‡āļ™āļĩāđ‰āļŠāļģāļ„āļąāļāļŠāļģāļŦāļĢāļąāļš deep link, āļāļēāļĢāđ€āļ›āļĨāļĩāđˆāļĒāļ™āđ€āļŠāđ‰āļ™āļ—āļēāļ‡āļŦāļĨāļąāļ‡āļāļēāļĢāļĒāļ·āļ™āļĒāļąāļ™āļ•āļąāļ§āļ•āļ™ āļŦāļĢāļ·āļ­āđ‚āļŸāļĨāļ§āđŒāļŦāļĨāļēāļĒāļ‚āļąāđ‰āļ™āļ•āļ­āļ™

ProgrammaticNavigation.swiftswift
// Centralized router to manage navigation
@Observable
class NavigationRouter {
    var path = NavigationPath()

    // Navigate to a specific screen
    func navigateTo(_ destination: AppRoute) {
        path.append(destination)
    }

    // Go back one level
    func goBack() {
        guard !path.isEmpty else { return }
        path.removeLast()
    }

    // Return to root
    func popToRoot() {
        path.removeLast(path.count)
    }

    // Navigate to a complete stack (deep link)
    func navigateToPath(_ routes: [AppRoute]) {
        popToRoot()
        for route in routes {
            path.append(route)
        }
    }
}

// Enum defining all app routes
enum AppRoute: Hashable {
    case userList
    case userDetail(userId: Int)
    case userEdit(userId: Int)
    case settings
    case settingsDetail(SettingsSection)
}

enum SettingsSection: String, Hashable {
    case notifications, privacy, account
}

// Usage in main view
struct MainView: View {
    @State private var router = NavigationRouter()

    var body: some View {
        NavigationStack(path: $router.path) {
            HomeView()
                .navigationDestination(for: AppRoute.self) { route in
                    destinationView(for: route)
                }
        }
        .environment(router)
    }

    @ViewBuilder
    private func destinationView(for route: AppRoute) -> some View {
        switch route {
        case .userList:
            UserListView()
        case .userDetail(let userId):
            UserDetailView(userId: userId)
        case .userEdit(let userId):
            UserEditView(userId: userId)
        case .settings:
            SettingsView()
        case .settingsDetail(let section):
            SettingsDetailView(section: section)
        }
    }
}

āļĢāļđāļ›āđāļšāļšāļ™āļĩāđ‰āļĢāļ§āļĄāļĻāļđāļ™āļĒāđŒāļ•āļĢāļĢāļāļ°āļāļēāļĢāļ™āļģāļ—āļēāļ‡āļ—āļąāđ‰āļ‡āļŦāļĄāļ” āļ—āļģāđƒāļŦāđ‰āļāļēāļĢāļ—āļ”āļŠāļ­āļšāļŦāļ™āđˆāļ§āļĒāđāļĨāļ°āļāļēāļĢāļšāļģāļĢāļļāļ‡āļĢāļąāļāļĐāļēāļ‡āđˆāļēāļĒāļ‚āļķāđ‰āļ™

āļĢāļđāļ›āđāļšāļšāļāļēāļĢāļ™āļģāļ—āļēāļ‡āļ‚āļąāđ‰āļ™āļŠāļđāļ‡

Deep link āļŠāđˆāļ§āļĒāđ€āļ›āļīāļ”āđāļ­āļ›āļžāļĨāļīāđ€āļ„āļŠāļąāļ™āđ„āļ›āļĒāļąāļ‡āļŦāļ™āđ‰āļēāļˆāļ­āļ—āļĩāđˆāļĢāļ°āļšāļļāđ„āļ”āđ‰āđ‚āļ”āļĒāļ•āļĢāļ‡āļˆāļēāļ URL āļ āļēāļĒāļ™āļ­āļ āļ”āđ‰āļ§āļĒ NavigationStack āļŠāļēāļĄāļēāļĢāļ–āļŠāļĢāđ‰āļēāļ‡āļŠāđāļ•āđ‡āļāļ‚āļķāđ‰āļ™āđƒāļŦāļĄāđˆāđ„āļ”āđ‰āļ”āđ‰āļ§āļĒāđ‚āļ›āļĢāđāļāļĢāļĄ

DeepLinkHandler.swiftswift
@Observable
class DeepLinkHandler {
    var router: NavigationRouter

    init(router: NavigationRouter) {
        self.router = router
    }

    // Parse a URL and navigate to destination
    func handle(url: URL) {
        guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
              let host = components.host else {
            return
        }

        // Build navigation stack according to URL
        let routes = parseRoutes(host: host, path: components.path, queryItems: components.queryItems)
        router.navigateToPath(routes)
    }

    private func parseRoutes(host: String, path: String, queryItems: [URLQueryItem]?) -> [AppRoute] {
        // myapp://users/42/edit → [.userList, .userDetail(42), .userEdit(42)]
        switch host {
        case "users":
            return parseUserPath(path)
        case "settings":
            return parseSettingsPath(path)
        default:
            return []
        }
    }

    private func parseUserPath(_ path: String) -> [AppRoute] {
        let segments = path.split(separator: "/").map(String.init)
        var routes: [AppRoute] = [.userList]

        if let userIdString = segments.first, let userId = Int(userIdString) {
            routes.append(.userDetail(userId: userId))

            // /users/42/edit
            if segments.count > 1 && segments[1] == "edit" {
                routes.append(.userEdit(userId: userId))
            }
        }

        return routes
    }

    private func parseSettingsPath(_ path: String) -> [AppRoute] {
        var routes: [AppRoute] = [.settings]

        let segments = path.split(separator: "/").map(String.init)
        if let sectionString = segments.first,
           let section = SettingsSection(rawValue: sectionString) {
            routes.append(.settingsDetail(section))
        }

        return routes
    }
}

// In the main App
@main
struct MyApp: App {
    @State private var router = NavigationRouter()
    @State private var deepLinkHandler: DeepLinkHandler?

    var body: some Scene {
        WindowGroup {
            MainView()
                .environment(router)
                .onOpenURL { url in
                    // Handle deep links
                    deepLinkHandler?.handle(url: url)
                }
                .onAppear {
                    deepLinkHandler = DeepLinkHandler(router: router)
                }
        }
    }
}

āļ„āļģāļ–āļēāļĄāļ—āļĩāđˆ 5: āļˆāļ°āđ€āļāđ‡āļšāđāļĨāļ°āļāļđāđ‰āļ„āļ·āļ™āļŠāļ–āļēāļ™āļ°āļāļēāļĢāļ™āļģāļ—āļēāļ‡āļ­āļĒāđˆāļēāļ‡āđ„āļĢ?

āļāļēāļĢāđ€āļāđ‡āļšāļŠāļ–āļēāļ™āļ°āļāļēāļĢāļ™āļģāļ—āļēāļ‡āļŠāđˆāļ§āļĒāđƒāļŦāđ‰āļāļđāđ‰āļ„āļ·āļ™āļ•āļģāđāļŦāļ™āđˆāļ‡āļ‚āļ­āļ‡āļœāļđāđ‰āđƒāļŠāđ‰āđ„āļ”āđ‰āļŦāļĨāļąāļ‡āļˆāļēāļāđ€āļĢāļīāđˆāļĄāļ•āđ‰āļ™āđāļ­āļ›āđƒāļŦāļĄāđˆ NavigationPath āļĢāļ­āļ‡āļĢāļąāļš Codable āļŠāļģāļŦāļĢāļąāļšāļāļēāļĢāļ‹āļĩāđ€āļĢāļĩāļĒāļĨāđ„āļĨāđ€āļ‹āļŠāļąāļ™

NavigationPersistence.swiftswift
// Extension to make NavigationPath persistable
extension NavigationPath {
    // Encode path to Data
    func encoded() -> Data? {
        guard let representation = self.codable else { return nil }
        return try? JSONEncoder().encode(representation)
    }

    // Decode from Data
    static func decoded(from data: Data) -> NavigationPath? {
        guard let representation = try? JSONDecoder().decode(
            NavigationPath.CodableRepresentation.self,
            from: data
        ) else {
            return nil
        }
        return NavigationPath(representation)
    }
}

// Router with persistence
@Observable
class PersistentNavigationRouter {
    var path: NavigationPath {
        didSet {
            saveState()
        }
    }

    private let storageKey = "navigation_path"

    init() {
        // Restore state at startup
        if let data = UserDefaults.standard.data(forKey: storageKey),
           let restored = NavigationPath.decoded(from: data) {
            self.path = restored
        } else {
            self.path = NavigationPath()
        }
    }

    private func saveState() {
        if let data = path.encoded() {
            UserDefaults.standard.set(data, forKey: storageKey)
        }
    }

    func clearPersistedState() {
        UserDefaults.standard.removeObject(forKey: storageKey)
    }
}
āļ„āļ§āļēāļĄāđ€āļ‚āđ‰āļēāļāļąāļ™āđ„āļ”āđ‰āļāļąāļš Codable

āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰ NavigationPath.codable āļ—āļģāļ‡āļēāļ™āđ„āļ”āđ‰ āļ—āļļāļāļ›āļĢāļ°āđ€āļ āļ—āļ—āļĩāđˆāđ€āļžāļīāđˆāļĄāļĨāļ‡āđƒāļ™ path āļ•āđ‰āļ­āļ‡āđ€āļ›āđ‡āļ™ Codable āļ™āļ­āļāļˆāļēāļ Hashable āļĄāļīāļ‰āļ°āļ™āļąāđ‰āļ™āļžāļĢāđ‡āļ­āļžāđ€āļžāļ­āļĢāđŒāļ•āļĩ codable āļˆāļ°āļ„āļ·āļ™āļ„āđˆāļē nil

āļžāļĢāđ‰āļ­āļĄāļ—āļĩāđˆāļˆāļ°āļžāļīāļŠāļīāļ•āļāļēāļĢāļŠāļąāļĄāļ āļēāļĐāļ“āđŒ iOS āđāļĨāđ‰āļ§āļŦāļĢāļ·āļ­āļĒāļąāļ‡āļ„āļĢāļąāļš?

āļāļķāļāļāļ™āļ”āđ‰āļ§āļĒāļ•āļąāļ§āļˆāļģāļĨāļ­āļ‡āđāļšāļšāđ‚āļ•āđ‰āļ•āļ­āļš, flashcards āđāļĨāļ°āđāļšāļšāļ—āļ”āļŠāļ­āļšāđ€āļ—āļ„āļ™āļīāļ„āļ„āļĢāļąāļš

āļ„āļģāļ–āļēāļĄāļ—āļĩāđˆ 6: āļˆāļ°āļˆāļąāļ”āļāļēāļĢāļāļēāļĢāļ™āļģāļ—āļēāļ‡āļĢāđˆāļ§āļĄāļāļąāļšāđ‚āļŸāļĨāļ§āđŒāļāļēāļĢāļĒāļ·āļ™āļĒāļąāļ™āļ•āļąāļ§āļ•āļ™āļ­āļĒāđˆāļēāļ‡āđ„āļĢ?

āđ‚āļŸāļĨāļ§āđŒāļāļēāļĢāļĒāļ·āļ™āļĒāļąāļ™āļ•āļąāļ§āļ•āļ™āļĄāļąāļāļ•āđ‰āļ­āļ‡āđ€āļ›āļĨāļĩāđˆāļĒāļ™āđ€āļŠāđ‰āļ™āļ—āļēāļ‡āđ„āļ›āļĒāļąāļ‡āļŦāļ™āđ‰āļēāļˆāļ­āļ—āļĩāđˆāđ„āļ”āđ‰āļĢāļąāļšāļāļēāļĢāļ›āđ‰āļ­āļ‡āļāļąāļ™āļŦāļĨāļąāļ‡āļˆāļēāļāđ€āļ‚āđ‰āļēāļŠāļđāđˆāļĢāļ°āļšāļš āļŦāļĢāļ·āļ­āļāļĨāļąāļšāđ„āļ›āļĒāļąāļ‡āļŦāļ™āđ‰āļēāđ€āļ‚āđ‰āļēāļŠāļđāđˆāļĢāļ°āļšāļšāļŦāļĨāļąāļ‡āļ­āļ­āļāļˆāļēāļāļĢāļ°āļšāļš āļĢāļđāļ›āđāļšāļšāļ•āđˆāļ­āđ„āļ›āļ™āļĩāđ‰āļˆāļąāļ”āļāļēāļĢāļāļēāļĢāđ€āļ›āļĨāļĩāđˆāļĒāļ™āļœāđˆāļēāļ™āđ€āļŦāļĨāđˆāļēāļ™āļĩāđ‰āđ„āļ”āđ‰āļ­āļĒāđˆāļēāļ‡āđ€āļĢāļĩāļĒāļšāļĢāđ‰āļ­āļĒ

AuthNavigationFlow.swiftswift
enum AuthState {
    case unauthenticated
    case authenticated(User)
}

@Observable
class AuthManager {
    var state: AuthState = .unauthenticated
    var pendingDeepLink: URL?

    func login(email: String, password: String) async throws {
        // Simulated authentication
        let user = try await AuthService.shared.login(email: email, password: password)
        state = .authenticated(user)
    }

    func logout() {
        state = .unauthenticated
    }
}

struct RootView: View {
    @State private var authManager = AuthManager()
    @State private var router = NavigationRouter()

    var body: some View {
        Group {
            switch authManager.state {
            case .unauthenticated:
                // Separate navigation stack for auth
                AuthNavigationStack(authManager: authManager)
            case .authenticated:
                // Main app stack
                MainNavigationStack(router: router, authManager: authManager)
            }
        }
        .onChange(of: authManager.state) { oldState, newState in
            handleAuthStateChange(from: oldState, to: newState)
        }
    }

    private func handleAuthStateChange(from oldState: AuthState, to newState: AuthState) {
        switch (oldState, newState) {
        case (.unauthenticated, .authenticated):
            // Login successful: process pending deep link
            if let pendingURL = authManager.pendingDeepLink {
                DeepLinkHandler(router: router).handle(url: pendingURL)
                authManager.pendingDeepLink = nil
            }
        case (.authenticated, .unauthenticated):
            // Logout: reset navigation
            router.popToRoot()
        default:
            break
        }
    }
}

struct AuthNavigationStack: View {
    let authManager: AuthManager
    @State private var authPath = NavigationPath()

    var body: some View {
        NavigationStack(path: $authPath) {
            LoginView(authManager: authManager)
                .navigationDestination(for: AuthRoute.self) { route in
                    switch route {
                    case .register:
                        RegisterView(authManager: authManager)
                    case .forgotPassword:
                        ForgotPasswordView()
                    }
                }
        }
    }
}

enum AuthRoute: Hashable {
    case register
    case forgotPassword
}

āļ„āļģāļ–āļēāļĄāļ—āļĩāđˆ 7: āļˆāļ°āļ™āļģāļāļēāļĢāļ™āļģāļ—āļēāļ‡āđāļšāļšāđ‚āļĄāļ”āļ­āļĨāđ„āļ›āđƒāļŠāđ‰āļāļąāļš NavigationStack āļ­āļĒāđˆāļēāļ‡āđ„āļĢ?

āđ‚āļĄāļ”āļ­āļĨāđāļĨāļ° sheet āļ•āđ‰āļ­āļ‡āļĄāļĩāļšāļĢāļīāļšāļ—āļāļēāļĢāļ™āļģāļ—āļēāļ‡āļ‚āļ­āļ‡āļ•āļąāļ§āđ€āļ­āļ‡ āļāļēāļĢāļĢāļ§āļĄ NavigationStack āļāļąāļšāļāļēāļĢāđāļŠāļ”āļ‡āļœāļĨāđāļšāļšāđ‚āļĄāļ”āļ­āļĨāļˆāļķāļ‡āļ•āđ‰āļ­āļ‡āļāļēāļĢāļāļēāļĢāļˆāļąāļ”āļāļēāļĢāļŠāļ–āļēāļ™āļ°āļ—āļĩāđˆāđāļĒāļāļ­āļ­āļāļˆāļēāļāļāļąāļ™

ModalNavigation.swiftswift
struct ParentView: View {
    @State private var mainPath = NavigationPath()
    @State private var showSettings = false
    @State private var showUserProfile: User?

    var body: some View {
        NavigationStack(path: $mainPath) {
            ContentView()
                .toolbar {
                    Button("Settings") {
                        showSettings = true
                    }
                }
                .navigationDestination(for: MainRoute.self) { route in
                    MainRouteView(route: route)
                }
        }
        // Sheet with its own NavigationStack
        .sheet(isPresented: $showSettings) {
            SettingsSheet()
        }
        // Conditional sheet based on item
        .sheet(item: $showUserProfile) { user in
            UserProfileSheet(user: user)
        }
    }
}

// Each sheet has its own NavigationStack
struct SettingsSheet: View {
    @Environment(\.dismiss) private var dismiss
    @State private var settingsPath = NavigationPath()

    var body: some View {
        NavigationStack(path: $settingsPath) {
            SettingsListView()
                .navigationTitle("Settings")
                .toolbar {
                    ToolbarItem(placement: .cancellationAction) {
                        Button("Close") {
                            dismiss()
                        }
                    }
                }
                .navigationDestination(for: SettingsSection.self) { section in
                    SettingsDetailView(section: section)
                }
        }
    }
}

// Extension to make User identifiable for sheet(item:)
extension User: Identifiable {}

āļāļēāļĢāļˆāļąāļ”āļāļēāļĢāļŠāļ–āļēāļ™āļ°āđāļĨāļ°āļ„āļ§āļēāļĄāļŠāļēāļĄāļēāļĢāļ–āđƒāļ™āļāļēāļĢāļ—āļ”āļŠāļ­āļš

āļ„āļģāļ–āļēāļĄāļ—āļĩāđˆ 8: āļˆāļ°āđ€āļ‚āļĩāļĒāļ™ unit test āļŠāļģāļŦāļĢāļąāļšāļāļēāļĢāļ™āļģāļ—āļēāļ‡āļ­āļĒāđˆāļēāļ‡āđ„āļĢ?

āļ„āļ§āļēāļĄāļŠāļēāļĄāļēāļĢāļ–āđƒāļ™āļāļēāļĢāļ—āļ”āļŠāļ­āļšāđ€āļ›āđ‡āļ™āļ‚āđ‰āļ­āđ„āļ”āđ‰āđ€āļ›āļĢāļĩāļĒāļšāļŠāļģāļ„āļąāļāļ‚āļ­āļ‡ NavigationStack āļāļēāļĢāđāļĒāļ router āļ­āļ­āļāļĄāļēāļŠāđˆāļ§āļĒāđƒāļŦāđ‰ unit test āļŠāļēāļĄāļēāļĢāļ–āļ•āļĢāļ§āļˆāļŠāļ­āļšāļ•āļĢāļĢāļāļ°āļāļēāļĢāļ™āļģāļ—āļēāļ‡āđ„āļ”āđ‰āđ‚āļ”āļĒāđ„āļĄāđˆāļ•āđ‰āļ­āļ‡āđƒāļŠāđ‰ UI

NavigationTests.swiftswift
// Protocol to abstract the router
protocol NavigationRouterProtocol {
    var pathCount: Int { get }
    func navigateTo(_ destination: AppRoute)
    func goBack()
    func popToRoot()
}

// Concrete implementation
@Observable
class AppNavigationRouter: NavigationRouterProtocol {
    var path = NavigationPath()

    var pathCount: Int {
        path.count
    }

    func navigateTo(_ destination: AppRoute) {
        path.append(destination)
    }

    func goBack() {
        guard !path.isEmpty else { return }
        path.removeLast()
    }

    func popToRoot() {
        path.removeLast(path.count)
    }
}

// Unit tests
import XCTest

final class NavigationRouterTests: XCTestCase {
    var router: AppNavigationRouter!

    override func setUp() {
        router = AppNavigationRouter()
    }

    func testNavigateToAddsToPath() {
        // Given
        XCTAssertEqual(router.pathCount, 0)

        // When
        router.navigateTo(.userDetail(userId: 42))

        // Then
        XCTAssertEqual(router.pathCount, 1)
    }

    func testGoBackRemovesLastItem() {
        // Given
        router.navigateTo(.userList)
        router.navigateTo(.userDetail(userId: 1))
        XCTAssertEqual(router.pathCount, 2)

        // When
        router.goBack()

        // Then
        XCTAssertEqual(router.pathCount, 1)
    }

    func testPopToRootClearsPath() {
        // Given
        router.navigateTo(.userList)
        router.navigateTo(.userDetail(userId: 1))
        router.navigateTo(.userEdit(userId: 1))
        XCTAssertEqual(router.pathCount, 3)

        // When
        router.popToRoot()

        // Then
        XCTAssertEqual(router.pathCount, 0)
    }

    func testGoBackOnEmptyPathDoesNothing() {
        // Given
        XCTAssertEqual(router.pathCount, 0)

        // When
        router.goBack()

        // Then
        XCTAssertEqual(router.pathCount, 0) // No crash
    }
}

āļ„āļģāļ–āļēāļĄāļ—āļĩāđˆ 9: āļˆāļ°āļˆāļąāļ”āļāļēāļĢāļŠāļ–āļēāļ™āļ°āļāļēāļĢāļ™āļģāļ—āļēāļ‡āļ—āļĩāđˆāļ‹āļąāļšāļ‹āđ‰āļ­āļ™āđ€āļĄāļ·āđˆāļ­āļĄāļĩāļŦāļĨāļēāļĒāđāļ—āđ‡āļšāļ­āļĒāđˆāļēāļ‡āđ„āļĢ?

āđāļ­āļ›āļžāļĨāļīāđ€āļ„āļŠāļąāļ™āļ—āļĩāđˆāļĄāļĩ TabView āļ•āđ‰āļ­āļ‡āļāļēāļĢāļŠāļ–āļēāļ™āļ°āļāļēāļĢāļ™āļģāļ—āļēāļ‡āļŠāļģāļŦāļĢāļąāļšāđāļ•āđˆāļĨāļ°āđāļ—āđ‡āļš āđāļ•āđˆāļĨāļ°āđāļ—āđ‡āļšāļˆāļ°āļ„āļ‡āļŠāđāļ•āđ‡āļāļ—āļĩāđˆāđ€āļ›āđ‡āļ™āļ­āļīāļŠāļĢāļ°āļ‚āļ­āļ‡āļ•āļąāļ§āđ€āļ­āļ‡āđ„āļ§āđ‰

TabBasedNavigation.swiftswift
// Navigation state for each tab
@Observable
class TabNavigationState {
    var homePath = NavigationPath()
    var searchPath = NavigationPath()
    var profilePath = NavigationPath()
    var selectedTab: Tab = .home

    enum Tab: Hashable {
        case home, search, profile
    }

    func resetCurrentTab() {
        switch selectedTab {
        case .home:
            homePath.removeLast(homePath.count)
        case .search:
            searchPath.removeLast(searchPath.count)
        case .profile:
            profilePath.removeLast(profilePath.count)
        }
    }

    func resetAllTabs() {
        homePath.removeLast(homePath.count)
        searchPath.removeLast(searchPath.count)
        profilePath.removeLast(profilePath.count)
    }
}

struct TabRootView: View {
    @State private var tabState = TabNavigationState()

    var body: some View {
        TabView(selection: $tabState.selectedTab) {
            // Home tab
            NavigationStack(path: $tabState.homePath) {
                HomeView()
                    .navigationDestination(for: HomeRoute.self) { route in
                        HomeRouteView(route: route)
                    }
            }
            .tabItem { Label("Home", systemImage: "house") }
            .tag(TabNavigationState.Tab.home)

            // Search tab
            NavigationStack(path: $tabState.searchPath) {
                SearchView()
                    .navigationDestination(for: SearchRoute.self) { route in
                        SearchRouteView(route: route)
                    }
            }
            .tabItem { Label("Search", systemImage: "magnifyingglass") }
            .tag(TabNavigationState.Tab.search)

            // Profile tab
            NavigationStack(path: $tabState.profilePath) {
                ProfileView()
                    .navigationDestination(for: ProfileRoute.self) { route in
                        ProfileRouteView(route: route)
                    }
            }
            .tabItem { Label("Profile", systemImage: "person") }
            .tag(TabNavigationState.Tab.profile)
        }
        .environment(tabState)
    }
}

āļ„āļģāļ–āļēāļĄāļ—āļĩāđˆ 10: āļˆāļ°āļŦāļĨāļĩāļāđ€āļĨāļĩāđˆāļĒāļ‡āļ›āļąāļāļŦāļēāļ›āļĢāļ°āļŠāļīāļ—āļ˜āļīāļ āļēāļžāļ‚āļ­āļ‡ NavigationStack āļ­āļĒāđˆāļēāļ‡āđ„āļĢ?

āļŠāđāļ•āđ‡āļāļāļēāļĢāļ™āļģāļ—āļēāļ‡āļ‚āļ™āļēāļ”āđƒāļŦāļāđˆāļŦāļĢāļ·āļ­āļ›āļĨāļēāļĒāļ—āļēāļ‡āļ—āļĩāđˆāļ‹āļąāļšāļ‹āđ‰āļ­āļ™āļ­āļēāļˆāļŠāđˆāļ‡āļœāļĨāļ•āđˆāļ­āļ›āļĢāļ°āļŠāļīāļ—āļ˜āļīāļ āļēāļž āļĄāļĩāļŦāļĨāļēāļĒāđ€āļ—āļ„āļ™āļīāļ„āļ—āļĩāđˆāļŠāđˆāļ§āļĒāļ›āļĢāļąāļšāļāļēāļĢāđ€āļĢāļ™āđ€āļ”āļ­āļĢāđŒāđāļĨāļ°āļāļēāļĢāđƒāļŠāđ‰āļŦāļ™āđˆāļ§āļĒāļ„āļ§āļēāļĄāļˆāļģāđƒāļŦāđ‰āđ€āļŦāļĄāļēāļ°āļŠāļĄ

NavigationPerformance.swiftswift
struct OptimizedNavigationStack: View {
    @State private var path = NavigationPath()

    var body: some View {
        NavigationStack(path: $path) {
            LazyContentView()
                // ✅ Lazy-loaded destinations
                .navigationDestination(for: HeavyRoute.self) { route in
                    // View only created on navigation
                    HeavyDetailView(route: route)
                }
        }
    }
}

// ✅ View with lazy content loading
struct LazyContentView: View {
    @State private var items: [Item] = []

    var body: some View {
        // LazyVStack only creates visible views
        ScrollView {
            LazyVStack(spacing: 12) {
                ForEach(items) { item in
                    NavigationLink(value: HeavyRoute.detail(item.id)) {
                        ItemRow(item: item)
                    }
                }
            }
        }
        .task {
            items = await loadItems()
        }
    }
}

// ✅ Detail with progressive loading
struct HeavyDetailView: View {
    let route: HeavyRoute
    @State private var data: DetailData?

    var body: some View {
        Group {
            if let data {
                DetailContent(data: data)
            } else {
                ProgressView()
            }
        }
        .task {
            // Load data only when view appears
            data = await loadDetailData(for: route)
        }
    }
}

// ❌ Avoid: eager creation of heavy views
struct BadNavigationStack: View {
    let allItems: [Item]

    var body: some View {
        NavigationStack {
            List(allItems) { item in
                // Creates all destinations immediately
                NavigationLink {
                    HeavyDetailView(item: item) // ❌ Created upfront
                } label: {
                    ItemRow(item: item)
                }
            }
        }
    }
}
āđāļ™āļ§āļ›āļāļīāļšāļąāļ•āļīāļ—āļĩāđˆāļ”āļĩāļ”āđ‰āļēāļ™āļ›āļĢāļ°āļŠāļīāļ—āļ˜āļīāļ āļēāļž

āļ„āļ§āļĢāđƒāļŠāđ‰ navigationDestination(for:) āđāļ—āļ™ NavigationLink āļ—āļĩāđˆāļĄāļĩāļ›āļĨāļēāļĒāļ—āļēāļ‡āđāļšāļšāļ­āļīāļ™āđ„āļĨāļ™āđŒāđ€āļŠāļĄāļ­ āļĢāļđāļ›āđāļšāļšāđāļĢāļāļˆāļ°āđ‚āļŦāļĨāļ”āļ§āļīāļ§āļ›āļĨāļēāļĒāļ—āļēāļ‡āđ€āļ‰āļžāļēāļ°āđ€āļĄāļ·āđˆāļ­āđ€āļāļīāļ”āļāļēāļĢāļ™āļģāļ—āļēāļ‡āļˆāļĢāļīāļ‡āđ€āļ—āđˆāļēāļ™āļąāđ‰āļ™

āļšāļ—āļŠāļĢāļļāļ›

NavigationStack āđ€āļ›āļĨāļĩāđˆāļĒāļ™āļ§āļīāļ˜āļĩāļˆāļąāļ”āļāļēāļĢāļāļēāļĢāļ™āļģāļ—āļēāļ‡āđƒāļ™ SwiftUI āļ”āđ‰āļ§āļĒāļāļēāļĢāļĄāļ­āļšāļāļēāļĢāļ„āļ§āļšāļ„āļļāļĄāđ€āļŠāļīāļ‡āđ‚āļ›āļĢāđāļāļĢāļĄāļ—āļĩāđˆāļŠāļĄāļšāļđāļĢāļ“āđŒ āļāļēāļĢāđ€āļŠāļĩāđˆāļĒāļ§āļŠāļēāļāļĢāļđāļ›āđāļšāļšāđ€āļŦāļĨāđˆāļēāļ™āļĩāđ‰ āļ•āļąāđ‰āļ‡āđāļ•āđˆāļāļēāļĢāļ™āļģāļ—āļēāļ‡āļžāļ·āđ‰āļ™āļāļēāļ™āđ„āļ›āļˆāļ™āļ–āļķāļ‡ deep link āđāļĨāļ°āļāļēāļĢāđ€āļāđ‡āļšāļŠāļ–āļēāļ™āļ° āļ—āļģāđƒāļŦāđ‰āļ™āļąāļāļžāļąāļ’āļ™āļē iOS āļ—āļĩāđˆāļĄāļĩāļ›āļĢāļ°āļŠāļšāļāļēāļĢāļ“āđŒāđ‚āļ”āļ”āđ€āļ”āđˆāļ™āđƒāļ™āļāļēāļĢāļŠāļąāļĄāļ āļēāļĐāļ“āđŒ

āļĢāļēāļĒāļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļš

  • ✅ āđ€āļ‚āđ‰āļēāđƒāļˆāļ„āļ§āļēāļĄāđāļ•āļāļ•āđˆāļēāļ‡āļĢāļ°āļŦāļ§āđˆāļēāļ‡ NavigationView āđāļĨāļ° NavigationStack
  • ✅ āđƒāļŠāđ‰ NavigationPath āļŠāļģāļŦāļĢāļąāļšāļāļēāļĢāļ™āļģāļ—āļēāļ‡āđ€āļŠāļīāļ‡āđ‚āļ›āļĢāđāļāļĢāļĄāđ€āļ›āđ‡āļ™
  • ✅ āļ•āļīāļ”āļ•āļąāđ‰āļ‡ router āđāļšāļšāļĢāļ§āļĄāļĻāļđāļ™āļĒāđŒāļŠāļģāļŦāļĢāļąāļšāļāļēāļĢāļ™āļģāļ—āļēāļ‡
  • ✅ āļˆāļąāļ”āļāļēāļĢ deep link āļžāļĢāđ‰āļ­āļĄāļāļēāļĢāļŠāļĢāđ‰āļēāļ‡āļŠāđāļ•āđ‡āļāļ‚āļķāđ‰āļ™āđƒāļŦāļĄāđˆ
  • ✅ āđ€āļāđ‡āļšāđāļĨāļ°āļāļđāđ‰āļ„āļ·āļ™āļŠāļ–āļēāļ™āļ°āļāļēāļĢāļ™āļģāļ—āļēāļ‡āļ”āđ‰āļ§āļĒ Codable
  • ✅ āđāļĒāļāđ‚āļŸāļĨāļ§āđŒāļāļēāļĢāļĒāļ·āļ™āļĒāļąāļ™āļ•āļąāļ§āļ•āļ™āļ­āļ­āļāļˆāļēāļāļāļēāļĢāļ™āļģāļ—āļēāļ‡āļŦāļĨāļąāļ
  • ✅ āđƒāļŠāđ‰āđ‚āļĄāļ”āļ­āļĨāļĢāđˆāļ§āļĄāļāļąāļš NavigationStack āđ„āļ”āđ‰āļ­āļĒāđˆāļēāļ‡āļ–āļđāļāļ•āđ‰āļ­āļ‡
  • ✅ āđ€āļ‚āļĩāļĒāļ™ unit test āļŠāļģāļŦāļĢāļąāļšāļ•āļĢāļĢāļāļ°āļāļēāļĢāļ™āļģāļ—āļēāļ‡
  • ✅ āļˆāļąāļ”āļāļēāļĢāļāļēāļĢāļ™āļģāļ—āļēāļ‡āđāļšāļšāļŦāļĨāļēāļĒāđāļ—āđ‡āļšāļ”āđ‰āļ§āļĒ TabView
  • ✅ āļ›āļĢāļąāļšāļ›āļĢāļ°āļŠāļīāļ—āļ˜āļīāļ āļēāļžāļŠāļģāļŦāļĢāļąāļšāļŠāđāļ•āđ‡āļāļāļēāļĢāļ™āļģāļ—āļēāļ‡āļ‚āļ™āļēāļ”āđƒāļŦāļāđˆ

āđ€āļĢāļīāđˆāļĄāļāļķāļāļ‹āđ‰āļ­āļĄāđ€āļĨāļĒ!

āļ—āļ”āļŠāļ­āļšāļ„āļ§āļēāļĄāļĢāļđāđ‰āļ‚āļ­āļ‡āļ„āļļāļ“āļ”āđ‰āļ§āļĒāļ•āļąāļ§āļˆāļģāļĨāļ­āļ‡āļŠāļąāļĄāļ āļēāļĐāļ“āđŒāđāļĨāļ°āđāļšāļšāļ—āļ”āļŠāļ­āļšāđ€āļ—āļ„āļ™āļīāļ„āļ„āļĢāļąāļš

āđāļ—āđ‡āļ

#swiftui
#ios
#navigation
#interview
#navigationstack

āđāļŠāļĢāđŒ

āļšāļ—āļ„āļ§āļēāļĄāļ—āļĩāđˆāđ€āļāļĩāđˆāļĒāļ§āļ‚āđ‰āļ­āļ‡

āļ„āļģāļ–āļēāļĄāļŠāļąāļĄāļ āļēāļĐāļ“āđŒ MapKit SwiftUI āļŠāļģāļŦāļĢāļąāļšāļ™āļąāļāļžāļąāļ’āļ™āļē iOS

āļŠāļąāļĄāļ āļēāļĐāļ“āđŒ MapKit SwiftUI āđƒāļ™āļ›āļĩ 2026: āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāļ›āļĢāļ°āļāļ­āļš āļāļēāļĢāļ‹āđ‰āļ­āļ™āļ—āļąāļš āđāļĨāļ°āļāļēāļĢāļĢāļ°āļšāļļāļ•āļģāđāļŦāļ™āđˆāļ‡

āđ€āļŠāļĩāđˆāļĒāļ§āļŠāļēāļ MapKit āļ”āđ‰āļ§āļĒ SwiftUI āļŠāļģāļŦāļĢāļąāļšāļāļēāļĢāļŠāļąāļĄāļ āļēāļĐāļ“āđŒ iOS: āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāļ›āļĢāļ°āļāļ­āļšāđāļšāļšāļāļģāļŦāļ™āļ”āđ€āļ­āļ‡ āļāļēāļĢāļ‹āđ‰āļ­āļ™āļ—āļąāļš āļāļēāļĢāļĢāļ°āļšāļļāļ•āļģāđāļŦāļ™āđˆāļ‡ āļāļēāļĢāļ„āđ‰āļ™āļŦāļēāļŠāļ–āļēāļ™āļ—āļĩāđˆ āđāļĨāļ°āļĢāļđāļ›āđāļšāļšāļāļēāļĢāļœāļŠāļēāļ™āļĢāļ§āļĄāļāļąāļš Maps

āļŠāļ–āļēāļ›āļąāļ•āļĒāļāļĢāļĢāļĄāļāļēāļĢāļŠāļĄāļąāļ„āļĢāļŠāļĄāļēāļŠāļīāļ iOS StoreKit 2 āđāļĨāļ°āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļšāđƒāļšāđ€āļŠāļĢāđ‡āļˆ

āļāļēāļĢāļŠāļąāļĄāļ āļēāļĐāļ“āđŒ StoreKit 2: āļāļēāļĢāļˆāļąāļ”āļāļēāļĢāļāļēāļĢāļŠāļĄāļąāļ„āļĢāļŠāļĄāļēāļŠāļīāļāđāļĨāļ°āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļšāđƒāļšāđ€āļŠāļĢāđ‡āļˆ

āđ€āļŠāļĩāđˆāļĒāļ§āļŠāļēāļāļ„āļģāļ–āļēāļĄāļŠāļąāļĄāļ āļēāļĐāļ“āđŒ iOS āđ€āļāļĩāđˆāļĒāļ§āļāļąāļš StoreKit 2 āļāļēāļĢāļˆāļąāļ”āļāļēāļĢāļāļēāļĢāļŠāļĄāļąāļ„āļĢāļŠāļĄāļēāļŠāļīāļ āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļšāđƒāļšāđ€āļŠāļĢāđ‡āļˆ āđāļĨāļ°āļāļēāļĢāļ™āļģāļāļēāļĢāļ‹āļ·āđ‰āļ­āđƒāļ™āđāļ­āļ›āđ„āļ›āđƒāļŠāđ‰ āļžāļĢāđ‰āļ­āļĄāļ•āļąāļ§āļ­āļĒāđˆāļēāļ‡āđ‚āļ„āđ‰āļ” Swift āļ—āļĩāđˆāđƒāļŠāđ‰āļ‡āļēāļ™āđ„āļ”āđ‰āļˆāļĢāļīāļ‡

Vision Framework āđāļĨāļ° CoreML āļŠāļģāļŦāļĢāļąāļš machine learning āļšāļ™āļ­āļļāļ›āļāļĢāļ“āđŒ iOS

Vision Framework āđāļĨāļ° CoreML: āļ„āļģāļ–āļēāļĄāļŠāļąāļĄāļ āļēāļĐāļ“āđŒ iOS āđ€āļĢāļ·āđˆāļ­āļ‡ ML āļšāļ™āļ­āļļāļ›āļāļĢāļ“āđŒ

āđ€āļ•āļĢāļĩāļĒāļĄāļ•āļąāļ§āļŠāļąāļĄāļ āļēāļĐāļ“āđŒ iOS āļ”āđ‰āļ§āļĒāļ„āļģāļ–āļēāļĄāļŠāļģāļ„āļąāļāđ€āļāļĩāđˆāļĒāļ§āļāļąāļš Vision Framework āđāļĨāļ° CoreML: āļāļēāļĢāļĢāļđāđ‰āļˆāļģāļ āļēāļž āļāļēāļĢāļ•āļĢāļ§āļˆāļˆāļąāļšāļ§āļąāļ•āļ–āļļ āđāļĨāļ° ML āļšāļ™āļ­āļļāļ›āļāļĢāļ“āđŒ