-
Notifications
You must be signed in to change notification settings - Fork 1
Capabilities
What the machine can do — camera, location, photos, biometrics, the network — as services taken through a constructor, realized per host. A component asks for a capability and never learns which target answered.
public sealed class ScanShell(ICamera? camera, ILocation? location) : StatefulComponent
{
private async void LocateAsync()
{
if (location is null) return; // this host has none
var here = await location.GetCurrentAsync();
}
}Nullable, always. A host that cannot do something registers nothing, so the service resolves to
null and the app shows the thing it already knows how to show. That is the framework's answer
everywhere: report the absence rather than pretend with a stub that fails later, at a worse moment.
| Capability | What it answers | Since |
|---|---|---|
IPhotoLibrary |
GetPermissionAsync(), PickImageAsync() — one picture the user chose |
0.2.0-preview.1 |
ICamera |
Capture() for a still, StartPreviewAsync() for an ICameraSession (a live texture) |
0.2.0-preview.1 |
ILocation |
GetCurrentAsync(), and Subscribe(…) for the stream of changes |
0.2.0-preview.1 |
IBiometrics |
IsAvailable, AuthenticateAsync(reason) — Face ID / Touch ID / the platform's own |
0.2.0-preview.1 |
IMotionSensor |
Subscribe(…) for device motion readings |
0.2.0-preview.1 |
INetworkStatus |
Current, and Subscribe(…) — reachability and what carries it |
0.2.0-preview.1 |
ITextClipboard |
Read() / Write(text), for a page's own Copy button |
0.2.0-preview.1 |
IThemeController |
The light/dark switch — see ServerIntegration | 0.2.0-preview.1 |
IAppStorage / ISecretStore
|
Durable preferences and secrets — see Storage | 0.2.0-preview.10 |
ILocation, IMotionSensor and INetworkStatus are the ones whose answer CHANGES, so they hand
back an IDisposable from Subscribe rather than a value. Dispose it when the component goes away,
or the subscription outlives what it was updating.
INetworkStatus reports reachability as the platform sees it, not a promise a specific host will
answer. An app showing a stale "online" is worse than one that says nothing.
PermissionState has four answers, and the third is the one apps forget:
-
NotDetermined— never asked. Asking shows the system prompt. -
Granted. -
Denied— refused, and asking again does nothing. Only the system's settings can change it, so a button that re-asks is a button that does nothing; send them to settings instead. - The platform may also report a restriction the user cannot lift at all.
On native, the strings the OS shows at the prompt come from the assembly:
[assembly: PhotonCapability("camera", "Scan a barcode to add an item.")]The build reads those into the platform's manifest (Info.plist, the Android manifest), so the
reason a user reads is stated once, in the app, next to the code that needs it.
Crosses by NAME, never by ordinal. The manifest matches the capability's string. Inserting a value into the middle of an enum once turned Location into Motion in a shipped manifest — the build was green and the app asked for the wrong permission.
The browser realizes what it honestly can — photos through a file input, camera and location and network through their web APIs — and registers the rest as unavailable rather than absent, so a page that takes one still receives an object and shows its fallback instead of failing to construct.
A page's constructor is not injected on the web yet. The .NET container resolves these when it constructs a component on Photon; the browser's mount constructs a page with no arguments. The web realizations exist and are registered, but a write-once page cannot reach them through its constructor today. See Storage for the same fence stated where it bites first.