mcpField
A
add-pdf-viewer

add-pdf-viewer

github.com/microsoft開発1.1k128 回インストール今日更新
リポジトリ

add-pdf-viewer について

Power Apps モバイルプロジェクトで、ネイティブ PDF ビューアー用ラッパーを追加・確認する内部スキルです。React Native API を使い、HTTPS URL と、バージョン 0.2.9 以降でローカル `file://` URI を扱います。

主な機能

  1. 01HTTPS PDF URL を開く
  2. 02ローカル file:// PDF を開く
  3. 03対応 URI スキームの検証
  4. 04ネイティブモジュールとビューアーのエラー通知
  5. 05共有・印刷アクション結果の取得

活用シーン

  1. 01リモート PDF レポートの閲覧
  2. 02端末で生成した PDF のプレビュー
  3. 03保存済みローカル PDF の表示
  4. 04アプリ画面でビューアー操作を処理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/microsoft/power-platform-skills --skill add-pdf-viewer

インストール後、Claude Code で/add-pdf-viewerを入力して読み込まれたか確認します。

詳細

📋 共通の手順:[shared-instructions.md](${PLUGIN_ROOT}/shared/shared-instructions.md) — 最初に読んでください。

作業ディレクトリ: プロジェクトの読み取りやコマンドの実行に先立ち、 native-artifact-compatibility.md Step 0 を実行してください。 /add-native で解決された絶対パスの working_dir を引き継ぎ、シェル呼び出しと ファイルツールのすべてをそのディレクトリにバインドしてください。このヘルパーが別のディレクトリから 開始された場合も同様です。

PDF ビューアーを追加する

内部ヘルパーです。 ユーザーは /add-native pdf-viewer、/add-native pdf-control、または /add-native @microsoft/power-apps-native-pdf-viewer を実行してください。機能の解決後、/add-native がここに処理を振り分けます。

ネイティブ PDF ビューアーのラッパーを生成または検証し、ネイティブ React Native API の呼び出し方法を示します。バージョン 0.2.9 以降は、HTTPS の PDF URL とローカルの file:// URI に対応しています。パッケージの README にある HostingSDK / PCF の方法は使用しないでください。これは別のユースケース向けです。

手順

1. アプリを検証する
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
test -f app.config.js && test -f power.config.json && test -f package.json && test -d src || { echo "BLOCKED: working_dir is not an initialized app" >&2; exit 1; }

これに失敗した場合は、まず /create-mobile-app を実行するようユーザーに伝え、停止してください。

2. パッケージがすでに存在することを検証する
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
node -e "const p=require('./package.json'); const m='@microsoft/power-apps-native-pdf-viewer'; if (!p.dependencies?.[m]) { console.error('MISSING: ' + m + ' is not in package.json. The template/app must already ship this native extension. This skill will not install it or edit native config.'); process.exit(1); } let v; try { v=require('./node_modules/' + m + '/package.json').version; } catch { console.error('MISSING_INSTALL: cannot verify the installed ' + m + ' version. Run the project package install first.'); process.exit(1); } const [major,minor,patch]=v.split('.').map(Number); if (!(major > 0 || minor > 2 || (minor === 2 && patch >= 9))) { console.error('UNSUPPORTED_VERSION: ' + m + ' ' + v + ' does not support file:// URIs. Version 0.2.9+ is required.'); process.exit(1); } console.log('OK: native PDF viewer ' + v + ' supports https:// and file://');"

確認に失敗した場合は停止してください。npm install、npx expo install、pod install を実行したり、app.config.js を編集したりしないでください。バージョン 0.2.9 以降は、アプリのネイティブビルドにすでに含まれている必要があります。

2a. 要求された成果物を調整する

何かを書き込んだり再利用したりする前に、 PDF ビューアーの項目について native-artifact-compatibility.md の手順 1~3 を読み、実行してください。 /add-native から現在の承認とモードを引き継いでください。有効なスコープ付き承認を再度求めないでください。 src/native/pdfViewer.ts の openHttpsPdf、PdfViewerResult、要求された オプション/アクション、およびインストール済みのバージョン 0.2.9 以降に対する実際の HTTPS/ローカルファイルの動作を確認してください。HTTPS のみに対応する実装では、要求されたローカルの file:// プレビューに対応できません。エクスポートだけでなく、無効な URI とネイティブモジュールが見つからない場合の処理も確認してください。承認の範囲外に互換性のない成果物がある場合は、所有者に NEEDS_CONTEXT を返すか、単独で実行している場合は確認を求めてください。

3. src/native/pdfViewer.ts を作成または検証する

src/native/pdfViewer.ts に対する手順 2a の判断を適用してください。要求されていて見つからない場合は作成し、互換性がある場合に限り変更せず再利用するか、承認された範囲内の更新のみを行ってください。 カスタムコード、エクスポート、呼び出し元を保持してください。サンプルで上書きしないでください。

ラッパーは必ず次の要件を満たす必要があります。

  • https:// URL と file:// URI を受け付ける。
  • ネイティブコードの呼び出し前に、content://、blob:、http://、空の URL、形式が正しくない URL を拒否する。
  • 判別可能なユニオン型を返し、例外をスローしない。
  • JavaScript 側に拡張機能がインストールされているものの、ネイティブビルドでは利用できない場合に NATIVE_MODULE_MISSING を返す。
  • 利用可能な場合は、ビューアーのアクション結果(shared、printed、dismissed)を通知する。
  • 検証やモジュールのチェックで処理されないネイティブエラーには VIEWER_FAILED を返す。
// src/native/pdfViewer.ts
import { NativePdfViewer } from '@microsoft/power-apps-native-pdf-viewer';

export type PdfViewerResult =
  | { ok: true; action?: 'shared' | 'printed' | 'dismissed' }
  | { ok: false; reason: 'INVALID_URL' | 'NATIVE_MODULE_MISSING' | 'VIEWER_FAILED'; message?: string };

export async function openHttpsPdf(
  url: string,
  options?: { title?: string; maxFileSizeMb?: number; cacheEnabled?: boolean },
): Promise<PdfViewerResult> {
  let parsed: URL;
  try {
    parsed = new URL(url);
  } catch {
    return { ok: false, reason: 'INVALID_URL', message: 'PDF location must be a valid https:// URL or file:// URI.' };
  }

  const isHttpsUrl = parsed.protocol === 'https:';
  const isFileUri = parsed.protocol === 'file:' && url.startsWith('file://') && parsed.pathname !== '/';
  if (!isHttpsUrl && !isFileUri) {
    return { ok: false, reason: 'INVALID_URL', message: 'Native PDF viewer supports https:// and file:// inputs only.' };
  }

  if (!NativePdfViewer?.openPdf) {
    return { ok: false, reason: 'NATIVE_MODULE_MISSING', message: 'Native PDF viewer module is not available in this build.' };
  }

  try {
    const response = await NativePdfViewer.openPdf(url, {
      maxFileSizeMb: 50,
      cacheEnabled: true,
      ...options,
    });

    if (response.status === 'ok') {
      return { ok: true, action: response.result?.action };
    }

    return { ok: false, reason: 'VIEWER_FAILED', message: response.message ?? response.error };
  } catch (error: any) {
    return { ok: false, reason: 'VIEWER_FAILED', message: error?.message ?? String(error) };
  }
}
4. ラッパーを使用する

所有者向けの統合ガイダンスです。このヘルパーでは画面を編集しないでください。

画面からネイティブパッケージを直接インポートせず、ラッパーをインポートしてください。

import { openHttpsPdf } from '@/native/pdfViewer';

const response = await openHttpsPdf('https://example.com/report.pdf', {
  title: "Inspection report",
});

if (response.ok) {
  switch (response.action) {
    case "shared":
      // User completed native Share.
      break;
    case "printed":
      // User completed native Print.
      break;
    case "dismissed":
      // User closed the viewer.
      break;
  }
} else {
  console.warn("Failed to open PDF:", response.reason, response.message);
}

注意:

  • URL には https://、または空でない file:// URI を使用してください。このスキルでは content://、blob:、http:// に対応していません。
  • @microsoft/power-apps-native-pdf-viewer は、このネイティブ PDF ビューアーのユースケースにのみ使用してください。
  • ローカルの PDF やドキュメントの選択/インポート/アップロードには expo-document-picker を使用してください。
  • ローカル PDF を生成するには /add-native pdf-report を使用してください。このヘルパーには expo-print が必要です。また、共有機能を追加するのは expo-sharing がすでに存在する場合のみです。
  • expo-print で生成したローカル PDF は、ネイティブ PDF ビューアー 0.2.9 以降で file:// URI として開けます。
  • 共有と印刷の機能はネイティブビューアーに組み込まれており、個別の JS 共有/印刷呼び出しはありません。
  • ラッパーは { ok: true } | { ok: false } を返します。成功以外のすべての理由を UI で処理してください。
5. 型チェック
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
npx --no-install tsc --noEmit

対象範囲内のヘルパーエラーのみを修正してから、共有互換性コントラクトの ステップ 4 を実行します。要求された入力/オプション/アクション、無効な URI の拒否、ネイティブモジュールの欠落、ビューアーの失敗を再確認します。 型チェックが成功しただけでは不十分です。画面ファイルや生成ファイルは 修正しないでください。

6. ネイティブ再ビルドに関する注意

このスキルではネイティブコードをインストールしません。パッケージをこの スキルの実行外で追加したばかりの場合は、このワークフローの実行外で アプリをネイティブ再ビルドする必要があります。パッケージがすでに ビルドに含まれている場合、ラッパーの編集には Metro のホットリロードで 十分です。

7. HostingSDK / PCF を使用しない

次のものはインポートまたは登録しないでください。

import NativePdfViewerExtension from "@microsoft/power-apps-native-pdf-viewer";

Companion PCF や NativePdfViewerExtension を接続しないでください。 Power Apps のネイティブコードアプリでは、上記のネイティブ React Native API を使用します。

8. 概要

この概要の前に、共有互換性の結果と、実際に作成/更新/再利用したパスを 返してください。成功した場合にのみ memory-bank を更新し、オーケストレー ションされた場合は、最終更新をオーナーに任せてください。

ユーザーに次のように伝えてください。

PDF viewer added
Package present   : @microsoft/power-apps-native-pdf-viewer
Wrapper           : src/native/pdfViewer.ts
URL support       : HTTPS and file:// (0.2.9+)
Type-check        : PASS
Native rebuild    : not performed by this skill
Usage             : openHttpsPdf(...)
HostingSDK / PCF  : not used

memory-bank.md の Controls の下を更新してください。

- PDF viewer added — @microsoft/power-apps-native-pdf-viewer (<ISO date>)

コメント