web-dev-qa-db-ja.com

ReactネイティブアプリでiOSのバックグラウンドでsocket.ioを実行する方法は?

iOS React Native(v0.20) appsocket.ioを使用しています。アプリは私の位置を追跡し、私の位置が変わると、サーバーにメッセージを送信します。ソケット接続が失われた場合、サーバーは私に通知するメールを送信します。

react-native-location を使用して位置追跡をバックグラウンドで実行していますが、socket.ioを機能させることができません。アプリを変更したり画面をオフにしたりすると、アプリは現在地を追跡し続けますが、ソケット接続を失います。

位置追跡のようにバックグラウンドでsocket.ioを実行する方法はありますか?それ以外に、バックグラウンドでclient/server connectionを維持できるネイティブコードはありますか?

WebSocketの代替 があることは知っていますが、バックグラウンドで実行する方法がわかりません。

UPDATE:私は自分のInfo.plistをダブルチェックしました react-native-location に必要なバックグラウンド値がすでに設定されています=。それが重要かどうかはわかりませんが、ソケット作業と位置追跡は同じコンポーネントで行われます。

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

これを「正しい方法」で行う方法はありません。

編集

Appleの 公式ドキュメント から:

長期実行タスクの実装

実装により多くの実行時間を必要とするタスクの場合、中断することなくバックグラウンドで実行するために特定の権限を要求する必要があります。 iOSでは、特定の種類のアプリのみがバックグラウンドで実行できます。

音楽プレーヤーアプリなど、バックグラウンドでユーザーに可聴コンテンツを再生するアプリ

バックグラウンドでオーディオコンテンツを録音するアプリ

ナビゲーションアプリなど、ユーザーに常に現在地を知らせるアプリ

Voice over Internet Protocol(VoIP)をサポートするアプリ

新しいコンテンツを定期的にダウンロードして処理する必要があるアプリ

外部アクセサリから定期的なアップデートを受け取るアプリ

これらのサービスを実装するアプリは、サポートするサービスを宣言し、システムフレームワークを使用してそれらのサービスの関連する側面を実装する必要があります。サービスを宣言すると、システムは使用するサービスを認識できますが、アプリケーションの中断を実際に防止するのはシステムフレームワークである場合があります。

これが言われている、あなたのソケットを開いたままにするための実用的なテクニックがあります:

サイレントサウンドを再生し、バックグラウンドモードをオーディオに設定します。問題の詳細については この記事 を確認してください(少し古いですが、まだ有効です)。これにより、オーディオアプリを装ってソケットを開いたままにすることができます。オーディオをバックグラウンドで実行できるように、info.plistを更新する必要があります。 UIBackgroundModesshould to set to audio(check the docs for more information)

4
G. Hamaide

これを行うためのハック(つまりaudioハック)があることは知っていますが、iOSがバックグラウンドで長時間実行されるタスクを許可しない理由があります。より良い製品を可能にするために設計を再検討してください。

ログ実行タスクを使用すると、バッテリーが消耗します。データの更新が必要な場合は、Appleプッシュサービスを使用してプッシュ通知を取得するように登録してください(直接行う場合は無料です。または、前回同様の問題に対処した場合は無料です)。

具体的には、位置追跡は許可されたバックグラウンドシステムサービスです。これにはネイティブAPIの使用を検討してください。

データをサーバーにプッシュすることに関しては、サーバーとの長期にわたる接続を維持することはできません(おそらくそうすべきではありません)。

データを収集し、収集されたバッチを時々サーバーにアップロードすることを検討してください。できればアプリを再度開いたときに、バックグラウンドでリソースを無駄にせず、バッテリーの寿命とデータの消費に人々を混乱させないようにします。

2
Myst

iOSでは、許可されるプロセスの種類にかなり制限があります アプリがバックグラウンドで実行されている場合

Socket.ioクライアント issue tracker でこれに関していくつかの議論があるようです。

バックグラウンドモードをaudioに設定すると、ソケット接続がアクティブのままになるようです。 YMMV

Info.plistファイルのUIBackgroundModesセクションで正しい値を設定していることを確認してください。 XCodeでこれを行う方法

1
frank

Info.plistの画像では、次の3つの バックグラウンドモード のみが許可されます。

  1. バックグラウンドフェッチ
  2. 現在地の更新
  3. リモート通知

    「オーディオとAirPlay」モードを許可する必要があり、「アプリがAirplayを使用してオーディオを再生するか、オーディオ/ビデオをストリーミングする」のようです。

0
waynezhu