Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 24 additions & 9 deletions NetworkBackendGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ PeerConnectivity is migrating toward Apple's Network framework while preserving

The Network backend is not the default runtime path yet. Treat it as an experimental/beta backend for apps that can validate behavior in their own topology and OS/device matrix.

Use it when you need to evaluate the Network framework migration path for reliable local peer messaging. Continue using the default MultipeerConnectivity backend when you need browser UI, stream transfer, resource transfer, or proven production parity.
Use it when you need to evaluate the Network framework migration path for reliable local peer messaging. Continue using the default MultipeerConnectivity backend when you need the system-provided browser UI, stream transfer, resource transfer, or proven production parity.

## Requirements

Expand Down Expand Up @@ -68,21 +68,30 @@ Supported. Peers advertise and browse for the same service type, then attempt to

### `.custom`

Supported for app-owned peer selection. Use `PeerBrowserModel` to track discovered peers, render them in app UI, then call `invitePeer` for the selected peer:
Supported for app-owned peer selection. `PeerBrowserModel` is the supported Network replacement foundation for `MCBrowserViewController` during this migration phase. It tracks discovered peers and connection status without prescribing UIKit or SwiftUI presentation.

For example, an app-owned table view controller can bind the model to its own state and invite only after selection:

```swift
let browserModel = PeerBrowserModel(manager: manager) { discoveredPeers in
// Called on the main queue; render `discoveredPeers` in app UI.
private var discoveredPeers : [Peer] = []
private lazy var browserModel = PeerBrowserModel(manager: manager) { [weak self] peers in
self?.discoveredPeers = peers
self?.tableView.reloadData() // Callback is delivered on the main queue.
}

browserModel.startObserving()
override func viewDidLoad() {
super.viewDidLoad()
browserModel.startObserving()
manager.start()
}

// Later, after user/app approval:
if let selectedPeer = browserModel.discoveredPeers.first {
browserModel.invitePeer(selectedPeer)
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
browserModel.invitePeer(discoveredPeers[indexPath.row])
}
```

Own selection, empty/error states, accessibility, styling, and the model lifecycle in the app. Call `stopObserving()` when observation should end; the model also stops observing on deinitialization.

For Network-backed managers, `invitePeer(_:withContext:timeout:)` uses the discovered peer endpoint. The `context` and `timeout` parameters are currently ignored.

### `.inviteOnly`
Expand All @@ -91,6 +100,12 @@ The built-in MultipeerConnectivity advertiser assistant/browser UI is not availa

`PeerConnectivityUI.browserViewController` returns `nil` for Network-backed managers.

## Browser UI decision

A reusable SwiftUI or UIKit Network browser is intentionally deferred. Peer selection is product-specific, and the migration does not yet have enough app usage to establish stable shared behavior for selection, cancellation, connection progress, errors, accessibility, or presentation. Adding that surface now would increase UI and compatibility scope while the Network backend remains opt-in.

`PeerBrowserModel` is therefore the supported app-owned UI foundation for this phase. The MultipeerConnectivity-only `MCBrowserViewController` compatibility path remains unchanged, and no backend default changes as part of this decision. A reusable component can be reconsidered after app-owned integrations validate common requirements.

## API support matrix

| API / behavior | MultipeerConnectivity backend | Network backend |
Expand Down Expand Up @@ -199,7 +214,7 @@ xcodebuild test -project PeerConnectivity.xcodeproj \
## Known follow-ups

- Revisit public Network connection policy configuration after more device and CI validation.
- Evaluate a reusable Network-native browser component after app-owned `PeerBrowserModel` usage is validated.
- Reconsider a reusable Network-native browser component only after app-owned `PeerBrowserModel` integrations establish common UI requirements.
- Decide whether to implement Network equivalents for streams and resource transfer or document them as MultipeerConnectivity-only long term.
- Strengthen identity binding beyond shared-key group membership for apps that require per-peer authentication.
- Continue monitoring Bonjour/Network.framework E2E behavior in CI and split or gate slow tests if they become flaky.
22 changes: 11 additions & 11 deletions NetworkFrameworkMigrationPlan.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Most public event types are already framework-neutral, which makes an incrementa
| `MCSession.send` | `NWConnection.send` + message framing | Network does not preserve message boundaries automatically. |
| Resource transfer | Custom protocol over `NWConnection` | Later slice; potentially file chunks/progress messages. |
| Stream transfer | Custom stream abstraction or compatibility shim | Later slice; no one-to-one replacement. |
| `MCBrowserViewController` | Custom PeerConnectivityUI browser | Required for UI package. |
| `MCBrowserViewController` | `PeerBrowserModel` + app-owned UI | Reusable PeerConnectivityUI replacement deferred pending app validation. |

Relevant Network framework APIs:

Expand Down Expand Up @@ -193,22 +193,22 @@ Acceptance criteria:
- MC-specific public API is marked deprecated before removal.
- Migration guide explains breaking changes and fallback behavior.

### Phase 6 — PeerConnectivityUI replacement
### Phase 6 — App-owned browser UI foundation

Objective: replace `MCBrowserViewController` usage.
Objective: support Network peer selection without prematurely standardizing reusable UI behavior.

Tasks:
Decision:

1. Build a custom browser UI backed by framework-neutral discovery events.
2. Rework `PeerConnectionManager+UI.swift` so browser UI no longer requires direct `multipeerSession` access for Network-backed managers.
3. Preserve existing PeerConnectivityUI product structure.
4. Add iOS-only tests where feasible.
5. Deprecate or remove MC browser assistant after replacement exists.
- Use the framework-neutral `PeerBrowserModel` as the supported replacement foundation for Network-backed apps.
- Keep rendering, selection, cancellation, progress, errors, accessibility, and presentation app-owned.
- Preserve the existing `MCBrowserViewController` path for the MultipeerConnectivity backend.
- Defer a reusable SwiftUI or UIKit browser until app integrations establish common requirements.

Acceptance criteria:

- UI package no longer depends on `MCBrowserViewController` for Network backend.
- Existing apps can browse/select peers with Network implementation.
- Network-backed apps can observe discovered peers and connection status, then invite an app-approved peer through `PeerBrowserModel`.
- Documentation includes an app-owned UI example and clearly states that reusable browser UI is deferred.
- No default backend or MultipeerConnectivity browser behavior changes.

## Testing Plan

Expand Down
18 changes: 9 additions & 9 deletions NetworkMigrationPRPlan.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,18 @@ Acceptance criteria:
- Require a clear justification for any new layer that remains.
- Prefer net LOC reduction unless tests or docs intentionally increase coverage.

### PR 8: SwiftUI browser replacement
### PR 8: App-owned browser UI foundation

- Add `PeerBrowserView` and `PeerBrowserModel` driven by framework-neutral discovery and connection events.
- Use SwiftUI as the primary browser implementation.
- Provide UIKit bridging through `UIHostingController` or representable wrappers where compatibility requires it.
- Retain and deprecate old `MCBrowserViewController`-specific paths as compatibility shims only.
- Add SwiftUI/UI tests for peer listing, selection, cancellation, and connection state updates.
- Use `PeerBrowserModel`, driven by framework-neutral discovery and connection events, as the supported Network browser foundation.
- Document a concise integration pattern for app-owned peer lists and approval flows.
- Defer a reusable `PeerBrowserView` and UIKit bridge until app integrations establish shared requirements.
- Retain the existing `MCBrowserViewController` path for the MultipeerConnectivity backend.
- Do not change the default backend or add transport/trust behavior in this UI decision.

### PR 9: End-to-end automation and UI testing
### PR 9: End-to-end automation and demo testing

- Add a loopback/local integration harness where possible.
- Add XCUITest coverage for the SwiftUI browser and demo app smoke paths.
- Add UI smoke coverage for the demo's app-owned browser flow when stable automation is practical.
- Add CI automation for stable smoke tests.
- Document manual device checks for Bonjour and Local Network privacy prompts.

Expand All @@ -108,7 +108,7 @@ Security review is mandatory for PRs that change:
- Network listener/connection setup.
- TLS identity, PSK, trust evaluation, or handshake payloads.
- Untrusted input parsing, frame decoding, or peer identity validation.
- SwiftUI browser input, peer selection, or invite flows.
- Reusable browser input, peer selection, or invite flows.
- Public backend selection or default backend behavior.

Before the Network backend is publicly selectable, peer authentication must be explicit rather than relying on self-asserted display names or unauthenticated handshakes.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,22 @@ let filteredBrowserViewController = pcm.browserViewController({ _ in }, peerFilt
})
```

The Network backend does not have an `MCBrowserViewController` equivalent. During this migration phase, `PeerBrowserModel` is the supported foundation for app-owned UIKit or SwiftUI peer-selection UI:

```swift
let browserModel = PeerBrowserModel(manager: pcm) { peers in
// Update app-owned UI; this callback runs on the main queue.
}

browserModel.startObserving()

if let approvedPeer = browserModel.discoveredPeers.first {
browserModel.invitePeer(approvedPeer)
}
```

A reusable Network browser view is intentionally deferred until app-owned integrations establish common UI requirements. See [NetworkBackendGuide.md](NetworkBackendGuide.md#browser-ui-decision) for the decision and lifecycle guidance.

## Demo App

Run `PeerConnectivityDemo.xcodeproj` on two simulators or devices. Before starting, select the
Expand Down
Loading