diff --git a/docs/native-community.md b/docs/native-community.md deleted file mode 100644 index 0bd759f18e8..00000000000 --- a/docs/native-community.md +++ /dev/null @@ -1,200 +0,0 @@ ---- -title: Cordova Community Plugins -sidebar_label: Setup -hide_table_of_contents: true -slug: /native/community ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - - - Cordova Plugins | Cordova Community Core Plugins for Ionic Apps - - - -[Apache Cordova](https://cordova.apache.org/) is an open source native runtime that allows developers to build native mobile apps with HTML, CSS, and JavaScript. Similar to [Capacitor](https://capacitorjs.com/), Ionic’s own native runtime, Cordova allows developers to access native device features, such as camera, keyboard, and geolocation, using a system of plugins. A plugin is a small amount of add-on code that provides JavaScript interface to native components. They allow your app to use native device capabilities beyond what is available to pure web apps. - -For developers using Ionic with Cordova, our team has developed a collection of TypeScript wrappers for open source Cordova plugins that make it easy to add native functionality to any Ionic app. See [Ionic Native](https://github.com/ionic-team/ionic-native). - -These plugins are submitted and maintained by the Ionic community. While community members are generally quick to find and fix issues, certain plugins may not function properly. - -For professional developers and teams that require dedicated native plugin support & SLAs, ongoing maintenance, and security patches, please explore our [premium options](https://ionicframework.com/native), including plugin support and pre-built solutions for common native use cases. - - - -:::note -These docs are for apps built with Ionic Framework 4.0.0 and greater. For older Ionic v3 projects, please [see here](https://ionicframework.com/docs/v3/native). -::: - -## Capacitor Support - -In addition to Cordova, Ionic Native also works with [Capacitor](https://capacitorjs.com), Ionic's official native runtime. Basic usage below. For complete details, [see the Capacitor documentation](https://capacitorjs.com/docs/cordova/using-cordova-plugins). - -## Usage - -All plugins have two components - the native code (Cordova) and the TypeScript code (Ionic Native). -Cordova plugins are also wrapped in a `Promise` or `Observable` in order to provide a common plugin interface and modernized development approach. - -Using the [Camera plugin](native/camera.md) as an example, first install it: - -````mdx-code-block - - - -```shell -// Install Cordova plugin -$ ionic cordova plugin add cordova-plugin-camera - -// Install Ionic Native TypeScript wrapper -$ npm install @awesome-cordova-plugins/camera - -// Install Ionic Native core library (once per project) -$ npm install @awesome-cordova-plugins/core -``` - - - - -For complete details, [see the Capacitor documentation](https://capacitorjs.com/docs/cordova/using-cordova-plugins). - -```shell -// Install Ionic Native TypeScript wrapper -$ npm install @awesome-cordova-plugins/camera - -// Install Cordova plugin -$ npm install cordova-plugin-camera - -// Update native platform project(s) to include newly added plugin -$ ionic cap sync -``` - - - -```` - -Next, begin using the plugin, following the various framework usage options below. For FAQ, see [here](native-faq.md). - -## Angular - -Angular apps can use either Cordova or Capacitor to build native mobile apps. Import the plugin in a `@NgModule` and add it to the list of Providers. For Angular, the import path should end with `/ngx`. Angular's change detection is automatically handled. - -```tsx -// app.module.ts -import { Camera } from '@awesome-cordova-plugins/camera/ngx'; - -... - -@NgModule({ - ... - - providers: [ - ... - Camera - ... - ] - ... -}) -export class AppModule { } -``` - -After the plugin has been declared, it can be imported and injected like any other service: - -```tsx -// camera.service.ts -import { Injectable } from '@angular/core'; -import { Camera, CameraOptions } from '@awesome-cordova-plugins/camera/ngx'; - -@Injectable({ - providedIn: 'root', -}) -export class PhotoService { - constructor(private camera: Camera) {} - - takePicture() { - const options: CameraOptions = { - quality: 100, - destinationType: this.camera.DestinationType.DATA_URL, - encodingType: this.camera.EncodingType.JPEG, - mediaType: this.camera.MediaType.PICTURE, - }; - - this.camera.getPicture(options).then( - (imageData) => { - // Do something with the new photo - }, - (err) => { - // Handle error - console.log('Camera issue: ' + err); - } - ); - } -} -``` - -## React - -React apps must use Capacitor to build native mobile apps. However, Ionic Native (and therefore, Cordova plugins) can still be used. - -```shell-session -// Install Core library (once per project) -$ npm install @awesome-cordova-plugins/core - -// Install Ionic Native TypeScript wrapper -$ npm install @awesome-cordova-plugins/barcode-scanner - -// Install Cordova plugin -$ npm install phonegap-plugin-barcodescanner - -// Update native platform project(s) to include newly added plugin -$ ionic cap sync -``` - -Import the plugin object then use its static methods: - -```tsx -import { BarcodeScanner } from '@awesome-cordova-plugins/barcode-scanner'; - -const Tab1: React.FC = () => { - const openScanner = async () => { - const data = await BarcodeScanner.scan(); - console.log(`Barcode data: ${data.text}`); - }; - return ( - - - - Tab 1 - - - - Scan barcode - - - ); -}; -``` - -## Vanilla JavaScript - -Vanilla JavaScript apps, targeting ES2015+ and/or TypeScript, can use either Cordova or Capacitor to build native mobile apps. To use any plugin, import the class from the appropriate package and use its static methods: - -```js -import { Camera } from '@awesome-cordova-plugins/camera'; - -document.addEventListener('deviceready', () => { - Camera.getPicture() - .then((data) => console.log('Took a picture!', data)) - .catch((e) => console.log('Error occurred while taking a picture', e)); -}); -``` diff --git a/docs/native-faq.md b/docs/native-faq.md index 80cb5b1ae89..ceaf06b6d38 100644 --- a/docs/native-faq.md +++ b/docs/native-faq.md @@ -3,83 +3,23 @@ sidebar_label: FAQ slug: /native/faq --- -# Ionic Native FAQ +# Frequently Asked Question -## Cordova Management Tips +## What is Capacitor? -**1) Use the [Ionic CLI](cli.md) to add/update/delete plugins.** +Capacitor a native runtime built by the Ionic team that offers web developers the ability to deploy their web apps to a native device. Capacitor also exposing native device capabilities through JavaScript so developers could access features like native location services, filesystem access, or notifications as if they are interacting with any other JavaScript library. -Instead of directly editing `config.xml` and `package.json`. Use `ionic` in front of Cordova commands for a better experience and additional functionality (`ionic cordova build ios` instead of `cordova build ios`). +## Permission Issues -**2) Upgrade plugins by removing, then re-adding them.** +If you're using a plugin, it may require adding additional permissions to your native project after you install the plugin. For instance, the Capacitor Camera plugin requires the following permission for iOS: -```shell -$ ionic cordova plugin remove cordova-plugin-camera -$ ionic cordova plugin add cordova-plugin-camera -``` +- `NSCameraUsageDescription` (`Privacy - Camera Usage Description`) +- `NSPhotoLibraryAddUsageDescription` (`Privacy - Photo Library Additions Usage Description`) +- `NSPhotoLibraryUsageDescription` (`Privacy - Photo Library Usage Description`) -**3) Install explicit versions.** +You need to manually add those permissions to the `info.plist` in your native project. Otherwise, calls to the native camera API will fail. -To ensure that the same version of a plugin is always installed via `npm install`, specify the version number: -```shell -ionic cordova plugin add cordova-plugin-camera@4.3.2 -``` +## Unexpected behaviour -**4) Restore Cordova in an existing Ionic project** - -Useful when adding new developers to a project. `ionic cordova prepare` restores platforms and plugins from `package.json` and `config.xml`. The version to be installed is taken from `package.json` or `config.xml`, if found in those files. In case of conflicts, `package.json` is given precedence over `config.xml`. - -**5) Troubleshoot Cordova issues with Ionic CLI commands** - -- `ionic doctor list`: Detects [common issues](cli/commands/doctor-list.md) and suggests steps to fix them -- `ionic repair`: Remove, then [regenerate](cli/commands/repair.md) all dependencies - -## Understanding Version Numbers - -For any given Ionic Native plugin, the Ionic Native (TypeScript code) and Cordova (native code) version numbers will not match. The Ionic Native version number is found in `package.json`: - -```json -"@awesome-cordova-plugins/camera": "^5.3.0", -``` - -The Cordova plugin version number is found in both `package.json` and `config.xml`: - -```json -"cordova-plugin-camera": "4.0.3", -``` - -```xml - -``` - -When checking for new native functionality or bug fixes, look for new versions on the Cordova plugin GitHub page itself (here's the [Camera one](https://github.com/apache/cordova-plugin-camera), for example). - -To check for new Ionic Native releases (may include exposing methods recently added by the Cordova plugin, etc.), see [here](https://github.com/ionic-team/ionic-native/releases). - -## Troubleshooting Failed Builds - -Research the build error(s) by checking out these resources: - -- Google & [StackOverflow](https://stackoverflow.com): Many issues are documented online -- Ask the [Ionic Community Ionic Forum](https://forum.ionicframework.com) (see the Ionic Native category) -- See the Ionic Customer Success [Knowledge Base](https://ionic.zendesk.com) - -### Cordova Plugin Conflicts - -Plugins can conflict with each other when they share the same underlying native dependencies or when more than one plugin tries to access the same native code at once. For example, common libraries like the Google Play Services version (Google Maps is using GPS v24.2 but Firebase wants GPS v27.1). Keeping these plugins updated regularly can help with this. - -Another tip is to ensure that your app uses only one plugin per specific feature/functionality (example: Push Notifications). - -## Recommended Upgrade Strategy - -The most Ionic stable apps are routinely updated, especially at the native layer. Keeping native plugins up to date ensures your project has the latest security fixes, new features, and improved performance. - -Update your project's plugins one at a time, ideally in separate code branches. This reduces the surface area that issues can arise from - if you update everything in your project at once, it's sometimes hard to tell where the problem stems from. - -### When should I update? - -- When a new feature/bug is released: Run `npm outdated` to see a list of available updates. -- When new major versions are released: Official blogs, such as the [Cordova blog](https://cordova.apache.org/blog/) and [Ionic blog](https://ionicframework.com/blog/), will publish announcements and news. -- Evaluate the nature of the update: is it a shiny new feature or critical security fix? -- Timing: Where does it fit in against your team's project goals? +If for some reason the plugin does not behave in a way that is unexpected, please [open an issue on our github repo](https://github.com/ionic-team/capacitor-plugins)! Providing a clear issue report along with a reproduction can help get your issue resolved. \ No newline at end of file diff --git a/docs/native-setup.md b/docs/native-setup.md new file mode 100644 index 00000000000..30a8ac5c0fc --- /dev/null +++ b/docs/native-setup.md @@ -0,0 +1,146 @@ +--- +title: Capacitor Plugins +sidebar_label: Setup +hide_table_of_contents: true +slug: /native/setup +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + Capacitor Plugins | Capacitor Core Plugins for Ionic Apps + + + + +Getting started with Capacitor is fairly straight forward for Ionic developers. Adding plugins to your project is no different than adding any dependencies you may need to a project. + + +## Install + +To install a plugin, find the plugin you want to use and install it using your package manager, like npm: + +```shell +# Install the Capacitor Plugins +$ npm install @capacitor/camera +``` + +## Usage + +Once installed, plugins can be imported into a component and you can call the native functionality directly from your code. + +Using the [Camera plugin](native/camera.md) as an example, first install it: + +````mdx-code-block + + + +```javascript +import { Camera, CameraResultType } from '@capacitor/camera'; + +const takePicture = async () => { + const image = await Camera.getPhoto({ + quality: 90, + allowEditing: true, + resultType: CameraResultType.Uri + }); + const imageUrl = image.webPath; + imageElement.src = imageUrl; +}; +``` + + + + +```javascript +import { Component } from '@angular/core'; +import { Camera, CameraResultType } from '@capacitor/camera'; + +@Component({...}) +export class CameraComponent{ + public imageSrc = ''; + + async takePicture() { + const image = await Camera.getPhoto({ + quality: 90, + allowEditing: true, + resultType: CameraResultType.Uri + }); + const imageUrl = image.webPath; + this.imageSrc = imageUrl; + }; + +} +``` + + + + +```typescript + + + + + +``` + + + + +```javascript +import { Camera, CameraResultType } from '@capacitor/camera'; +import { useState } from 'react'; + +export function CameraComponent() { + const [imageSrc, setImageSrc] = usetState(''); + + const takePicture = async () => { + const image = await Camera.getPhoto({ + quality: 90, + allowEditing: true, + resultType: CameraResultType.Uri + }); + const imageUrl = image.webPath; + setImageSrc(imageUrl); + }; + return (...) +} +``` + + + +```` diff --git a/docs/native.md b/docs/native.md index 1c5efecb489..f17ba591bf7 100644 --- a/docs/native.md +++ b/docs/native.md @@ -1,5 +1,5 @@ --- -title: Native APIs +title: Capacitor hide_table_of_contents: true --- @@ -21,33 +21,16 @@ import NativeEnterpriseCard from '@components/page/native/NativeEnterpriseCard'; `} -Build native-powered app experiences with a collection of open source and premium plugins and integrations that make it easy to add native device functionality to any Ionic app with Capacitor or Cordova. - -:::note -[Read about the changes](https://ionicframework.com/blog/a-new-chapter-for-ionic-native/) coming to the Ionic Native project. +Add native functionality to your app with Capacitor, a native runtime built by the Ionic team. Install of the core packages and add them to your project with ease. Capacitor offers a wide range of features and capabilities that developers can use to access features like the file system, native location services, or the device camera. All of this is powered by a unified TypeScript API that handled platform differences automatically. + +While the core features of Capacitor are free and open source, some enterprises might find them selves needing more features or custom third-party integrations. If you find yourself needing these additional features, checkout [Ionic Enterprise SDK](https://ionic.io/enterprise-sdk). + -::: - - -

- A modern, open source native runtime built and maintained by the Ionic team and the Capacitor community. Our - recommended native solution. -

-
- -

- A collection of free Cordova plugins, built and maintained by the community, with TypeScript wrappers and a - consistent API and naming convention. -

-
-
-:::note -These docs are for apps built with Ionic Framework 4.0.0 and greater. For older Ionic v3 projects, please [see here](https://ionicframework.com/docs/v3/native/). -::: +> Looking for older Cordova plugins? Visit their new home at [Awesome Cordova Plugins.](https://danielsogl.gitbook.io/awesome-cordova-plugins/) \ No newline at end of file diff --git a/docusaurus.config.js b/docusaurus.config.js index 4e94c18df89..367494c195b 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -274,7 +274,7 @@ module.exports = { )}.ts`; } if ((match = docPath.match(/native\/(.*)\.md/)) != null) { - return `https://github.com/ionic-team/ionic-native/edit/master/src/@awesome-cordova-plugins/plugins/${match[1]}/index.ts`; + return `https://github.com/ionic-team/capacitor-plugins/edit/main/${match[1]}/README.md`; } return `https://github.com/ionic-team/ionic-docs/edit/main/${versionDocsDirPath}/${docPath}`; }, diff --git a/package-lock.json b/package-lock.json index 235bfd45a15..80d09305544 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8733,8 +8733,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.2.3", - "license": "MIT", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "engines": { "node": ">=8.6" }, @@ -18257,7 +18258,9 @@ "version": "1.0.0" }, "picomatch": { - "version": "2.2.3" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, "pify": { "version": "4.0.1" diff --git a/scripts/native.js b/scripts/native.js index 3be42be73f5..5470930d839 100644 --- a/scripts/native.js +++ b/scripts/native.js @@ -1,164 +1,105 @@ const fs = require('fs'); -const nativeJSON = require('./data/native.json'); -const utils = require('./utils.js'); -const { native: nativeOverrides } = require('./data/meta-override.json'); - -// Filter out some plugins -const filteredPlugins = [ - '@awesome-cordova-plugins/android-fingerprint-auth', - '@awesome-cordova-plugins/fingerprint-aio', - '@awesome-cordova-plugins/app-center-shared', - '@awesome-cordova-plugins/app-update', - '@awesome-cordova-plugins/hot-code-push', - '@awesome-cordova-plugins/in-app-update', - '@awesome-cordova-plugins/checkout', - '@awesome-cordova-plugins/secure-storage-echo', - '@awesome-cordova-plugins/secure-storage', - '@awesome-cordova-plugins/admob-pro', - '@awesome-cordova-plugins/approov-advanced-http' +const fetch = require('node-fetch'); + +const API_DIR = './docs/native/'; + + +// replace with latest once it's relased +const tag = 'latest'; + +const pluginApis = [ + 'action-sheet', + 'app', + 'app-launcher', + 'browser', + 'camera', + 'clipboard', + 'device', + 'dialog', + 'filesystem', + 'geolocation', + 'google-maps', + 'haptics', + 'keyboard', + 'local-notifications', + 'motion', + 'network', + 'preferences', + 'push-notifications', + 'screen-reader', + 'share', + 'splash-screen', + 'status-bar', + 'text-zoom', + 'toast', ]; -let plugins = nativeJSON.filter((plugin) => !filteredPlugins.includes(plugin.packageName)); -const data = fs.writeFileSync('./scripts/data/native.json', JSON.stringify(plugins, null, 2)); - -(async function () { - // console.log(cliJSON); - - plugins.map(writePage); -})(); - -function writePage(page) { - const data = [ - renderFrontmatter(page), - renderImports(page), - renderIntro(page), - renderSalesCTA(page), - renderInstallation(page), - renderSupportedPlatforms(page), - renderCapIncompat(page), - renderUsage(page), - ].join(''); - - const path = `docs/native/${page.packageName.replace('@awesome-cordova-plugins/', '')}.md`; - fs.writeFileSync(path, data); +async function buildPluginApiDocs(pluginId) { + const [readme, pkgJson] = await Promise.all([getReadme(pluginId), getPkgJsonData(pluginId)]); + + const apiContent = createApiPage(pluginId, readme, pkgJson); + const fileName = `${pluginId}.md`; + const filePath = `${API_DIR}${fileName}` + fs.writeFileSync(filePath, apiContent); } -function renderFrontmatter({ displayName, packageName }) { - const slug = packageName.replace('@awesome-cordova-plugins/', ''); +function createApiPage(pluginId, readme, pkgJson) { + const title = `${toTitleCase(pluginId)} Capacitor Plugin API`; + const desc = pkgJson.description ? pkgJson.description.replace(/\n/g, ' ') : title; + const editUrl = `https://github.com/ionic-team/capacitor-plugins/blob/main/${pluginId}/README.md`; + const editApiUrl = `https://github.com/ionic-team/capacitor-plugins/blob/main/${pluginId}/src/definitions.ts`; + const sidebarLabel = toTitleCase(pluginId); - const frontmatter = { - title: displayName, - }; + // removes JSDoc HTML comments as they break docusauurs + readme = readme.replaceAll(//g, ''); - return `--- -${Object.entries(frontmatter) - .map(([key, value]) => `${key}: ${typeof value === 'string' ? `"${value.replace('"', '\\"')}"` : value}`) - .join('\n')} + return ` +--- +title: ${title} +description: ${desc} +editUrl: ${editUrl} +editApiUrl: ${editApiUrl} +sidebar_label: ${sidebarLabel} --- -${utils.getHeadTag(nativeOverrides[slug])} -`; +${readme}`.trim(); } -function renderImports({}) { - return ` -import DocsCard from '@components/global/DocsCard'; -import DocsButton from '@components/page/native/DocsButton'; -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import CodeBlock from '@theme/CodeBlock'; -`; +async function getReadme(pluginId) { + const url = `https://cdn.jsdelivr.net/npm/@capacitor/${pluginId}@${tag}/README.md`; + const rsp = await fetch(url); + return rsp.text(); } -function renderIntro({ description, repo }) { - return ` -${description} - -

- ${utils.gitBranchSVG()} ${repo} -

-`; +async function getPkgJsonData(pluginId) { + const url = `https://cdn.jsdelivr.net/npm/@capacitor/${pluginId}@${tag}/package.json`; + const rsp = await fetch(url); + return rsp.json(); } -function renderSalesCTA({}) { - return ` -

Stuck on a Cordova issue?

- -
- -

If you're building a serious project, you can't afford to spend hours troubleshooting. Ionic’s experts offer premium advisory services for both community plugins and premier plugins.

- Contact Us Today! -
-
- -`; +async function main() { + await Promise.all(pluginApis.map(buildPluginApiDocs)); + console.log(`Plugin API Files Updated 🎸`); } -function renderInstallation({ cordovaPlugin, packageName }) { - return ` -

- Installation -

- - - - $ npm install ${cordovaPlugin.name} {"\\n"} - $ npm install ${packageName} {"\\n"} - $ ionic cap sync - - - - - $ ionic cordova plugin add ${cordovaPlugin.name} {"\\n"} - $ npm install ${packageName} {"\\n"} - - - -
Ionic Enterprise comes with fully supported and maintained plugins from the Ionic Team.   - Learn More or if you're interested in an enterprise version of this plugin Contact Us
-
-
-`; +function toTitleCase(str) { + return str.replace(/(^\w|-\w)/g, (s) => { + return s.replace(/-/, ' ').toUpperCase(); + }); } -function renderSupportedPlatforms({ platforms }) { - return ` -## Supported Platforms +if (!String.prototype.replaceAll) { + String.prototype.replaceAll = function(str, newStr){ -${platforms.map((platform) => `- ${platform}`).join('\n')} -`; -} + // If a regex pattern + if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') { + return this.replace(str, newStr); + } -function renderCapIncompat({ capacitorIncompatible }) { - if (!capacitorIncompatible) { - return null; - } + // If a string + return this.replace(new RegExp(str, 'g'), newStr); - return ` -## Capacitor - -Not Compatible -`; + }; } -function renderUsage({ usage }) { - if (!usage) { - return null; - } - - return ` -## Usage - -### React +main(); -[Learn more about using Ionic Native components in React](../native-community.md#react) - - -### Angular - -${usage.replace(/ +
-
Ionic Native Enterprise Edition
+
Ionic Enterprise SDK

- Premium, supported Capacitor and Cordova plugins, third-party integrations, and pre-built native solutions for + Premium, supported plugins, third-party integrations, and pre-built native solutions for building enterprise-grade apps.