<!--
{
  "documentType" : "article",
  "framework" : "watchOS Apps",
  "identifier" : "/documentation/watchOS-Apps/building_a_watchos_app",
  "metadataVersion" : "0.1.0",
  "role" : "article",
  "title" : "Building a watchOS app"
}
-->

# Building a watchOS app

Set up your app’s life cycle and create its user interface with SwiftUI.

## Overview

Develop powerful, personal apps for Apple Watch using SwiftUI, a declarative
framework for building user interfaces on all of Apple’s platforms. You can
create rich user interfaces by composing simple views — which perform a single,
focused task — into larger, more complex layouts. Your app describes the correct
layout for its views based on its current state. SwiftUI detects changes to the
state and updates the views accordingly.

On watchOS, SwiftUI gives you considerably more freedom, power, and control than
user interfaces laid out and designed in a storyboard. For example,
<doc://com.apple.documentation/documentation/SwiftUI/List> has a number of
features that aren’t supported by
<doc://com.apple.documentation/documentation/WatchKit/WKInterfaceTable>, such as
the platter style, swipe actions (shown below), and row reordering.

![A screenshot of a watch face displaying a list. The middle row shows the list’s delete swipe action. The row shifts to the left, revealing a large X.](images/com.apple.watchOS-Apps/building_a_watchos_app-1@2x.png)

Additionally, you can preview your SwiftUI code in Xcode’s canvas. You can
design, build, and test your interfaces without ever running your app.

![A screenshot showing Xcode with the circle image selected in the preview.](images/com.apple.watchOS-Apps/building_a_watchos_app-2@2x.png)

SwiftUI also provides watch-specific representations of tab and navigation
views, with fully customizable navigation bars and customizable toolbar items
for confirmation, cancellation, and destructive actions. You can also use
SwiftUI to manage your app’s life cycle. To learn more about SwiftUI, see
<doc://com.apple.documentation/tutorials/SwiftUI>.

### Set up the root view

To manage your app’s life cycle with SwiftUI, create a structure that adopts the
<doc://com.apple.documentation/documentation/SwiftUI/App> protocol in your
watchOS app target.

```swift
import SwiftUI

@main
struct MyProject_Watch_App: App {
}
```

The
[`@main`](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/attributes)
attribute indicates this is the entry point for your app. Each app can have only
one entry point.

Inside the structure, define the app’s
<doc://com.apple.documentation/documentation/SwiftUI/App/body-swift.property>.
The `body` automatically composes a collection of
<doc://com.apple.documentation/documentation/SwiftUI/Scene> instances into
a single, compound `Scene`.

```swift
@main
struct MyProject_Watch_App: App {
    var body: some Scene {
    }
}
```

Next, add a `Scene` or your app’s root view. For a watchOS app, you typically
create a <doc://com.apple.documentation/documentation/SwiftUI/WindowGroup> scene
that wraps
a <doc://com.apple.documentation/documentation/SwiftUI/NavigationView> around
your app’s root view. The `NavigationView` provides a navigation stack and title
area for your app.

```swift
@main
struct MyProject_Watch_App: App {
    var body: some Scene {
        WindowGroup {
            NavigationView {
                ContentView()
            }
        }
    }
}
```

When your app launches, it displays the view hierarchy defined by the window
group.

You can also add scenes for notification categories.

```swift
var body: some Scene {
    WindowGroup {
        NavigationView {
            ContentView()
        }
    }

    WKNotificationScene(controller: NotificationController.self, category: "myCategory")
}
```

When the system receives a notification with a matching category, it displays
a dynamic view specified by the notification controller. You can create
a <doc://com.apple.documentation/documentation/SwiftUI/WKUserNotificationHostingController>
subclass for each notification category supported by your app.

```swift
import SwiftUI
import UserNotifications

class NotificationController: WKUserNotificationHostingController<NotificationLongLook> {

    var content:UNNotificationContent!
    var date:Date!

    override var body: NotificationLongLook{
        NotificationLongLook(content: content, date: date)
    }

    override class var isInteractive: Bool { true }

    override func didReceive(_ notification: UNNotification) {
        content = notification.request.content
        date = notification.date
    }
}
```

For more information, see [Customizing your long-look interface](/documentation/watchOS-Apps/customizing-your-long-look-interface).

### Respond to app events in SwiftUI

Your app can respond to many app events directly in SwiftUI.

SwiftUI updates the
<doc://com.apple.documentation/documentation/SwiftUI/EnvironmentValues/scenePhase>
environment value as your app changes state. To update a view based on these
changes, you can use the
<doc://com.apple.documentation/documentation/SwiftUI/View/onChange(of:perform:)>
modifier. For more information, see
<doc://com.apple.documentation/documentation/WatchKit/handling-common-state-transitions>.

SwiftUI also provides view modifiers for handling user activity and background
tasks:

- Use
  <doc://com.apple.documentation/documentation/SwiftUI/View/onContinueUserActivity(_:perform:)>
  to handle incoming
  <doc://com.apple.documentation/documentation/Foundation/NSUserActivity>
  objects. For more information, see
  <doc://com.apple.documentation/documentation/WatchKit/handling-user-activity>.
- Use
  <doc://com.apple.documentation/documentation/SwiftUI/Scene/backgroundTask(_:action:)>
  to handle incoming
  <doc://com.apple.documentation/documentation/SwiftUI/BackgroundTask>
  instances. For more information, see
  <doc://com.apple.documentation/documentation/WatchKit/using-background-tasks>.

### Respond to app events using an app delegate

You need an app delegate to handle the following events:

- Life cycle events, like
  <doc://com.apple.documentation/documentation/WatchKit/WKApplicationDelegate/applicationDidFinishLaunching()>,
  that aren’t handled by the
  <doc://com.apple.documentation/documentation/SwiftUI/EnvironmentValues/scenePhase>
  environment variable
- `userInfo` dictionaries from either handoff or complications
- Remote Now Playing activity
- Workout configurations and recovery
- Extended runtime sessions
- Registration of remote notifications

To add an app delegate to your app, create a class that adopts the
<doc://com.apple.documentation/documentation/WatchKit/WKApplicationDelegate> protocol. In this
class, implement the methods needed to handle your app’s events. Then use the
<doc://com.apple.documentation/documentation/SwiftUI/WKApplicationDelegateAdaptor>
property wrapper to declare a variable for your delegate.

```swift
import SwiftUI
import WatchKit

@main
struct MyProject_Watch_App: App {

    @WKApplicationDelegateAdaptor var appDelegate: MyAppDelegate

    var body: some Scene {
        WindowGroup {
            NavigationView {
                ContentView()
            }
        }

        WKNotificationScene(controller: NotificationController.self, category: "myCategory")
    }
}
```

When your app launches, the system instantiates your delegate class and calls
<doc://com.apple.documentation/documentation/WatchKit/WKApplicationDelegate/applicationDidFinishLaunching()>.
Use this method to perform any additional configuration that your delegate
requires. After it returns, the system begins calling your delegate methods when
the corresponding events occur.

## See Also

  <doc://com.apple.documentation/tutorials/SwiftUI/creating-a-watchOS-app>

  <doc://com.apple.documentation/documentation/WatchKit/life-cycles>



---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)