web-dev-qa-db-fra.com

Comment exécuter socket.io en arrière-plan sur iOS dans une application React Native?

J'utilise socket.io dans une iOS React Native(v0.20) app. L'application suit ma position et, lorsque ma position change, elle envoie un message à un serveur. Si la connexion au socket est perdue, le serveur envoie un email pour me prévenir. 

Le suivi de localisation fonctionne en arrière-plan avec react-native-location , mais je ne parviens pas à faire fonctionner socket.io. À chaque fois que je change d'application ou que j'éteins l'écran, l'application continue de suivre ma position, mais je perds la connexion par socket.

Existe-t-il un moyen d'exécuter socket.io en arrière-plan, tel que le suivi de localisation? À part cela, y a-t-il un code natif qui me permettra de conserver un client/server connection en arrière-plan?

Je sais qu'il existe une alternative WebSocket mais je ne vois pas comment le faire fonctionner en arrière-plan.

UPDATE: J'ai doublé vérifié mon Info.plist, il a déjà défini les valeurs d'arrière-plan nécessaires pour react-native-location . Je ne sais pas si cela compte, mais le travail sur les sockets et le suivi de la localisation se font dans le même composant.

 enter image description here

LocationComponent.js

window.navigator.userAgent = 'react-native';
const io = require('socket.io-client/socket.io');
const socket = io(url, {jsonp: false});

import React, { Text, View, DeviceEventEmitter } from 'react-native';
import { RNLocation } from 'NativeModules';

export default GeolocationExample = React.createClass({

  componentDidMount: function() {
    RNLocation.requestAlwaysAuthorization();
    RNLocation.startUpdatingLocation();
    RNLocation.setDistanceFilter(3.0);
    DeviceEventEmitter.addListener('locationUpdated', locationObject => {
      this.props.newPosition({ longitude: locationObject.coords.longitude, latitude: locationObject.coords.latitude });
    });
  },

  render: function() {
    const { lastPosition, distance } = this.props;
    socket.emit('newPos', { longitude: lastPosition.longitude, latitude: lastPosition.latitude, distance, time: Date() });
    return (
      <View>
        <Text> {distance} </Text>
      </View>
    );
  }
});
19
EasilyBaffled

Il n'y a aucun moyen de faire cela "de la bonne façon".

Modifier

De la documentation officielle } _ d'Apple:

Mise en œuvre de tâches de longue durée

Pour les tâches nécessitant plus de temps d'exécution, vous devez demander des autorisations spécifiques pour les exécuter en arrière-plan sans leur être suspendu. Dans iOS, seuls les types d'applications spécifiques sont autorisés à courir en arrière plan:

Applications qui diffusent un contenu audible à l'utilisateur en arrière-plan, comme une application de lecteur de musique 

Applications qui enregistrent du contenu audio dans le Contexte 

Applications permettant aux utilisateurs d’être informés de leur emplacement fois, comme une application de navigation 

Applications prenant en charge le protocole de voix sur IP (VoIP) 

Applications nécessitant de télécharger et de traiter régulièrement du nouveau contenu

Applications recevant des mises à jour régulières d'accessoires externes

Les applications qui implémentent ces services doivent déclarer les services qu’ils soutenir et utiliser les cadres système pour mettre en œuvre les aspects pertinents de ces services. La déclaration des services indique au système lequel services que vous utilisez, mais dans certains cas, ce sont les cadres système qui effectivement empêcher votre demande d'être suspendue.

Ceci étant dit, il existe une technique permettant de garder votre socket ouvert: 

Jouez un son silencieux et définissez le mode d’arrière-plan sur audio. Vérifiez cet article _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _.C afin.— Cela vous permettra de garder votre prise ouverte en simulant une application audio. Votre info.plist doit être mis à jour pour permettre à l'audio de s'exécuter en arrière-plan .UIBackgroundModes doit être défini sur audio (consultez la docs pour plus d'informations)

3
G. Hamaide

iOS est assez restrictif sur le type de processus qu'il autorise lorsqu'une application est en arrière-plan

Il semble y avoir une discussion autour de cela sur le socket/client/ suivi des problèmes .

Il semble que la connexion de socket reste active si le mode d’arrière-plan est défini sur audio. YMMV

Vérifiez que vous définissez les valeurs correctes dans la section UIBackgroundModes du fichier Info.plist. Comment faire cela en XCode

1
frank

Je sais qu'il existe des hacks pour y parvenir (c'est-à-dire le hack audio), mais il y a une raison pour laquelle iOS n'autorise pas les tâches longues à exécuter en arrière-plan - veuillez repenser votre conception pour permettre un meilleur produit.

L'utilisation des tâches d'exécution du journal épuisera la batterie. Si vous avez besoin de mises à jour de données, enregistrez-vous pour obtenir des notifications Push à l'aide du service Apple Push (c'est gratuit, si vous le faites directement, ou si c'était la dernière fois que j'ai traité d'un problème similaire).

Le suivi d'emplacement, en particulier, est un service système en arrière-plan autorisé, envisagez d'utiliser l'API native pour cela.

Pour ce qui est d'envoyer les données au serveur, vous ne pourrez pas (et ne devriez probablement pas) maintenir une connexion durable avec le serveur.

Envisagez de collecter des données et de télécharger le lot collecté de temps en temps sur le serveur. De préférence, lorsque l'application est rouverte, vous ne gaspillez pas de ressources en arrière-plan et ne fâchez pas les gens au sujet de la vie de leur batterie et de leur consommation de données.

1
Myst

Dans votre image de Info.plist, seuls les trois modes arrière-plan suivants sont autorisés:

  1. Fetch de fond 
  2. Mises à jour de l'emplacement
  3. Notifications à distance

    Vous devez autoriser le mode "Audio et AirPlay". Il semble que "L'application lit ou diffuse de l'audio/de la vidéo en utilisant Airplay".

0
waynezhu