Skip to main content

add-native

Public entry point for native device capabilities and native controls — camera, image picker, barcode/QR scanner, document picker, file picker, secure storage, file system, sharing, haptic feedback, PDF generation/viewing, pen/signature capture, background GPS/geolocation tracking, or supported local file workflows — in a Power Apps mobile app. Also owns routing to internal camera/PDF/pen/geolocation implementation helpers and the guidance boundary between native wrappers and Dataverse File/Image host controls.

Quellinformationen

Repository
microsoft/power-platform-skills
Letzte Quellaktivität
7. Oktober 2026 um 11:02
Erkannte Sprache von SKILL.md
Englisch
Sterne
969
Forks
196

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
6 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
add-native
description
Public entry point for native device capabilities and native controls — camera, image picker, barcode/QR scanner, document picker, file picker, secure storage, file system, sharing, haptic feedback, PDF generation/viewing, pen/signature capture, background GPS/geolocation tracking, or supported local file workflows — in a Power Apps mobile app. Also owns routing to internal camera/PDF/pen/geolocation implementation helpers and the guidance boundary between native wrappers and Dataverse File/Image host controls.
user-invocable
true
allowed-tools
Read, Edit, Write, Grep, Glob, Bash, AskUserQuestion
model
sonnet
> **Plugin check**: Run `node "${PLUGIN_ROOT}/scripts/check-version.js"` - if it outputs a message, show it to the user before proceeding. **📋 Shared instructions: [shared-instructions.md](${PLUGIN_ROOT}/shared/shared-instructions.md)** — read first. # Add Native Capability Generate a one-file typed wrapper under `src/native/` for a native device capability that the upstream template already ships. Screens import the wrapper instead of touching Expo modules directly, so the discriminated-union result contract stays consistent across the app. ## Hard rules — do NOT cross these lines 1. **Never run `npx expo install`, `npm install`, or `yarn add` for a native module.** The set of native modules in `package.json` is fixed by the upstream template. Adding a new one breaks the rewrap pipeline (the customer's binary is built from a pre-built base, not from their `package.json`). 2. **Never edit `app.config.js`** — plugins, `ios.infoPlist`, `android.permissions`, or anything else. All native config the template ships is intentional and signed off; arbitrary additions cannot be honored at rewrap time. 3. **Never edit `package.json` `dependencies` for native modules.** Native means the package ships platform source/projects, a podspec, codegen, an Expo module/config plugin, or `react-native.config.js`; a package-name prefix alone is not proof. Pure-JavaScript dependencies are out of scope for `/add-native` and are installed from an approved `JavaScript Dependencies` plan by `/create-mobile-app` or `/edit-app`. 4. **If the requested module isn't actually present in `package.json` — STOP.** That means the upstream template hasn't shipped it yet; do not work around by installing it. ## Routing — `/add-native` is the public entry point Some capabilities have a dedicated implementation helper that does more than a plain wrapper (camera writes scanner/upload helpers; PDF report/viewer helpers enforce local-vs-HTTPS boundaries; pen has native-control-specific validation). Users should still call `/add-native <capability>` for native controls. When a dedicated implementation exists, **run it internally and do not ask the user to run that helper directly**. **Lookup convention:** after normalizing the capability, first check the internal-helper map below. For `camera`, `image-picker`, `barcode-scanner`, and `qr-scanner`, read and execute `${PLUGIN_ROOT}/skills/add-native/add-camera/SKILL.md` inside this `/add-native` invocation. For `pdf-report`, read and execute `${PLUGIN_ROOT}/skills/add-native/add-pdf-report/SKILL.md`. For `pdf-viewer`, read and execute `${PLUGIN_ROOT}/skills/add-native/add-pdf-viewer/SKILL.md`. For `pen-input`, read and execute `${PLUGIN_ROOT}/skills/add-native/add-pen-input/SKILL.md`. For `geolocation`, read and execute `${PLUGIN_ROOT}/skills/add-native/add-geolocation/SKILL.md`. If no helper exists, fall through to this skill's inline wrapper flow. Current dedicated implementations: | Capability | Dedicated skill | Why dedicated | |---|---|---| | `camera`, `take-photo`, `photo`, `expo-camera`, `image-picker`, `gallery`, `expo-image-picker`, `barcode-scanner`, `qr-scanner`, `scanner` | [`add-camera`](add-camera/SKILL.md) internal helper | Owns photo capture, gallery image picking, and barcode/QR scanner controls backed by `expo-camera` / `expo-image-picker` | | `pdf-report`, `pdf-export`, `generate-pdf`, `print-report`, `evidence-packet` | [`add-pdf-report`](add-pdf-report/SKILL.md) internal helper | Generates app-owned local PDFs with `expo-print` and shares them only when `expo-sharing` is present | | `pdf-viewer`, `native-pdf-viewer`, `pdf-control`, `open-pdf`, `@microsoft/power-apps-native-pdf-viewer` | [`add-pdf-viewer`](add-pdf-viewer/SKILL.md) internal helper | Enforces `https://` / `file://` viewer inputs and native viewer result handling | | `pen-input`, `signature`, `ink`, `draw`, `@microsoft/power-apps-native-pen-input` | [`add-pen-input`](add-pen-input/SKILL.md) internal helper | Captures PNG data URI and documents Dataverse Image/File persistence | | `geolocation`, `location-tracking`, `background-location`, `gps-tracking`, `geo-tracking`, `@microsoft/power-apps-native-bglocation` | [`add-geolocation`](add-geolocation/SKILL.md) internal helper | Native background GPS tracking with durable storage and inline Dataverse sync; distinct from one-shot `expo-location` | For every other capability listed below, this skill writes the wrapper directly. ## Native capability gate Before adding any native control or wrapper, apply every gate: classify the intent, resolve the exact package/control from the live `package.json`, confirm it is not runtime-banned, confirm the input/output/storage constraints, then use the matching route below. If any gate fails, the native functionality is not supported for this app version — do not install packages, edit native config, or create fake wrappers. | User intent | Add/use | Required package or control | Do not use / fallback | |---|---|---|---| | Form field bound to a Dataverse File column | Host `<FilePicker>` in screen JSX | `@microsoft/power-apps-native-host` host control | Do not generate document-picker/file-system/sharing wrappers for this field | | Form field bound to a Dataverse Image column | Host `<ImagePicker>` in screen JSX | `@microsoft/power-apps-native-host` host control | Do not use camera/image-picker wrappers for normal form-bound image fields | | Dedicated photo/gallery/scanner workflow | `/add-native camera`, `image-picker`, or `barcode-scanner` | `expo-camera` and/or `expo-image-picker` present | If packages are absent, stop with missing-package guidance | | Pick/import/upload a user-selected PDF/document | `/add-native document-picker`, or host `<FilePicker>` for Dataverse File fields | `expo-document-picker` present, or host File control | Do not treat this as `pdf-report` or native PDF viewer | | Generate/export/print an app-owned report PDF | `/add-native pdf-report` | `expo-print` present | If `expo-print` is absent, do not add PDF report capability | | Share a generated local PDF | `pdfReport.ts` share helper | `expo-sharing` present | If `expo-sharing` is absent, do not render sharing UI | | Open/preview an HTTPS or local file PDF | `/add-native pdf-viewer` | `@microsoft/power-apps-native-pdf-viewer` 0.2.9+ present and input is `https://` or `file://` | Do not pass `content://`, `blob:`, or `http://` URIs to the viewer | | Capture signature, ink, drawing, or sign-off | `/add-native pen-input` | `@microsoft/power-apps-native-pen-input` present | If persisted, plan Dataverse Image/File/child Evidence target first | | Continuous/background GPS tracking with durable Dataverse upload | `/add-native geolocation` | `@microsoft/power-apps-native-bglocation` present | Do not use one-shot `expo-location` for background tracking; do not use the `GeolocationExtension`/HostingSDK path | | Tactile feedback for presses, selections, and operation results | `/add-native haptics` | `expo-haptics` present | Use the typed wrapper and pair every haptic with visible UI feedback | | Store generated PDF/signature artifact | Generated Dataverse services after parent row exists | File/Image column or child Evidence/Attachment table exists | Never put File bytes in create/update JSON | | Native capability not listed in this table | Resolve from `package.json`, then add an inline wrapper only when the matching package is present and not runtime-banned | Exact relevant package present in `package.json` | If no relevant package exists, or the package is runtime-banned, add a transparency note and stop | Handle multi-part requests row-by-row. Example: "capture signature and attach signed report PDF" requires `pen-input`, `pdf-report`, Dataverse artifact storage, and possibly `sharing`; do not add only the native capability while leaving storage or screen states undefined. The map is not closed: for new shipped packages, resolve by capability semantics, use the directly matching package when safe, and ask once only if multiple installed packages plausibly match. ## File/Image Picker Ownership This skill owns native file capability mechanics. Screen builders own only the final JSX placement. There are two different cases: | Case | Correct implementation | Owner | |---|---|---| | Dataverse `File` column | Use `<FilePicker>` from `@microsoft/power-apps-native-host` | screen-builder JSX rule, documented here | | Dataverse `Image` column | Use `<ImagePicker>` from `@microsoft/power-apps-native-host` | screen-builder JSX rule, documented here | | Local device document/file workflow not bound to a Dataverse column | Generate/use `src/native/documentPicker.ts`, `src/native/fileSystem.ts`, and/or `src/native/sharing.ts` wrappers | `/add-native` | | App-generated PDF report workflow | `/add-native` routes internally to `add-pdf-report`; uses `expo-print` and optionally `expo-sharing` only if present | `/add-native` | | Camera capture, gallery image selection, barcode scanner, or QR scanner workflow | `/add-native` routes internally to `add-camera` | `/add-native` | **Dataverse File/Image columns use host controls, not raw Expo modules and not app-specific native wrappers.** When a form field binds to a Dataverse **File** column (`FileAttributeMetadata`), render `<FilePicker>` from `@microsoft/power-apps-native-host`. When it binds to a Dataverse **Image** column (`ImageAttributeMetadata`), render `<ImagePicker>` from `@microsoft/power-apps-native-host`. These controls read accent, surface, and text colors from `PowerAppsProvider` / `ThemeProvider` and produce Dataverse-compatible payloads. ```tsx import { FilePicker, ImagePicker } from '@microsoft/power-apps-native-host'; import type { PickedFileInfo, PickedImageInfo } from '@microsoft/power-apps-native-host'; // Image column — seed preview from Dataverse bytes/base64 and capture upload-ready payload. <ImagePicker label="Site Photo" initialBase64={imageBase64} onImageChange={(image: PickedImageInfo | null) => { /* store image for upload */ }} /> // File column — edit-only pick/replace. <FilePicker label="Specification Sheet" fileName={record.cr123_specsheet_name} onChange={(file: PickedFileInfo) => { /* store file for save */ }} /> // File column — view + replace. <FilePicker label="Specification Sheet" fileName={record.cr123_specsheet_name} onDownload={() => Cr123_inspectionService.downloadFile(id, 'cr123_specsheet')} onChange={(file: PickedFileInfo) => { /* store file for save */ }} /> ``` Save/read pattern for host picker-bound Dataverse columns: ```ts // FILE/IMAGE columns: do not include picker bytes in the PATCH body. // Save normal fields first, then upload through generated service helpers. await Cr123_inspectionService.update(id, { cr123_name: name.trim() }); await Cr123_inspectionService.upload(id, 'cr123_specsheet', file.file, file.name); await Cr123_inspectionService.upload(id, 'cr123_sitephoto', image.file, image.name); // Download helpers are used for read/view scenarios. const fileBytes = await Cr123_inspectionService.downloadFile(id, 'cr123_specsheet'); const imageBytes = await Cr123_inspectionService.downloadImage(id, 'cr123_sitephoto'); ``` Use host `ImagePicker` / `FilePicker` with generated `upload(...)` for persistence and `downloadFile(...)` / `downloadImage(...)` for read/view. Do not use `Service.update(...{ <imageColumn>: base64 })` for picker-driven image/file persistence. Do not use raw `expo-document-picker`, `expo-image-picker`, `expo-file-system`, or `expo-sharing` to build custom UI for Dataverse File/Image columns. Host `FilePicker` and `ImagePicker` already handle permissions, reading, sharing/download affordances, and Dataverse-compatible payload shape. Use `/add-native` wrappers only when the workflow is not a Dataverse File/Image column, for example importing a local PDF for offline parsing, exporting a generated report, saving a local draft packet, or opening a share sheet for an app-generated summary. ## Supported capabilities Apply the Native capability gate above. This table is a known capability-to-package map, not a guarantee that every listed package exists in every template version. | Capability | Module | Wrapper to generate | Notes | |---|---|---|---| | `camera`, `take-photo`, `photo`, `expo-camera` | `expo-camera` | `src/native/camera.ts` | `/add-native` routes internally to `add-camera` | | `image-picker`, `gallery`, `expo-image-picker` | `expo-image-picker` | `src/native/imagePicker.ts` | `/add-native` routes internally to `add-camera` | | `barcode-scanner`, `qr-scanner`, `scanner`, `barcode`, `qr` | `expo-camera` | `src/native/barcodeScanner.tsx` | `/add-native` routes internally to `add-camera` | | `document-picker` | `expo-document-picker` | `src/native/documentPicker.ts` | Picks/imports user-selected files (PDF, docs, etc.) from the device | | `pdf-viewer`, `native-pdf-viewer`, `pdf-control`, `open-pdf`, `@microsoft/power-apps-native-pdf-viewer` | `@microsoft/power-apps-native-pdf-viewer` | `src/native/pdfViewer.ts` | `/add-native` routes internally to `add-pdf-viewer`; 0.2.9+ opens HTTPS URLs and file URIs | | `pdf-report`, `pdf-export`, `generate-pdf`, `print-report`, `evidence-packet` | `expo-print` (+ optional `expo-sharing`) | `src/native/pdfReport.ts` | `/add-native` routes internally to `add-pdf-report`; generated local files are shared only when `expo-sharing` is present, or uploaded to Dataverse | | `pen-input`, `signature`, `ink`, `draw`, `@microsoft/power-apps-native-pen-input` | `@microsoft/power-apps-native-pen-input` | `src/native/penInput.ts` | `/add-native` routes internally to `add-pen-input`; captures PNG data URI | | `geolocation`, `location-tracking`, `background-location`, `gps-tracking`, `geo-tracking`, `@microsoft/power-apps-native-bglocation` | `@microsoft/power-apps-native-bglocation` | `src/native/geolocation.ts` | `/add-native` routes internally to `add-geolocation`; native background tracking + durable Dataverse sync. Distinct from one-shot `location` below | | `secure-store` | `expo-secure-store` | `src/native/secureStore.ts` | | | `file-system` | `expo-file-system` | `src/native/fileSystem.ts` | | | `sharing` | `expo-sharing` | `src/native/sharing.ts` | | | `location` | `expo-location` | `src/native/location.ts` | One-shot/foreground fix only. For continuous background tracking with Dataverse sync, use `geolocation` (`@microsoft/power-apps-native-bglocation`). Use only when the current template package contains `expo-location` | | `biometrics`, `local-authentication` | `expo-local-authentication` | `src/native/biometrics.ts` | Use only when the current template package contains `expo-local-authentication` |
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen