Skip to main content
All articles
SwiftUIFeatured

Apple Continuity Is Three Different Contracts

Ben Van AkenCo-Founder & CTO8 min read

Continuity is one word covering ten features, from Handoff and Universal Clipboard to Sidecar and iPhone Mirroring. Ask a team whether their app supports Continuity and you get a shrug, and the shrug is correct: the features behind the word do not ask the same thing of an app. Some ask for code. One asks for permission to stop. Several ask for nothing and cannot be refused.

On 23 September 2026 we audited a production SwiftUI and AppKit business app we build, deliberately not named. It had zero NSUserActivity call sites and zero activity types declared in any Info.plist, so it supported no Handoff whatsoever. It also had eight places that wrote customer data to the general pasteboard with no options set, and had therefore been copying that data to the user's other signed-in devices since the day each line was written. Nobody had decided either thing.

That is what a family of features treated as one switch gets you. Continuity is three different contracts wearing one brand name. Almost every mistake comes from applying one contract's rule to another contract's feature, ours included.

Three sourcing rules govern all nine parts. Apple availability figures come from the machine-readable header of each documentation page's markdown variant (append .md to the URL). Archived pages are quoted with Apple's own revision date. Anything resting on a forum thread is labelled a community report: evidence about experience, not about the API contract.

Three postures wearing one brand name

Sort the family by what it asks of your app rather than by what it does for the user, and it falls into three groups:

  1. Opt-in, with an API. Handoff, Continuity Camera import, Shared with You. Nothing happens until you write code and declare something in a plist, and the failure mode is silence: the feature never appears.
  2. Opt-out, on by default. Universal Clipboard. It is already moving your app's data between the user's devices. On iOS the only open question is whether you said no; on macOS you cannot.
  3. No API at all. Sidecar, Universal Control, iPhone Mirroring, Instant Hotspot, Auto Unlock. You can neither adopt them nor refuse them. The only move available is not making assumptions they break.

Contract one: nothing happens until you write code

Handoff has the real API surface, and parts 2 to 6 build it. The whole gate is two conditions, from Apple's archived About Handoff page:

A user activity can be continued only in an app that has the same developer Team ID as the activity's source app and that supports the activity's type.

Apple, About Handoff (archived)

Same team, declared type. The strings go in the NSUserActivityTypes array in Info.plist, available since iOS 8.0 and macOS 10.10. Miss any of it and nothing crashes, nothing logs, no build warning fires: the feature is simply absent, which is very hard to notice in your own product.

Contract two: already running, with your data

Universal Clipboard is the retroactive one. Apple Platform Security states the mechanism and the default in a single breath: it "leverages Handoff to securely transfer the content of a user's clipboard across devices", and clipboard content "is shared by default with Universal Clipboard unless the app developer chooses to disallow sharing".

Read that second clause as the API contract it is: the decision is per item, it belongs to the writing app, and the default is yes. On iOS you opt out with UIPasteboard.OptionsKey.localOnly, available since iOS 10.0:

Swift
let value = "…"

// Syncs to the member's other devices.
UIPasteboard.general.string = value

// Same copy, this device only.
UIPasteboard.general.setItems(
    [["public.utf8-plain-text": value]],
    options: [.localOnly: true]
)

On macOS you cannot. Apple says so on the NSPasteboard reference page:

The general pasteboard… automatically participates with the Universal Clipboard feature in macOS 10.12 and later and in iOS 10.0 and later. There is no macOS API for interacting with this feature.

Apple, NSPasteboard

So whatever your Mac app puts on the general pasteboard goes to the user's other devices, and the mitigations are architectural. Part 7 is the whole story.

Contract three: no API at all

Sidecar, Universal Control, Instant Hotspot and Auto Unlock have neither an adoption API nor a refusal API, and mostly that is fine. iPhone Mirroring is the one worth a decision.

Apple Platform Security describes the user-facing protections: the phone stays locked, a persistent notification shows on its lock screen, and a banner appears on the next unlock. But we searched directly for an app-level analogue of UIScreen.isCaptured and there is none. No way to detect that your app is being mirrored, no way to mark a screen ineligible. For a surface showing other people's confidential data, that is an exposure you cannot mitigate in code.

The family, member by member

The orientation table, condensed to the one thing that decides what you do:

  • Handoff: opt-in. NSUserActivity plus NSUserActivityTypes; same Team ID and a declared type is the entire gate. Parts 2 to 6.
  • Universal Clipboard: opt-out. localOnly on iOS; on macOS, by Apple's own sentence, no API at all. Part 7.
  • Continuity Camera, import: opt-in. NSMenuItem.importFromDeviceIdentifier. Without the menu item the app silently never offers Take Photo, Scan Documents, Add Sketch or Add Markup.
  • Continuity Camera, webcam: largely automatic. AVCaptureDevice.DeviceType.continuityCamera and isContinuityCamera, iOS 17 and macOS 14. Hard-coded device types and stale discovery sessions are how it breaks; part 8.
  • Shared with You: opt-in, with a structural precondition. SWHighlight is a list of universal links, so content behind a login cannot participate.
  • Sidecar: no API. A second display, with a second display's scale and characteristics.
  • Universal Control: nothing to adopt; MDM can restrict it. Pointer and keyboard events, not touch.
  • iPhone Mirroring: no API, no detection, no opt-out. MDM only, and the MDM belongs to the customer.
  • Instant Hotspot and Auto Unlock: no API, no app impact.
  • AirDrop: share-sheet plumbing only, via UIActivityViewController or NSSharingService. A fully custom share flow never appears in AirDrop.

What every member assumes

Two preconditions run under the whole family. The first is identity: Continuity requires the same Apple Account on every participating device. Two devices owned by one person but signed into different accounts will not hand off and will not share a clipboard.

The second is transport. Apple's Handoff security page, last updated 18 February 2021, describes AES-256-GCM encryption with replay protection over Bluetooth Low Energy 4.2, devices paired out of band through APNs, a symmetric 256-bit key in each device's keychain, and larger transfers moving over peer-to-peer Wi-Fi with TLS whose trust derives from iCloud Keychain identities. Quote the date when you cite it: that page has not been revised in five years, and the family has grown since.

Encryption in transit is not a judgement about whether a value should leave the device, or about who is looking at the other screen. Nor is there a provenance API: we looked specifically, and on neither platform can a reading app learn which device wrote what it received.

Three findings the rest of the series turns on

The tutorial parts are real and runnable, but they are not why the series exists. Three findings change a decision:

  1. The iOS receive seam most tutorials teach does not fire for a scene-adopted app, and the three app-delegate continuation methods carry an availability upper bound their scene equivalents do not. macOS is unaffected. Part 3.
  2. Apple does publish a Handoff payload figure. It appears on exactly one archived page, twice, and never on the current reference; what the current reference carries instead is a dedicated too-large error code with no number attached. Part 4.
  3. Universal Clipboard is opt-out and on by default, and on macOS there is no opt-out at all. Not an inference: Apple's own sentence, quoted above. Part 7.

What this series will not be able to tell you

The research treated "looked for and not found" as a result worth recording. Five of those shape what the series may claim:

  • Apple documents no precedence rule for what happens when both an app-delegate and a scene-delegate continuation method are implemented; across every delivery-path page we fetched, there is no such sentence. The behaviour part 3 describes is sourced to community reports and long-standing practice.
  • Nobody has published an empirical measurement of where a Handoff payload actually breaks: no blog, forum thread or answer reporting that activities died reliably above some number of kilobytes. Part 4 argues from Apple's recommendation, and says so.
  • Six forum threads over five years report that SwiftUI's .onContinueUserActivity closure never runs in a macOS app, with no Apple engineer reply, no root cause and no workaround in any of them. Good enough to design defensively around, not good enough to state as an API fact; part 3 labels it that way.
  • There is no automated way to test Handoff that we could find: no CI technique, no sample project, no WWDC session. The practitioner consensus is visible only by absence: two physical devices, one account, and a human. Part 9.
  • No Apple HIG or App Review guidance on pasteboard content sensitivity turned up, in particular nothing addressing an app that handles other people's confidential data. Part 7 reasons without it.

One thing to do before part 2 lands: sort the features you care about into the three groups. Group one is a backlog item, group two is a search for pasteboard writes, group three is a list of assumptions to stop making. Ours produced the two numbers at the top of this article.

Next up (Part 2): Your First NSUserActivity: Handoff in Swiftlands tomorrow

Comments

Loading comments…

Not sure what your app is already sending between devices?

We audit and build Continuity behaviour in production SwiftUI apps: Handoff that lands in the right window, and pasteboard writes that leave the device only when you meant them to. Book a call.

Keep reading

SwiftUIlands tomorrow

Your First NSUserActivity: Handoff in Swift

Part 2 of our Apple Continuity series: the smallest Handoff that works end to end. Build the activity, declare NSUserActivityTypes in every receiving target, advertise and receive it in SwiftUI. The same Team ID plus a declared type is the entire gate.

Ben Van Aken8 min read
SwiftUIlands in 3 days

Where Handoff Actually Arrives on iOS and macOS

Part 3 of our Apple Continuity series. On iOS, a scene-adopted app receives Handoff in scene(_:continue:) and never in the app delegate. The three app-delegate Handoff methods carry an availability upper bound of 26.0; the scene and AppKit equivalents carry none. With the fetch technique behind those figures, the three-callback set, and a snippet that proves which seam fires in your app.

Ben Van Aken10 min read
SwiftUIlands in 13 days

Universal Clipboard: The Continuity Feature You Already Shipped

Part 7 of our Apple Continuity series, and the uncomfortable one. Universal Clipboard rides on Handoff, is opt-out, and is already running in your app: a plain UIPasteboard.general.string on a screen full of someone else's data is a cross-device transfer. iOS has localOnly. macOS, by Apple's own sentence, has no opt-out at all.

Ben Van Aken11 min read