首页 > 解决方案 > 反应原生博览会项目的 TaskManager 和 BackgroundFetch 的位置?

问题描述

在我的 react native expo 项目中,我正在使用 TaskManager 实现 BackgroundFetch。但是在文档中,我只看到了如何在 App.js 文件中实现代码的示例。但是,我想将此代码委托给外部脚本文件,以获得更好的代码结构。一个不渲染任何东西的脚本文件。另外,我想将此代码与 expo Notifications 结合使用,以在应用程序不在前台时推送通知。

应用结构:

-App
--expo 
--.vscode
--assets
--node_modules
--src
---assets
---components
---constants
---navigation
---redux
---screens
--App.js
--app.json 
--package.json

我的 App.js

import React, { useEffect } from 'react';
import { StyleSheet } from 'react-native';
import MainStackNavigator from './src/navigation/AppNavigator';
import { Provider as StateProvider } from 'react-redux';
import * as BackgroundFetch from 'expo-background-fetch';
import * as TaskManager from 'expo-task-manager';
import store from './src/redux/store';
//import index from './src/index';

BackgroundFetch.setMinimumIntervalAsync(60);
const taskName = 'test-background-fetch';
TaskManager.defineTask(taskName, async () => {
  console.log('background fetch running');
  return BackgroundFetch.Result.NewData;
});
console.log('task defined');

export default class App extends React.Component {
  componentDidMount() {
    this.registerTaskAsync();
  }

  registerTaskAsync = async () => {
    await BackgroundFetch.registerTaskAsync(taskName);
    console.log('task registered');
  };

  render() {
    return (
      <StateProvider store={store}>
        <MainStackNavigator />
      </StateProvider>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

我如何将其委托给外部 js 文件

以及将它与我得到的一些通知代码合并:

const [expoPushToken, setExpoPushToken] = useState('');
  const [notification, setNotification] = useState(false);
  const notificationListener = useRef();
  const responseListener = useRef();

  useEffect(() => {
    registerForPushNotificationsAsync().then((token) =>
      setExpoPushToken(token)
    );

    // This listener is fired whenever a notification is received while the app is foregrounded
    notificationListener.current = Notifications.addNotificationReceivedListener(
      (notification) => {
        setNotification(notification);
      }
    );

    // This listener is fired whenever a user taps on or interacts with a notification (works when app is foregrounded, backgrounded, or killed)
    responseListener.current = Notifications.addNotificationResponseReceivedListener(
      (response) => {
        console.log('When a user interacts with a notification, this will be the response')
        console.log(response);
      }
    );

    return () => {
      Notifications.removeNotificationSubscription(
        notificationListener.current
      );
      Notifications.removeNotificationSubscription(responseListener.current);
    };
  }, []);


async function sendPushNotification(expoPushToken) {
  const message = {
    to: expoPushToken,
    sound: 'default',
    title: 'Morra di jobber ikke her',
    body: 'Det gjør heller ikke fattern',
    data: { someData: 'goes here' },
  };

  await fetch('https://exp.host/--/api/v2/push/send', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Accept-encoding': 'gzip, deflate',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(message),
  });
}

async function registerForPushNotificationsAsync() {
  let token;
  if (Constants.isDevice) {
    const {
      status: existingStatus,
    } = await Notifications.getPermissionsAsync();
    let finalStatus = existingStatus;
    if (existingStatus !== 'granted') {
      const { status } = await Notifications.requestPermissionsAsync();
      finalStatus = status;
    }
    if (finalStatus !== 'granted') {
      alert('Failed to get push token for push notification!');
      return;
    }
    token = (await Notifications.getExpoPushTokenAsync()).data;
    console.log(token);
  } else {
    alert('Must use physical device for Push Notifications');
  }

  if (Platform.OS === 'android') {
    Notifications.setNotificationChannelAsync('default', {
      name: 'default',
      importance: Notifications.AndroidImportance.MAX,
      vibrationPattern: [0, 250, 250, 250],
      lightColor: '#FF231F7C',
    });
  }

  return token;
}

谢谢回答关于时间短的本科生!

标签: javascriptexporeact-native-iosexpo-notificationsreact-native-background-fetch

解决方案


推荐阅读