创建迷你应用程序:如何使用任何JS框架和离子门户网站构建时尚和快速移动应用程序
#javascript #react #ionic #miniapp

想象您是在线钱包移动应用程序的开发人员,当地电影院的所有者向您接触请求。他希望您在应用程序中添加功能,该功能允许用户直接从应用程序预订和支付座位。您很乐意义务,并开始制作Android和iOS版本。成功发布后,另一个人接近您,并询问您是否可以将其在线商店添加到您的应用程序中,以便客户可以直接从那里付款。您开始担心所有这些新功能将获得该应用程序会增加多少。您不希望用户只需要下载十亿GB应用程序才能支付其电影票。

你会做什么?让我们一起解决这个问题。

我们正在考虑使应用程序更轻松,更易于用于所有这些新功能的方法。一种想法是将基于Web的解决方案直接从应用程序中直接从应用程序中进行预订。为了使集成尽可能简单,我们可以创建一个JavaScript SDK。

经过一些研究,我们发现了离子团队的项目Ionic Portals。根据文档,它是iOS和Android的增压本机WebView组件。使用离子门户,我们可以:

  • 使用Web内容扩展本机应用程序。它允许用户在现有的本机移动应用程序中添加基于Web的功能和体验。
  • 通过电容器桥访问本地功能。安全且安全访问功能,例如相机,地理位置,触觉等等 - 全部来自WebView。这样,我们可以使用网络提供真正的本地移动体验。
  • 控制对本机功能和数据的访问。本地开发团队对应用程序的哪些部分(包括特定功能和数据)进行了详尽的控制,可以在移动项目进行协作时访问。 ...

简而言之,离子门户是解决我们问题的理想解决方案。它使我们能够在不使其沉重的情况下将基于Web的功能添加到我们的应用程序中。它还提供了一种访问本地功能和数据的安全方法,这意味着我们可以使用网络提供真正的本机移动体验,从而使App轻巧,高效且用户友好。这样,我们可以在观看最新的大片时让我们的用户开心并享受爆米花。

让我们开始做生意!为了使集成过程尽可能简单,我们将编写JavaScript SDK。我们将创建一个用于与本机应用程序交互的库,并在NPM上发布。经过一些调整后,我使用vite生成了一个打字稿项目,并创建了一个message.ts文件。该文件包含在开始时,可​​以通过npm轻松安装Github存储库中的4种方法(代码的必要部分和丢失的部分。):

import Portals, { getInitialContext } from "@ionic/portals";
import {
  IInitialContext,
  IMessage,
  IMessageSubscription,
  IPortalSubscription,
  ISubscribeOptions,
  ISubscriptionCallback,
} from "./types";

export const SendMessage = async (params: IMessage) => {
  return Portals.publish<IMessage>(params);
};

export const SubscribeToMessage = async (
  options: ISubscribeOptions,
  callback: ISubscriptionCallback
): Promise<IPortalSubscription> => {
  return Portals.subscribe<IMessageSubscription>(options, callback);
};

export const UnsubscribeFromMessage = async (
  options: IPortalSubscription
): Promise<void> => {
  return Portals.unsubscribe(options);
};

export const GetInitialContext = <T = unknown>():
  | IInitialContext<T>
  | undefined => {
  return getInitialContext();
};

我们正在使用著名的Create-React-App创建一个前端项目。最好的开始方法是什么?当然,通过创建一个空的React项目!让我们创建一个组件:

import { useEffect, useState, useCallback, useRef } from "react";
import {
  SendMessage,
  SubscribeToMessage,
  UnsubscribeFromMessage,
  GetInitialContext,
  IPortalSubscription,
} from "js-miniapp-bridge";
import { MESSAGE_TOPICS } from "./constants";

function App() {
  const tokenSubscriptionRef = useRef<IPortalSubscription>();
  const initialContext = GetInitialContext<{ data: string }>();
  const [message, setMessage] = useState("");
  const [subscribeToTokenSuccessResponse, setSubscribeToTokenSuccessResponse] =
    useState<Partial<IPortalSubscription>>({});
  const [context, setContext] = useState(initialContext);

  const handlePublishToken = async () => {
    SendMessage({
      topic: MESSAGE_TOPICS.ACCOUNT_TOKEN,
      data: message,
    });
  };

  const subscribeToTokenCallback = (result: { topic: string; data: string }) => {
    setSubscribeToTokenSuccessResponse(result);
  };

  const subscribeToToken = useCallback(async () => {
    try {
      tokenSubscriptionRef.current = await SubscribeToMessage(
        { topic: MESSAGE_TOPICS.CHAT_MESSAGE },
        subscribeToTokenCallback
      );
    } catch (e) {
      setsubscribeToTokenErrorResponse(e);
    }
  }, []);

  const handleChangeInput = (e: React.ChangeEvent<HTMLInputElement>) => {
    setMessage(e.target.value);
  };

  useEffect(() => {
    subscribeToToken();

    return () => {
      UnsubscribeFromMessage(tokenSubscriptionRef.current!);
    };
  }, [subscribeToToken]);

  useEffect(() => {
    setContext(initialContext);
  }, [initialContext]);

  return (
    <div className="App">
      <div>
        <b>Subscribe Token Success Result:</b>
        <pre>{JSON.stringify(subscribeToTokenSuccessResponse, null, 4)}</pre>
      </div>
      <hr />
      <div>
        <b>Initial Context Result:</b>
        <pre>{JSON.stringify(context, null, 4)}</pre>
      </div>
      <hr />
      <div>
        <b>Message:</b>
      </div>
      <div>
        <input value={message} onChange={handleChangeInput} />
      </div>
      <button onClick={() => handlePublishToken()}>
        Publish/Send Message
      </button>
    </div>
  );
}

export default App;

现在,我们需要创建一个可以订阅和发送消息的应用程序。为此,我们将生成一个React Native项目并创建必要的组件:

import React, {useState} from 'react';
import {SafeAreaView, ScrollView, View, Text, Button} from 'react-native';

import {
  PortalView,
  publish,
  subscribe,
  unsubscribe,
} from '@ionic/portals-react-native';
import initializePortals from './initializePortals';

initializePortals();

function App(): JSX.Element {
  const [subscribeTokenSuccessResponse, setSubscribeTokenSuccessResponse] =
    useState(null);

  const subscribeToTokenRef = React.useRef<number>();

  const handlePublishToken = async () => {
    publish('CHAT_MESSAGE', 'token from native');
  };

  const subscribeToTokenCallback = (result: {topic: string; data: any}) => {
    setSubscribeTokenSuccessResponse(result);
  };

  const subscribeToToken = React.useCallback(async () => {
    subscribeToTokenRef.current = await subscribe(
      'ACCOUNT_TOKEN',
      subscribeToTokenCallback,
    );
  }, []);

  React.useEffect(() => {
    subscribeToToken();

    return () => {
      unsubscribe('ACCOUNT_TOKEN', subscribeToTokenRef.current!);
    };
  }, [subscribeToToken]);

  return (
    <SafeAreaView>
      <ScrollView contentInsetAdjustmentBehavior="automatic">
        <View>
          <PortalView
            portal={{
              name: 'hello',
              initialContext: {
                data: 'Initial data from Native',
              },
            }}
          />
          <Text>Subscribe Token Success Result:</Text>
          <Text>
            {JSON.stringify(subscribeTokenSuccessResponse || '', null, 4)}
          </Text>
          <Button title="Publish Token" onPress={handlePublishToken} />
        </View>
      </ScrollView>
    </SafeAreaView>
  );
}

export default App;

就是这样。我们创建了一个轻巧,高效且用户友好的应用程序,它仍然提供所有必要的功能。您可以通过单击此link在视频演示中看到结果。

通过使用此方法,我们将达到一个平衡,用户可以拥有一个仍然提供他们需要的所有功能的轻量级应用程序。

如前所述,所有代码都可以在GitHub上找到。如果您有任何疑问或反馈,请发表评论。感谢您的意见。祝你有美好的一天!