Concepts(概念)
Capacitor应用程序中的广告
许多消费类应用程序需要显示广告才能产生收入。
最受欢迎的移动应用程序广告网络是Google Admob,并且有一个社区维护的Capacitor插件可以使用:
npm install @capacitor-community/admob
npx cap update
然后,按照Capacitor社区Admob文档进行配置和使用。
这篇社区文章对于这个插件的实际应用也是一个有用的参考(尽管它使用的是旧版本的插件)。
Capacitor应用的持续继承/交付
每一个严肃的应用程序都会利用一个CI/CD过程来进行持续的测试、集成和交付。
不幸的是,移动端带来了独特的CI/CD挑战,web开发人员在前端CI/CD中使用的相同技术不适用于移动设备,因为构建和部署过程完全不同。
您前端项目的基本CI/CD
Capacitor应用程序CI/CD的第一步是使用一个构建和测试前端JS应用程序的过程。
目前,这通常是使用一个通用的CI/CD服务来完成的,比如GitHub Actions、CircleCI、Jenkins等。
在此过程中,应用程序被设置为在每次提交的基础上构建,并且通常运行本地测试套件。这是典型的JS CI/CD过程,您的团队可能已经熟悉它了。
但这只是冰山一角,因为团队需要弄清楚如何构建、测试和部署应用程序的实际原生移动端。
添加移动端CI/CD
对于一个移动应用来说,仅仅构建和运行JS应用程序测试是远远不够的,因为你的应用程序的很大一部分需要构建并作为一个原生的iOS和Android应用程序运行。
此外,移动应用程序的部署和更新方式与web应用程序非常不同。web应用程序将托管在一个可以快速更新的服务器上,而移动应用程序则“托管”在应用程序商店中,并作为加密签名的二进制文件分发。更新过程非常不同。
这意味着我们需要一个能够进行原生移动端构建和测试的服务,同时也提供一种以适合原生移动端的方式部署和更新我们的应用程序的方法。
Appflow:Capacitor应用的移动CI/CD
提供端到端移动CI/CD服务之一的是Appflow,这是一个Capacitor应用程序的官方移动端CI/CD和移动端 DevOps平台。
Appflow提供频繁更新管理的iOS和Android构建环境。Appflow与流行的git服务(如GitLab、GitHub和Bitbucket)集成,以支持在每次提交时触发JS和原生移动构建。Appflow还支持为参与方、beta测试人员和产品用户将构建分成不同的渠道。
对于Capacitor开发者来说,Appflow还提供了无需提交应用程序商店就可以向应用程序推送实时更新的功能,只要这些更新位于应用程序的JS/HTML/CSS层。
有关更多详细信息,请参阅Appflow文档。
在Appflow中使用传统的CI/CD服务
Appflow可以替代传统的CI/CD服务,因为它执行web/JS构建和本地移动端构建。但是,它可以很好地与传统的CI/CD服务配合使用。
要以这种方式使用它,请在每次提交时使用webhook将构建的资源文件发送到Appflow。
其他移动CI/CD选项
移动CI/CD还有其他服务,但没有一个专注于Capacitor。其中一些选项包括visual studio appcenter、Bitrise和Buddybuild(仅限iOS)。请记住,目前这些服务都没有为Capacitor应用程序提供远程实时应用程序更新。
与通用和应用程序链接的深度链接
平台:iOS、Android
通用链接(iOS)和应用程序链接(Android)可以让用户直接访问本地应用程序中的特定内容(通常称为深度链接)。
当用户tap
或click
一个深层链接时,用户将直接发送到你的应用程序中,而无需先通过设备的网络浏览器或网站进行路由。如果未安装应用程序,则用户将被定向到网站。如果用户直接导航到该网站,则他们仍停留在网站上。这使得深层链接成为为web、iOS和Android构建的跨平台应用程序的一个优秀特性:无缝移动体验,优雅的回退到网站。
优点:
- 安全:通用/应用程序链接使用HTTPS URL链接到您拥有的网站域名,确保没有其他应用程序可以使用您的链接。
- 无缝体验:一个URL同时适用于您的网站和应用程序,确保用户能够顺利访问他们正在寻找的内容而不会出错。
- 增加参与度:可以从电子邮件客户端、搜索引擎结果等打开链接。
示例视频
以下是实际操作中的情况。在本例中,用户已经在手机上安装了原生应用程序。他们从电子邮件中点击应用程序链接,然后直接进入应用程序本身。首先,用户点击了根链接(https://beerswift.app),将用户定向到主应用程序页面。接下来,一个深层链接被打开(https://beerswift.app/tabs/tab3)将用户带到Tab3页面。
https://www.youtube.com/watch?v=UAvBCZsxMFo&feature=emb_rel_end
为了便于说明,https://beerswift.app将用作web应用程序链接。
使用Capacitor应用程序API的深层链接路由
当原生应用程序在点击一个深度链接后被打开时,移动操作系统不会自动知道将用户路由到哪里。这必须在应用程序启动时使用Capacitor应用程序API在应用程序内部实现。
如果您的网站和应用程序路径不匹配,则需要实现更高级的url模式匹配(请参阅本指南中的示例)。如果你的移动应用程序和web应用程序使用相同的代码库,这是非常简单的-只要重定向到相同的URL。下面的例子是这样子的。
Angular
路由应该在app.component.ts
中被继承。首先要从Angular中引入NgZone
和Router
,然后从Capacitor中引入App
。
import { Component, NgZone } from '@angular/core';
import { Router } from '@angular/router';
import { Plugins } from '@capacitor/core';
const { App } = Plugins;
然后在构造器中声明NgZone
和Router
constructor(private router: Router, private zone: NgZone) {
this.initializeApp();
}
最后,监听appUrlOpen
事件,然后当一个深层链接被发现的时候进行重定向:
initializeApp() {
App.addListener('appUrlOpen', (data: any) => {
this.zone.run(() => {
// Example url: https://beerswift.app/tabs/tab2
// slug = /tabs/tab2
const slug = data.url.split(".app").pop();
if (slug) {
this.router.navigateByUrl(slug);
}
// If no match, do nothing - let regular routing
// logic take over
});
});
}
React
React有多种选择。一种方法是将App API监听器功能包装在新组件中,然后将其添加到App.tsx
中。创建AppUrlListener.tsx
,然后导入React Router useHistory
钩子以及capacitor应用程序API:
import React, { useEffect } from 'react';
import { useHistory } from "react-router-dom";
import { Plugins } from '@capacitor/core';
const { App: CapApp } = Plugins;
接下来,定义AppUrlListener组件,监听appUrlOpen
事件,然后在深层链接被发现时进行重定向:
const AppUrlListener: React.FC<any> = () => {
let history = useHistory();
useEffect(() => {
CapApp.addListener('appUrlOpen', (data: any) => {
// Example url: https://beerswift.app/tabs/tab2
// slug = /tabs/tab2
const slug = data.url.split(".app").pop();
if (slug) {
history.push(slug);
}
// If no match, do nothing - let regular routing
// logic take over
});
}, []);
return null;
};
export default AppUrlListener;
最后在App.tsx
中引入这个新的组件:
import AppUrlListener from './pages/AppUrlListener';
然后将其添加到IonReactRouter
内部(或者在应用程序引导的任何位置,只需确保History钩子可用):
const App: React.FC = () => {
return (
<IonApp>
<IonReactRouter>
<AppUrlListener></AppUrlListener>
<IonRouterOutlet>
<Route path="/home" component={Home} exact={true} />
<Route exact path="/" render={() => <Redirect to="/home" />} />
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
);
};
Vue
Vue JS提供了一个被称为Vue Router的路由系统,它与Vue原生集成。要使用Vue Router来设置深度链接,请从你用于配置所有路由的文件开始(通常是routes.js
或者类似的东西)。
首先我们引入Vue
和VueRouter
以及capacitor的App
插件。
import { Plugins } from '@capacitor/core';
const { App } = Plugins;
import Vue from 'vue';
import VueRouter from 'vue-router';
然后通过Vue Router来配置你的路由(详见配置指南)。
const router = new VueRouter({
routes: []
})
推荐使用mode:history
,这样的话你就不用处理#
。
让Vue知道你在使用Vue Router然后在Vue里面注册路由:
const VueApp = new Vue({
router
}).$mount('#app')
最后,我们需要注册我们的应用程序进行深层链接。为此,我们在Capacitor应用程序中添加一个appUrlOpen
事件监听器。Capacitor会接收到这个事件,然后我们把它交给Vue路由器导航到请求的页面。
App.addListener('appUrlOpen', function( data ){
// Example url: https://beerswift.app/tabs/tabs2
// slug = /tabs/tabs2
const slug = data.url.split(".app").pop();
// We only push to the route if there is a slug present
if( slug ){
router.push({
path: slug
});
}
});
创建站点关联文件
为了让苹果和谷歌允许深度链接打开你的应用程序,你的网站和应用程序之间必须建立一个双向关联。必须为每个app创建一个文件,并将其放置在您网站上的.well known
文件夹中,如下所示:https://beerswift.app/.well-known/。
继续了解iOS和Android配置详细信息。
iOS配置
iOS配置包括创建站点关联文件和配置原生应用程序以识别应用程序域名。
你必须要注册苹果开发者计划。
创建站点关联文件
首先,登录苹果开发者网站。导航到“Certificates, Identifiers, & Profiles”部分并选择应用程序的标识符。注意Team ID和Bundle ID,并在Capabilities下切换“Associated Domains”,然后保存:
然后,创建站点关联文件(apple-app-site-association
)。
注意:尽管是一个JSON文件,但不要用文件扩展名保存它。
下面是apple-app-site-association
文件示例,记得把TEAMID.BUNDLEID
替换成你自己的ID(例如:8L65AZE66A.com.netkosoft.beerswift
)。
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAMID.BUNDLEID",
"paths": ["*"]
}
]
}
}
然后,把这个文件上传到你的网站(必须是https开头的网址),然后使用苹果的工具来验证是否配置正确。你的URL的格式必须遵循这种格式: https://beerswift.app/.well-known/apple-app-site-association
添加关联域名
最后一步是配置iOS应用程序以识别传入链接。打开Xcode,然后导航到Signing&Capabilities。单击“+Capabilities”,然后选择关联域名。在显示的域条目中,使用以下格式编辑它applinks:yourdomain.com
:
安卓配置
Android配置包括创建一个站点关联文件,并配置原生应用程序以使用意图过滤器识别应用程序链接。
创建站点关联文件
站点关联文件需要Android证书的SHA256指纹。
如果没有证书,请创建证书:
keytool -genkey -v -keystore KEY-NAME.keystore -alias ALIAS -keyalg RSA -keysize 2048 -validity 10000
使用现有(或新创建的)密钥库证书,使用keytool命令列出密钥库的详细信息:
keytool -list -v -keystore my-release-key.keystore
上面的代码的打印输出会包括SHA256指纹:
接下来,使用Google的Asset Links tool创建站点关联文件。填写网站域名、应用包名称、SHA256指纹,点击“Generate statement”:
将JSON输出复制到.well-known/assetlinks.json
文件中。
// assetlinks.json
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.netkosoft.beerswift",
"sha256_cert_fingerprints": [
"43:12:D4:27:D7:C4:14..."
]
}
}
]
将文件部署到您的网站(托管在HTTPS上),然后通过单击Asset Link tool
中的“Test statement”按钮进行验证。如果配置正确,将显示成功消息:
Success! Host [website] grants app deep linking to [app package].
添加意向过滤器
最后一步是配置Android应用程序以识别传入的链接。为此,请将新的意向过滤器添加到AndroidManifest.xml
文件的<activity>
元素中:
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="beerswift.app" />
</intent-filter>
完整的活动应该类似于:
<activity
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"
android:name="com.netkosoft.beerswift.MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBarLaunch"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="beerswift.app" />
</intent-filter>
</activity>
细节:网站配置
网站配置将根据所使用的工具和后端而有所不同。以下是一些建议。
Angular
将关联文件放在src/.well-known
下。接下来,配置构建过程以完全按原样部署这些文件(确保Apple/Google能够正确读取它们)。打开angular.json
在architect=>assets
下,向数组添加一个新条目:
{
"glob": "**/*",
"input": "src/.well-known",
"output": ".well-known/"
}
构建然后部署站点。
NuxtJS
将关联文件放在static/.well-known
下。不需要额外的步骤;只需构建然后部署站点。
React
将关联文件放在static/.well-known
下。不需要额外的步骤;只需构建然后部署站点。
Wordpress
请参阅此处获取Wordpress说明。
验证
若要验证网站和原生应用是否配置正确,网站需要包含站点关联文件,但应用程序不需要位于应用程序商店中。
将真机连接到计算机,构建并部署原生应用程序,然后通过点击网站链接进行测试。如果原生应用程序打开,则所有步骤都已正确实现。
资源
- Branch.io: What is Deep Linking?
- Android: App Links
- iOS: Universal Links
- iOS: Enabling Universal Links
应用部署和实时更新
应用程序开发的最后一步涉及到将应用程序发布到应用程序商店,以及随时保持更新。
基于web(或混合)的移动开发方法的一个关键优势是能够以app store友好的方式对应用程序进行实时更新,只要这些更改不需要二进制更新(即编译的原生功能)。
此外,由于大多数capacitor开发者同时瞄准iOS和Android(以及web),手动发布应用程序和每个应用商店的二进制数据更新可能是不必要的而且很乏味。
为了使app store的发布和长期的应用更新变得更容易,capacitor背后的公司Ionic提供了一个强大的移动DevOps平台Appflow。
使用Appflow进行应用程序自动化发布到应用商店
Appflow为capacitor开发人员提供了几个主要的节省时间的功能。其中最有趣的是它可以直接发布到苹果应用商店和谷歌应用商店。所有计划都支持每月多次部署,扩展了支持更多应用程序的限制,并能够完全自动化为更高级别的计划部署。
使用Appflow部署实时更新
与app store发布功能相配合,开发者可以使用Appflow的live deploy功能在其应用的整个生命周期中部署实时的应用程序更新。
Live deployment的工作原理是,capacitor应用程序基本上是作为web应用程序构建的,并与原生功能钩子。苹果和谷歌明确允许对应用程序进行web内容更新,因此这项功能与app store兼容,为移动应用程序团队提供了前所未有的灵活性。
连接到GitHub、Bitbucket和GitLab
对于git触发的构建和部署,Appflow可以直接连接到GitHub、Bitbucket或GitLab repo。
这使得连接到您现有的开发工作流变得很容易,以开始添加自动化应用程序商店和实时更新,而不会造成任何中断。
今天就试试Appflow
Appflow为拥有数亿用户和重大业务影响的主要消费者和企业应用提供支持。Appflow团队与许多财富500强企业以及数千家中小企业密切合作。
而且,由于Appflow背后的团队与capacitor团队密切合作,因此Appflow经过优化,能够与capacitor一起很好的工作。
Appflow可以免费开始使用,您可以使用以前的Ionic帐户。要开始,请访问使用AppFlow.com或者浏览文档以了解Appflow如何工作的更多信息。
Capacitor应用内购买
大多数应用程序都需要创建和消费应用内购买,以便产生收入和实现升级。在capacitor应用程序中添加应用内购买支持很简单,但需要大量的工作来配置和注册自己的应用程序产品。
为此,我们将使用cordova-plugin-purchase插件。
npm install cordova-plugin-purchase
npx cap update
设置产品和消费品
在capacitor应用程序中设置应用程序内购买的大部分工作是为iOS和Android注册产品和消费品,然后设置适当的流程以在应用程序中注册和消费这些项目。
这是一个相当复杂的过程,我们推荐以下指南作为下一步:
实时重载
Live Reload对于调试应用程序的web部分以及设备硬件或模拟器上的原生功能非常有用。它不是在每次更改代码时都部署新的原生二进制文件,而是在检测到应用程序中的更改时重新加载浏览器(或Web View)。
如果在真机上运行,请确保它与计算机位于同一Wi-Fi网络上。
与Ionic CLI一起使用
Ionic CLI包括完整的实时重新加载体验,可以自动执行下面手动详述的所有步骤。与native-run
一起安装它(一个跨平台的命令行实用工具,用于在设备和模拟器/虚拟机上运行原生二进制文件):
npm install -g @ionic/cli native-run
接下来,使用ionic cap run
命令来开始Live Reload进程:
ionic cap run android -l --external
ionic cap run ios -l --external
上面的命令将执行ionic build
,复制web资源文件到你特定的原生平台,然后打开你原生平台的开发工具(iOS的Xcode,安卓的Android Studio)。
在capacitor.config.json
中自动创建的服务器项会在命令终止后删除。有关ionic cap run
命令的完整详细信息,请参阅此处。
和框架CLIS一起使用
capacitor支持具有实时重新加载能力的CLIs。
首先,确定计算机在局域网上的IP地址。
在macOS上,运行ifconfig
。IP地址列在en0
条目下,在inet
之后。或者,打开System Preferences->Network->(选择active Network),然后在Status下找到列出的IP。
在Windows上运行ipconfig
。查找IPv4
地址。
接下来,启动本地web服务器。服务器必须绑定到0.0.0.0
才能从LAN访问。要运行的命令会有所不同,但通常是:
npm run start
对于react脚本,使用
HOST=0.0.0.0 npm run start
在capacitor.config.json
文件中,创建一个server
实体,然后使用本地web服务器的IP地址和端口配置url
"server": {
"url": "http://192.168.1.68:8100",
"cleartext": true
},
接下来,运行npx cap copy
将更新后的capacitor配置复制到所有原生项目中。
打开原生IDE(如果尚未打开的话):
npx cap open ios
npx cap open android
最后,单击Run按钮启动应用程序并开始使用Live Reload。
注意不要将服务器配置提交给源代码管理。
在Ionic+Angular应用里面使用Firebase推送通知
网络框架:Angular平台:iOS、Android
应用程序开发人员向用户提供的最常见功能之一是推送通知。在本教程中,我们将介绍让Firebase云消息在iOS和Android上运行所需的所有步骤。
为了注册和监控来自Firebase的推送通知,我们将在Ionic + Angular应用程序中使用Push Notification API for Capacitor。
必需的依赖项
使用capacitor构建和部署iOS和Android应用程序需要一些设置。继续之前,请按照此处说明安装必要的capacitor依赖项。
要在iOS上测试推送通知,Apple要求您拥有付费的Apple开发者帐户和物理iOS设备。
如果您遇到问题,或者您的控制台对过时或不推荐的软件包发出警告,请确保您使用的是Node、Android Studio和Xcode的最新稳定版本。
另外,我们使用Firebase进行推送通知,因此如果您使用的是使用Firebase SDK的其他Cordova插件,请确保它们使用的是最新版本。
准备一个Ionic Capacitor应用
如果你有一个现有的Ionic应用程序,跳过这一部分。如果没有,让我们先创建一个Ionic应用程序。
在首选终端中,安装最新版本的Ionic CLI:
npm install -g @ionic/cli
接下来,让我们使用CLI创建一个基于空白启动程序的新的Ionic Angular应用程序并称之为CapApp:
onic start capApp blank --type=angular
在要求将新应用程序与capacitor集成的提示下,键入y
并按enter键。这将为我们的新应用程序添加capacitor和capacitorCLI。
成功创建应用程序后,切换到新创建的项目目录:
cd capApp/
最后运行npx cap init
,这将允许我们填写我们的应用程序信息。
npx cap init
? App name: CapApp
? App Package ID: com.mydomain.myappname
构建应用&添加平台
在添加任何原生平台到项目之前,应用至少应该构建一次。一次web构建的话会生成一个web资源文件夹,Capacitor需要这个文件夹(如果是Ionic Angular项目的话会生成www
文件夹)。
ionic build
接下来,让我们添加iOS和Android平台到我们的项目。
npx cap add ios
npx cap add android
运行这些命令后,将在项目根目录下创建android
和ios
文件夹。这些都是完全独立的原生项目工件,应该被视为你的Ionic应用程序的一部分(即,将它们纳入到源代码控制中)。
在你的应用程序中,转到home.page.ts
文件并添加import
语句和const
以使用Capacitor Push API:
import {
Plugins,
PushNotification,
PushNotificationToken,
PushNotificationActionPerformed } from '@capacitor/core';
const { PushNotifications } = Plugins;
然后,添加ngOnInit()
方法和一些API方法来注册和监控推送通知。我们还将添加alert()
一些事件来监控正在发生的情况:
export class HomePage implements OnInit {
ngOnInit() {
console.log('Initializing HomePage');
// Request permission to use push notifications
// iOS will prompt user and return if they granted permission or not
// Android will just grant without prompting
PushNotifications.requestPermission().then( result => {
if (result.granted) {
// Register with Apple / Google to receive push via APNS/FCM
PushNotifications.register();
} else {
// Show some error
}
});
// On success, we should be able to receive notifications
PushNotifications.addListener('registration',
(token: PushNotificationToken) => {
alert('Push registration success, token: ' + token.value);
}
);
// Some issue with our setup and push will not work
PushNotifications.addListener('registrationError',
(error: any) => {
alert('Error on registration: ' + JSON.stringify(error));
}
);
// Show us the notification payload if the app is open on our device
PushNotifications.addListener('pushNotificationReceived',
(notification: PushNotification) => {
alert('Push received: ' + JSON.stringify(notification));
}
);
// Method called when tapping on a notification
PushNotifications.addListener('pushNotificationActionPerformed',
(notification: PushNotificationActionPerformed) => {
alert('Push action performed: ' + JSON.stringify(notification));
}
);
}
这是home.page.ts
的全部实现:
import { Component, OnInit } from '@angular/core';
import {
Plugins,
PushNotification,
PushNotificationToken,
PushNotificationActionPerformed } from '@capacitor/core';
const { PushNotifications } = Plugins;
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage implements OnInit {
ngOnInit() {
console.log('Initializing HomePage');
// Request permission to use push notifications
// iOS will prompt user and return if they granted permission or not
// Android will just grant without prompting
PushNotifications.requestPermission().then( result => {
if (result.granted) {
// Register with Apple / Google to receive push via APNS/FCM
PushNotifications.register();
} else {
// Show some error
}
});
PushNotifications.addListener('registration',
(token: PushNotificationToken) => {
alert('Push registration success, token: ' + token.value);
}
);
PushNotifications.addListener('registrationError',
(error: any) => {
alert('Error on registration: ' + JSON.stringify(error));
}
);
PushNotifications.addListener('pushNotificationReceived',
(notification: PushNotification) => {
alert('Push received: ' + JSON.stringify(notification));
}
);
PushNotifications.addListener('pushNotificationActionPerformed',
(notification: PushNotificationActionPerformed) => {
alert('Push action performed: ' + JSON.stringify(notification));
}
);
}
}
在此之后,您需要生成一个新的构建,并让Capacitor知道这些更改。您可以使用:
ionic build
npx cap copy
在Firebase上为你的应用程序创建项目
在我们将Firebase云消息连接到您的应用程序并发送推送通知之前,您需要在Firebase中启动一个项目。
转到Firebase控制台并单击Add Project按钮。
命名项目,接受Firebase ToS并单击Create Project继续。此时会自动为您生成项目ID。
安卓
将Firebase与安卓应用集成
本部分或多或少地映射了 setting up Firebase using the Firebase console documentation。请参阅以下有关Capacitor的特定说明。
转到Firebase项目的“项目概述”页面,然后在顶部单击Android图标以添加新的android应用程序。
下一个屏幕将询问您有关应用程序的一些信息。
- 你的Android package name应该匹配您
capacitor.config.json
文件中的appid。 - 我们使用
com.mydomain.myappname
作为此Capacitor应用程序的ID,因此将用于此项目。 - 昵称和调试签名证书是可选的。
然后单击 Register app 按钮。
下载并使用google-services.json
文件
下一个提示将要求您下载google-services.json
文件。此文件包含您的Capacitor应用程序从Android连接到Firebase所需的信息。
将google-services.json
文件下载到本地计算机。然后将文件移到Capacitor Android项目目录中,特别是在android/app/
目录下。
我们不需要向项目添加任何依赖项,因为Capacitor项目会自动在其build.gradle
文件中引入某个版本的firebase-messaging
。
iOS
先决条件
iOS推送通知的设置要比Android复杂得多。您必须具有付费的Apple Developer帐户 ,并注意以下事项,然后才能使用iOS应用程序测试推送通知:
- 在Apple Developer Portal中为您的iOS应用程序设置正确的开发或生产证书和配置文件
- 在Apple Developer Portal中为开发或生产创建APNS证书或密钥
- 确保已在Xcode中让你的应用程序启用了推送通知功能
- 根据Dependencies文档中的指南安装物理iOS设备
将Firebase与我们的原生iOS应用程序集成
这部分与上面的Android部分非常相似,但有一些关键区别。
首先,转到Firebase项目的“ 项目概述”页面。如果您一直在遵循本指南,那么您已经在页面顶部列出了一个Android应用程序。
要将iOS添加到Firebase项目中,请单击Add App按钮,然后选择iOS平台。
下一个屏幕将询问您有关应用程序的一些信息。
- 你的iOS bundle ID 应匹配您
capacitor.config.json
文件中的appid - 我们使用
com.mydomain.myappname
作为此Capacitor应用程序的ID,因此将用于此项目。 - 昵称和调试签名证书是可选的。
然后单击Register app按钮。
将GoogleService-Info.plist
文件添加到您的iOS应用
注:这与Android应用使用的不是同一个文件。
将GoogleService-Info.plist
下载到本地计算机。
然后,您要打开Xcode ...
npx cap open ios
...,然后将.plist
文件按照Firebase的指示移动到Xcode项目中,确保将其添加到所有目标中。
通过CocoaPods添加Firebase SDK
iOS上的Push Notification API使用了CocoaPods(一种iOS依赖管理系统),我们需要告诉CocoaPods使用Firebase。
为此,我们需要修改Podfile
,可以在Xcode的Pods
目录下找到:
我们需要将Firebase添加到为我们的App目标提供的CocoaPods中。为此,请添加pod Firebase/Messaging
到您的target 'App'
部分,如下所示:
target 'App' do
capacitor_pods
# Add your Pods here
pod 'Firebase/Messaging' # Add this line
end
您Podfile
应该看起来像这样:
platform :ios, '11.0'
use_frameworks!
# workaround to avoid Xcode caching of Pods that requires
# Product -> Clean Build Folder after new Cordova plugins installed
# Requires CocoaPods 1.6 or newer
install! 'cocoapods', :disable_input_output_paths => true
def capacitor_pods
# Automatic Capacitor Pod dependencies, do not delete
pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
# Do not delete
end
target 'App' do
capacitor_pods
# Add your Pods here
pod 'Firebase/Messaging'
end
更新项目
现在,我们需要确保我们的iOS项目已更新,并且安装了正确的Firebase CocoaPod。
注意:由于CocoaPods需要下载所有适当的文件/依赖项,因此此部分可能需要一段时间。
npx cap update ios
添加初始化代码
要在iOS应用启动时连接到Firebase,您需要在AppDelegate.swift
文件中添加以下内容。
首先,在文件顶部添加一个import
:
import Firebase
...然后在application(didFinishLaunchingWithOptions)
方法中,添加Firebase的配置方法,用于在AppDelegate.swift
文件中初始化代码。
FirebaseApp.configure()
完成的AppDelegate.swift
文件应如下所示:
import UIKit
import Capacitor
import Firebase
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
return true
}
如果您想从iOS接收firebase FCM令牌而不是原始APNS令牌,则还需要更改AppDelegate.didRegisterForRemoteNotificationsWithDeviceToken
代码,如下所示:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
InstanceID.instanceID().instanceID { (result, error) in
if let error = error {
NotificationCenter.default.post(name: Notification.Name(CAPNotifications.DidFailToRegisterForRemoteNotificationsWithError.name()), object: error)
} else if let result = result {
NotificationCenter.default.post(name: Notification.Name(CAPNotifications.DidRegisterForRemoteNotificationsWithDeviceToken.name()), object: result.token)
}
}
}
将APNS证书或密钥上传到Firebase
如果您从一开始就按照说明进行操作,那么你已经Apple Developer门户中创建了Apple APNS证书或APNS身份验证密钥。您需要先将其中之一上传到Firebase,然后Firebase才能与APNS对话并向您的应用程序发送推送通知。
要上传证书或身份验证密钥,请从Project Overview页面:
- 单击您的iOS应用程序,然后单击Settings齿轮图标。
- 在“设置”页面上,单击Cloud Messaging选项卡。
- 在iOS app configuration标题下,使用提供的Upload按钮上传您的身份验证密钥或证书。
发送测试通知
现在好玩了-让我们验证Firebase的推送通知是否在Android和iOS上正常工作!
我们需要在Android或iOS上启动我们的应用程序,以便我们的home.page.ts
页面可以注册和接收通知。
要在Android Studio中打开Android项目,请执行以下操作:
npx cap open android
要在Xcode中打开iOS项目:
npx cap open ios
打开项目后,使用Android Studio或Xcode的Run功能将应用程序加载到设备上。该应用程序应在主页上启动。
注意:在iOS上,您会看到一个弹出窗口,要求您允许您的应用程序收到通知 -确保选择允许通知!
如果您的应用程序成功注册,并且您遵循了上面的代码,则应该看到一条包含成功消息的弹窗信息。
现在,我们将进行测试以查看设备是否收到了通知。要发送通知,请在Firebase中,转到项目窗格中Grow标题下的Cloud Messaging部分。
接下来,选择New Notification按钮。
创建通知时,只需指定以下信息:
- 通知文字
- 标题(仅Android,iOS可选)
- 目标(用户部分或主题;我建议仅针对iOS或Android应用本身,请参见下文)
- 计划(将其保留为“Now”)
届时,您可以Review已放在一起的通知,然后选择Publish将通知发送出去。
如果您正确设置了应用程序,则会在主屏幕上看到一条弹窗,其中包含您在Firebase中编写的推送通知。然后,您可以点击通知,按照上面的代码里的pushActionPerformed
事件获取一个提示。
Capacitor的React钩子
在其Capacitor应用程序中使用React的开发人员可以访问一组有用的,社区维护的React Hook,以访问其React函数组件中的Capacitor API。
安装钩子:
npm install @capacitor-community/react-hooks
要使用这些钩子,请导入并在功能组件中使用:
import { useFilesystem, base64FromPath, availableFeatures } from '@capacitor-community/react-hooks/filesystem';
const MyComponent = () => (
const { readFile } = useFilesystem();
useEffect(() => {
const readMyFile = async () => {
const file = await readFile({
path: filepath,
directory: FilesystemDirectory.Data
});
// ...
}
readMyFile();
}, [ readFile ]);
更多阅读
有关所有可用钩子的文档,请参见@ capacitor-community / react-hooks存储库。
Capacitor应用中的屏幕方向
许多应用在纵向和横向设备方向上都能很好地运行。但是,许多应用程序却没有这样做,并且有充分的理由要求应用程序仅以一种模式或另一种模式单独或偶尔运行。
全局方向设置
要在Capacitor应用的全局设置中设置方向,请为目标平台设置必要的配置值。
iOS配置
要限制iOS允许的方向,请打开Xcode并打开项目的常规设置。然后,选择您的应用将支持的方向:
Android配置
在Android上,可以通过修改AndroidManifest.xml
和主应用程序活动条目上的<activity>
标签里面的android:screenOrientation
来设置方向。有关可能的条目的详细信息,请参见Android清单文档。
动态方向设置
许多应用程序需要支持多种方向,并能够根据内容偶尔锁定方向。
Capacitor通过cordova-plugin-screen-orientation
插件支持此功能:
npm install cordova-plugin-screen-orientation
npx cap update
然后,使用window.screen.orientation
上可用的lock
和unlock
方法:
window.screen.orientation.lock('portrait');
window.screen.orientation.lock('landscape');
// To unlock orientation which will default back to the global setting:
window.screen.orientation.unlock();
有关可能的定向值和配置选项的所有范围,请参阅 Orientation Plugin Docs。
Capacitor安全最佳实践
每个Capacitor开发人员都有责任确保他们的应用遵循安全最佳实践。如果没有适当的顾及,就会出现严重的安全问题,这可能会造成极大的破坏和付出昂贵的代价。
安全性是一个广泛的主题,但是Capacitor开发人员应在许多方面进行审计以确保其符合安全性,包括数据,身份验证/深层链接,网络和Web View安全性。
数据安全
数据安全性处理本地存储和应用程序代码中数据的安全性。
避免在代码中嵌入机密
Capacitor应用程序以及任何与此相关的前端应用程序最重要的安全提示之一是,永远不要在您的应用程序代码中嵌入秘密。这意味着确保您的代码中绝不会包含秘密的API密钥,加密密钥或使用基本的应用程序分析技术可以轻易窃取的任何其他敏感数据。注意在构建时可能会将敏感值注入到您的应用程序代码中的环境变量插件。
取而代之的是,将大多数需要密钥或令牌的操作移到服务器端,在那里可以对其进行保护,并可以从服务器转发任何请求。这可能是无服务器功能或传统的服务器端应用程序过程。
对于必须与客户端上的持久性敏感密钥或令牌(例如身份验证令牌或加密密钥)一起使用的应用程序,建议的选项是仅处理内存中的值(即从不将其持久化到磁盘),或使用安全钥匙串/密钥库技术,如下所述。
存储加密密钥,会话令牌等
现代移动设备和操作系统提供了强大的安全性API和专用的安全性硬件,用于在设备上存储敏感值。这是应用程序在管理高度敏感的值(例如加密密钥或会话令牌)的同时,提供生物识别或安全密码验证的方式。
iOS钥匙串服务和Android密钥库 API 中提供了提供此功能的API。这些API很复杂且底层,因此您可能希望找到一个可以使用它们的插件(例如cordova-plugin-ios-keychain社区插件)。
对于企业用例,Capacitor团队提供了Identity Vault,该Identity Vault在这些原生安全API的基础上提供了易于使用的API和频繁更新的体验。Identity Vault可以与其他Capacitor企业产品(例如,脱机存储和Auth Connect)一起使用,以分别提供加密密钥或身份验证令牌管理组件。
身份验证和深层链接
本地应用程序中的身份验证流需要格外小心,因为身份验证通常是通过使用自定义URL方案进行的。自定义URL方案(如)instagram://
不受网络域的全局控制,因此恶意应用可能会通过定义和覆盖自定义URL方案来拦截针对一个应用的请求。想象一个安全令牌被发送到错误的应用程序!
通常,应用程序永远不应通过“自定义URL”方案深层链接发送敏感数据(诸如通用链接之类的新技术更安全,因为它们依赖于实际的网络域所有权,请参阅“ 深层链接” >“指南”以获取详细信息)。
这对于oAuth2流程尤其重要,在该流程中,身份验证体验的最后一步取决于返回到应用程序的深层链接。为了减轻恶意的应用程序接收令牌,PKCE必须在使用OAuth2的Capacitor的应用中使用。
为确保您的oAuth2流程安全,请确保您的插件支持PKCE。对于企业用例,官方的Auth ConnectCapacitor解决方案完全支持PKCE用于oAuth2身份验证流程。
有关更多信息,请参阅此出色的oAuth2本机应用最佳实践指南。
网络安全
网络安全性涉及确保将网络请求发送到受信任的端点并进行加密,以避免以纯文本形式发送敏感数据(例如密码)。
SSL协议
应用程序应仅向启用SSL的端点发出请求。这意味着永远不要向http://
的端点发出请求,而要始终使用https://
。这样可以确保数据绝不会以纯文本格式发送。
但是,仅靠这本身是不够的。为避免可能的中间人攻击,应固定SSL证书,以便仅接受已知证书。这必须在客户端和服务器上原生完成。如今,cordova-plugin-advanced-http插件支持此功能,并且可能还有其他插件也可以。
Web View安全性
内容安全政策
内容安全策略(CSP)是浏览器(以及CapacitorWeb视图)中可用的一组安全功能。CSP可用于限制允许用户代理在WebView中加载的资源(例如图像,XHR,视频,WebSockets等)。
可以在Capacitor应用中配置CSP,方法是将meta
以可接受的CSP格式添加到<head>
标签(可以使用相同的格式在服务器端和客户端配置CSP)。例如,此配置将允许所有请求发送到当前来源和foo.com
CSP支持多种配置,并且必须阅读CSP参考。另一个有用的资源是content-security-policy.com。
JavaScript安全技术
由于Capacitor应用程序的大部分是使用JavaScript的网络应用程序,因此需要使用典型的JS安全技术。
JS安全性不在本文档的讨论范围之内,并且有许多现有资源可用于适当的JS和Web应用程序安全性技术。这是一个入门的好方法。
创建启动画面和图标
现在可以使用初始屏幕和图标生成功能。有关完整的详细信息,请参见cordova-res docs。
首先,安装cordova-res
:
$ npm install -g cordova-res
cordova-res
需要一个类似于Cordova的结构:将一个图标和一个初始屏幕文件放在resources
项目中的顶级文件夹中,如下所示:
resources/
├── icon.png
└── splash.png
接下来,运行以下命令生成所有图像,然后将其复制到原生项目中:
$ cordova-res ios --skip-config --copy $ cordova-res android --skip-config --copy
Capacitor中的数据存储
大多数应用程序需要保留并读取本地数据。根据特定的用例,可以采用几种方法。
为什么不能只使用LocalStorage或IndexedDB?
由于Capacitor应用程序主要在Web视图或浏览器中运行,因此Capacitor开发人员可以使用用于存储的Web API。但是,使用这些API需要牢记一些主要警告。
本地存储可用于少量临时数据(例如用户ID),但必须将其视为瞬态数据,这意味着您的应用需要期望最终数据会丢失。这是因为如果设备空间不足,操作系统将从Web Views回收本地存储。至少在iOS上,IndexedDB可以说是相同的处理方法(在Android上,持久存储API可用于将IndexedDB标记为持久)。在浏览器中阅读有关数据存储逐出策略的更多信息。
Capacitor存储API
Capacitor带有原生存储API,可避免上述逐出问题,但仅适用于少量数据。
Storage API提供了一个简单的键/值API,没有高级查询支持:
import { Plugins } from '@capacitor/core';
const { Storage } = Plugins;
// JSON "set" example
async setObject() {
await Storage.set({
key: 'user',
value: JSON.stringify({
id: 1,
name: 'Max'
})
});
}
// JSON "get" example
async getObject() {
const ret = await Storage.get({ key: 'user' });
const user = JSON.parse(ret.value);
}
大数据或高性能存储选项
为了存储大量数据并以高可用方式访问它,有几种选择。
支持最广泛的选项是SQLite。有许多社区维护的SQLite插件应可在Capacitor中使用,包括CapacitorSQLite和cordova-plugin-sqlite。
Capacitor团队还提供了企业SQLite存储解决方案,该解决方案具有加密支持并与设备上的安全密钥管理API集成。
社区指南
通用
How to Build an Ionic Chat App with React and Stream ›
Capacitor: Five Apps in Five Minutes ›
Create an Ionic 4 PWA with Capacitor ›
Capacitor Workflow for iOS and Android Apps ›
Using the Capacitor in Vue.js app ›
接口
Camera: Building an Ionic Framework Camera App
Push Notifications: Using Push Notifications with Firebase in an Ionic Angular App
Splash Screen: Creating a Dynamic/Adaptable Splash Screen for Capacitor (Android) ›
Using the Capacitor Share API in IOS app ›
Using the Capacitor Browser API to open urls ›
Network Detection with Capacitor in Ionic project ›
整合方式
Using Google Maps and Geolocation in Ionic with Capacitor ›
Create Native HTML5 Games with Phaser and Capacitor ›
Integrating the Scanbot SDK in a Capacitor App with Ionic ›
Music Playback in Capacitor App with Ionic ›
Facebook Login in Capacitor App with Ionic React ›
Google Login in Capacitor Apps with Ionic React ›
Twitter Login in Capacitor Apps with Ionic React ›
文章评论