nativeScript-parley
Parley 消息的 NativeScript 插件。
npm i --save nativescript-parley

NativeScript Parley 插件

NativeScript Parley 消息插件。使用此插件需要 appSecret。您可以在 https://www.parley.nu/ 上获取 appSecret

要求

  • Android API 级别 17+
  • iOS 9+
  • NativeScript 4.0.0

更改

V1.2.15 (2019 年 6 月 14 日)

  • PARLEY-250 更新了示例和 iOS 依赖项。

V1.2.14 (2019 年 6 月 12 日)

  • PARLEY-247 更新了示例和 Android 依赖项。

V1.2.13 (2019 年 6 月 3 日)

  • PARLEY-247 更新了示例和 iOS 依赖项。

V1.2.12 (2019 年 5 月 27 日)

  • PARLEY-246 更新了 Android 依赖项,以便在加载图像时添加自定义头。

V1.2.11 (2019 年 5 月 24 日)

  • PARLEY-245 更新了示例和 iOS 依赖项。

V1.2.10 (2019 年 4 月 24 日)

  • PARLEY-240 更新了 Android 和 iOS 依赖项。

V1.2.9 (2019 年 4 月 24 日)

  • 未发布的更改。

V1.2.8 (2019 年 4 月 1 日)

  • PARLEY-234 移除了 before-prepare remove-firebase-podfile.js 指令。
  • PARLEY-234 修复了顶部边距问题。

V1.2.7 (2019 年 3 月 18 日)

  • PARLEY-233 修复了 iOS 中键盘辅助视图的问题。

V1.2.6 (2019 年 3 月 18 日)

  • PARLEY-232 升级到 NativeScript 5.2.2 并更新了 README.MD 中的说明(步骤 1.2.1),以通过 nativescript-plugin-firebase 包绕过 GoogleService-Info.plist 检查。

V1.2.5 (2019 年 2 月 18 日)

  • PARLEY-231 修复了当后台应用刷新开启时推送启用检查始终为真的问题。

V1.2.4 (2019 年 2 月 1 日)

  • PARLEY-228 更换了 Android 推送通知的 intent 标志。

V1.2.3 (2019 年 1 月 31 日)

  • PARLEY-223 修复了 Android 中“正在输入”功能中的点未着色的问题。

V1.2.2 (2019 年 1 月 23 日)

  • PARLEY-228 现在可以通过使用 Parley.getInstance().setNotificationTarget(notificationTarget: string) 来设置通过推送消息打开的 Android 活动对象。

V1.2.1 (2019 年 1 月 23 日)

  • PARLEY-227 修复了 Android API 18 的兼容性问题。

V1.2.0 (2019 年 1 月 22 日)

  • PARLEY-219 添加了对粘性消息的支持。
  • PARLEY-216 添加了新的气球样式。
  • PARLEY-224 提高了消息的向后兼容性。

V1.1.4 (2019 年 1 月 11 日)

  • PARLEY-223 修复了应用在后台时推送消息的 bug。

V1.1.3 (2018 年 12 月 21 日)

  • PARLEY-215 修复了在没有 SSL-pinning 的情况下使用库时的 bug。

V1.1.2 (2018 年 12 月 4 日)

  • PARLEY-209 将轮询间隔更改为 20 秒(仅在推送关闭或禁用时使用轮询)。

V1.1.1 (2018 年 10 月 16 日)

  • PARLEY-206 正确配置了基本 URL 和路径。

V1.1.0 (2018 年 9 月 27 日)

  • PARLEY-205 添加了对使用自定义头部的支持。

V1.0.15 (2018 年 8 月 21 日)

  • PARLEY-202 支持透明背景。
  • PARLEY-202 在示例应用中添加了渐变背景。

V1.0.12 (2018 年 5 月 15 日)

  • PARLEY-187 禁用了工具栏和导航栏的操纵。

V1.0.0 (2018 年 4 月 23 日)

  • PARLEY-179 在 GitHub 和 npm 上发布。

入门

该插件提供了一个名为 Parley 的单例和一个名为 ParleyView 的视图。单例 Parley 是您应用程序和插件之间的连接。视图 ParleyView 代表原生 Android 和 iOS 视图。

步骤 1:为插件准备您的项目

1.1 Android

步骤 1.1.1:创建一个 AppCompatActivity

该插件需要AppCompatActivity才能运行。创建文件app/main-activity.android.ts并添加以下内容

import {setActivityCallbacks, AndroidActivityCallbacks} from "tns-core-modules/ui/frame";

declare const com: any;

@JavaProxy("__PACKAGE__.MainActivity")
class MainActivity extends android.support.v7.app.AppCompatActivity {
private _callbacks: AndroidActivityCallbacks;

protected onCreate(savedInstanceState: android.os.Bundle): void {
if (!this._callbacks) {
setActivityCallbacks(this);
}

this._callbacks.onCreate(this, savedInstanceState, super.onCreate);
}

protected onSaveInstanceState(outState: android.os.Bundle): void {
this._callbacks.onSaveInstanceState(this, outState, super.onSaveInstanceState);
}

protected onStart(): void {
this._callbacks.onStart(this, super.onStart);
}

protected onStop(): void {
this._callbacks.onStop(this, super.onStop);
}

protected onDestroy(): void {
this._callbacks.onDestroy(this, super.onDestroy);
}

public onBackPressed(): void {
this._callbacks.onBackPressed(this, super.onBackPressed);
}

public onRequestPermissionsResult(requestCode: number, permissions: Array<String>, grantResults: Array<number>): void {
this._callbacks.onRequestPermissionsResult(this, requestCode, permissions, grantResults, undefined /*TODO: Enable if needed*/);
}

protected onActivityResult(requestCode: number, resultCode: number, data: android.content.Intent): void {
this._callbacks.onActivityResult(this, requestCode, resultCode, data, super.onActivityResult);
}
}

__PACKAGE__替换为您的包名

步骤1.1.2:在AndroidManifest中配置AppCompatActivity

打开AndroidManifest(位于App_Resources/Android/AndroidManifest.xml),将com.tns.NativeScriptActivity替换为__PACKAGE__.MainActivity

示例

之前

<activity
android:name="com.tns.NativeScriptActivity"
android:label="@string/title_activity_kimera"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@style/LaunchScreenTheme">

之后

<activity
android:name="__PACKAGE__.MainActivity"
android:label="@string/title_activity_kimera"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@style/LaunchScreenTheme">
步骤1.1.3:在app.gradle中定义支持版本和Firebase版本

为了避免编译Android应用程序时出现冲突,我们需要设置正确的supportVersionfirebaseVersion。打开app/App_Resources/Android/app.gradle并添加

android {
//

project.ext {
supportVersion = '27.1.1'
firebaseVersion = '12.0.1'
}
}
步骤1.1.4:配置Firebase云消息

该插件使用远程消息来更新聊天。您需要在Android中实现Firebase云消息以接收远程消息。

步骤1.1.4.1:在Firebase控制台中创建项目

Firebase需要一个google-services.info文件才能运行。您可以通过在https://console.firebase.google.com/上创建项目来检索此google-service.info文件。

将生成的google-services.info文件添加到app/App_Resources/Android中。

步骤1.1.4.2:安装NativeScript Firebase插件
tns plugin add nativescript-plugin-firebase

仅当安装插件时启用Android和Firebase消息传递。

步骤1.1.4.3:在AndroidManifest中定义Firebase云消息服务

打开AndroidManifest(位于App_Resources/Android/AndroidManifest.xml),并添加以下Firebase云消息服务

<manifest ... >
<application ... >
...
<service android:name="org.nativescript.plugins.firebase.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<service android:name="org.nativescript.plugins.firebase.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
</application>
</manifest>

1.2 iOS

步骤1.2.1:创建GoogleService-Info.plist以绕过nativescript-plugin-firebase包的检查。

NativeScript Firebase插件默认会检查文件GoogleService-Info.plists是否存在。由于Parley使用APNs接收远程消息,iOS不需要Firebase。要绕过此检查,请创建包含以下内容的文件App_Resources/iOS/GoogleService-Info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
</dict>
</plist>

步骤1.2.2:配置远程消息

为了在iOS中接收远程消息,应用程序需要添加一个app.entitlements文件。

创建文件app/App_Resources/iOS/app.entitlements并添加以下内容

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
</dict>
</plist>

然后安装nativescript-custom-entitlements以在编译iOS项目时复制app.entitlements文件

npm install nativescript-custom-entitlements --save-dev

步骤2:安装插件

npm install nativescript-parley --save-dev

步骤3:注册设备并配置远程消息

步骤3.1:删除app/app.ts

为了处理远程消息,我们需要针对特定平台进行配置,因此删除文件app/app.ts

3.2 Android

步骤3.2.1:创建Android特定应用程序

创建文件app/app.android.ts并添加以下内容

import * as application from 'tns-core-modules/application';

const firebase = require("nativescript-plugin-firebase");
import {Message} from "nativescript-plugin-firebase";
import {Parley} from "nativescript-parley";

firebase.init({
onMessageReceivedCallback: (message: Message) => {
console.log("onMessageReceivedCallback: ", message.data);

// Optional: Set the target activity to open when the notification is being clicked
Parley.getInstance().setNotificationTarget("com.webuildapps.tracebuzz.parleydemo.MainActivity");

Parley.getInstance().handlePushMessage(message.data);
},

onPushTokenReceivedCallback: function(token) {
console.log("onPushTokenReceivedCallback: ", token);

Parley.getInstance().setDeviceToken(token);
}
});

application.start({ moduleName: "main-page" });

3.3:iOS

步骤3.2.1:创建AppDelegate

创建文件app/app-delegate.ts并添加以下内容

import {Parley} from "nativescript-parley";

export class AppDelegate extends UIResponder implements UIApplicationDelegate {

public static ObjCProtocols = [UIApplicationDelegate];

applicationDidFailToRegisterForRemoteNotificationsWithError(application: UIApplication, error: NSError): void {
console.log("Failed to register for remote notifications");
}

applicationDidReceiveRemoteNotification(application: UIApplication, userInfo: NSDictionary<any, any>): void {
Parley.getInstance().handlePushMessage(userInfo);
}

applicationDidRegisterForRemoteNotificationsWithDeviceToken(application: UIApplication, deviceToken: NSData): void {
let deviceTokenString = deviceToken.description;

Parley.getInstance().setDeviceToken(deviceTokenString);
}

applicationDidFinishLaunchingWithOptions(application: UIApplication, launchOptions: NSDictionary<any, any>): boolean {
application.registerForRemoteNotifications();

return true;
}
}

步骤3.2.1:创建iOS特定应用程序

创建文件app/app.ios.ts并添加以下内容

import * as application from 'tns-core-modules/application';
import {AppDelegate} from "./app-delegate";

application.ios.delegate = AppDelegate;

application.start({ moduleName: "main-page" });

步骤4:在页面中实现Parley插件(最终🎉)

4.1:配置和使用Parley

Parley库提供了监听器以通知应用程序。Parley的配置可以自定义,例如修改基本URL和使用SSL固定。

应用程序本身负责在准备好时显示聊天。这可以通过在接收到onDeviceRegistrationSuccess回调时调用parleyView.showChat()来实现。

注意:在显示聊天之前需要注册设备。这意味着应用程序负责在尝试初始化和使用Parley插件之前确保推送令牌已设置。

步骤4.2.1:创建ChatViewModel

创建文件app/chat-view-model.ts并添加以下内容

import {Parley, ParleyListener, ParleySslPinningListener, ParleyView} from "nativescript-parley";
import {Observable} from "tns-core-modules/data/observable";

export class ChatViewModel extends Observable implements ParleyListener {

private parleyView: ParleyView;

constructor() {
super();

Parley.init(this, "appSecret");
// Add optional custom configuration here
Parley.getInstance().configure();
}

setParleyView(parleyView: ParleyView): void {
this.parleyView = parleyView;
}

// ParleyListener
onConfigureFailed() {
console.log('onConfigureFailed');
}

onConfigureSuccess() {
console.log('onConfigureSuccess');
Parley.getInstance().registerDevice();
}

onDeviceRegistrationFailed() {
console.log('onDeviceRegistrationFailed');
}

onDeviceRegistrationSuccess() {
console.log('onDeviceRegistrationSuccess');

this.parleyView.showChat();
}

onUserUnauthorized() {
console.log('onUserUnauthorized');
}

onChatMessageSend() {
console.log('onChatMessageSend');
}
}

appSecret替换为您的appSecret。您可以在https://www.parley.nu/上获取appSecret

步骤4.2:配置聊天视图

为聊天打开xml视图,并将 xmlns:Parley="nativescript-parley" 添加到 Page 标签。

例如

<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded" class="page" xmlns:Parley="nativescript-parley">

然后在 StackLayout 内部添加 ParleyView,例如。

<Parley:ParleyView id="parleyView" width="100%" height="100%"/>
步骤 4.3:配置聊天页面

打开聊天页面的typescript文件,并添加以下导入

import {Page} from "tns-core-modules/ui/page";
import {ChatViewModel} from "~/chat-view-model";
import {ParleyView} from "nativescript-parley";

之后,在您的 pageLoaded 方法中添加以下内容

let initialised = false;

export function pageLoaded(args: EventData) {
if (initialised) return;

let page: Page = <Page>args.object;
let parleyView: ParleyView = page.getViewById("parleyView");

let chatViewModel = new ChatViewModel();
chatViewModel.setParleyView(parleyView);
page.bindingContext = chatViewModel;

initialised = true;
}

自定义配置

Parley 允许使用自定义配置,例如指定基础URL和启用SSL固定。请注意:配置总是在 init() 方法之后和 configure() 方法之前完成。

可用的配置方法如下

Parley.init(this, "0W4qcE5aXoKq9OzvHxj2");
Parley.getInstance().registerUser("ZGFhbnw5ZTA5ZjQ2NWMyMGNjYThiYjMxNzZiYjBhOTZmZDNhNWY0YzVlZjYzMGVhNGZmMWUwMjFjZmE0NTEyYjlmMDQwYTJkMTJmNTQwYTE1YmUwYWU2YTZjNTc4NjNjN2IxMmRjODNhNmU1ODNhODhkMmQwNzY2MGYxZTEzZDVhNDk1Mnw1ZDcwZjM5ZTFlZWE5MTM2YmM3MmIwMzk4ZDcyZjEwNDJkNzUwOTBmZmJjNDM3OTg5ZWU1MzE5MzdlZDlkYmFmNTU1YTcyNTUyZWEyNjllYmI5Yzg5ZDgyZGQ3MDYwYTRjZGYxMzE3NWJkNTUwOGRhZDRmMDA1MTEzNjlkYjkxNQ"); // Optional -- Read the user registration custom configuration!
Parley.getInstance().setBaseUrl("https://www.irischat.com"); // Optional
Parley.getInstance().setBasePath("/clientApi/v1.2/"); // Optional
Parley.getInstance().enableSslPinning(this , "N9YyJf13LbHgGv1kn9/YEXGFLJbleikrcpDORa896ok=", "aR6DUqN8qK4HQGhBpcDLVnkRAvOHH1behpQUU1Xl7fE="); // Optional -- Read the SSL pinning custom configuration!
Parley.getInstance().configure();

(显示的值是默认值,根据需要修改)

自定义头部

Parley 支持使用自定义头部。这些可以在配置实例之前和之后更新。

请注意,如果头部具有相同的名称,Parley 将覆盖值。此外,Parley 的头部无法通过此方法删除。

Parley.getInstance().addHttpHeader("custom-company", "Webuildapps");
Parley.getInstance().removeHttpHeader("custom-company");

启用SSL固定

要启用SSL固定,您必须有一个安全配置。

可以使用以下配置方法启用SSL固定: enableSslPinning(listener: ParleySslPinningListener, publicKeyOne: string, publicKeyTwo: string)。 示例

// Parley.init(...);
Parley.getInstance().enableSslPinning(this , "N9YyJf13LbHgGv1kn9/YEXGFLJbleikrcpDORa896ok=", "aR6DUqN8qK4HQGhBpcDLVnkRAvOHH1behpQUU1Xl7fE="); // Default Parley keys
// Parley.getInstance().configure();

第一个参数期望一个 ParleySslPinningListener。这用于接收SSL固定的回调,并包含以下方法

ParleySslPinningListener {
public onEnableSslPinningSuccess(): void;
public onEnableSslPinningFailed(message: string ): void;
}
Android

上面的配置对于iOS就足够了。Android需要网络安全配置。创建文件 app/App_Resources/Android/xml/network_security_config.xml 并添加网络安全配置。

例如

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<domain includeSubdomains="false">www.irischat.com</domain>

<pin-set expiration="2018-05-31">
<pin digest="SHA-256">N9YyJf13LbHgGv1kn9/YEXGFLJbleikrcpDORa896ok=</pin>
<pin digest="SHA-256">aR6DUqN8qK4HQGhBpcDLVnkRAvOHH1behpQUU1Xl7fE=</pin>
</pin-set>
</domain-config>
</network-security-config>

您还需要在 AndroidManifest 中指定此网络安全配置。打开 AndroidManifest(位于 App_Resources/Android/AndroidManifest.xml),并按以下方式添加网络安全配置

<application
android:name="..."
android:icon="..."
android:roundIcon="..."
android:label="..."
android:theme="..."
android:networkSecurityConfig="@xml/network_security_config">

注册用户

用户可以被注册以加密数据(并在用户登出时注销)。注册用户需要用户认证令牌。请注意:registerUser() 总是在 init() 方法之后和 configure() 方法之前调用。这通过使用以下方法完成:Parley.getInstance().registerUser(userAuthorization: string);,如下所示

// Parley.init(...);
Parley.getInstance().registerUser("ZGFhbnw5ZTA5ZjQ2NWMyMGNjYThiYjMxNzZiYjBhOTZmZDNhNWY0YzVlZjYzMGVhNGZmMWUwMjFjZmE0NTEyYjlmMDQwYTJkMTJmNTQwYTE1YmUwYWU2YTZjNTc4NjNjN2IxMmRjODNhNmU1ODNhODhkMmQwNzY2MGYxZTEzZDVhNDk1Mnw1ZDcwZjM5ZTFlZWE5MTM2YmM3MmIwMzk4ZDcyZjEwNDJkNzUwOTBmZmJjNDM3OTg5ZWU1MzE5MzdlZDlkYmFmNTU1YTcyNTUyZWEyNjllYmI5Yzg5ZDgyZGQ3MDYwYTRjZGYxMzE3NWJkNTUwOGRhZDRmMDA1MTEzNjlkYjkxNQ"); // Optional -- Parley example user
// Parley.getInstance().configure();

此外,用户可以被注销(例如:当用户登出时)。请注意,这可以在初始化之后完成。注销可以如下进行

Parley.getInstance().deregisterUser();