16

メタタグを持つ iPad 用の webapp があります。

<meta name="apple-mobile-web-app-capable" content="yes">

ホームページ(ウェブアプリ対応版)からアプリを開くか、Mobile Safariでアドレスを入力すると、localStorageの内容が異なります。location.href を印刷して、アドレスが同一であることを確認しました。

Mobile Safari の使用中に localStorage に加えられたすべての変更は、Web アプリ対応バージョンに反映されますが、Web アプリ対応バージョンに加えられた変更は Mobile Safari バージョンには反映されません。

ドメインは同一であり、localStorage は同一である必要があります。世界で何が起こっているのですか?これは修正できますか?


更新 - 解決策: 受け入れられた回答からの提案 #2 (ユーザーをフルスクリーン モードにすることを強制する) に従って、次のコードを追加しました。

if(("standalone" in window.navigator) && !window.navigator.standalone)
    window.location = "instructions.html";

そのため、スタンドアロン モードをサポートするブラウザを使用していて、スタンドアロン モードではない場合は、アプリをホーム画面に追加する方法をユーザーに示すページ (instructions.html) にリダイレクトします。

ご意見をお寄せいただきありがとうございます。

4

3 に答える 3

31

概要:

Safari とフルスクリーン Web アプリ (別名 Web アプリ対応) には、localStorage データの個別のインメモリ ライトスルー キャッシュがあります。フルスクリーン アプリがアクティブになるたびに、ディスクから localStorage をリロードします (Safari の変更を表示できるようにします)。ただし、Safari がアクティブになると、localStorage データがディスクからリロードされないため、Safari を強制終了して再起動しない限り、フルスクリーン アプリで行われた変更は表示されません。

完全な説明:

コンピュータ サイエンスの難しい問題は2 つだけです。

  1. キャッシュの無効化
  2. ものに名前を付ける
  3. オフバイワンエラー

localStorage のバグのある動作は、問題 #1 の結果です。理由は次のとおりです。

iOS ブラウザー エンジンがロードされると、localStorage のデータがディスクから読み取られ、メモリにキャッシュされます。次に、データを読み取るたびに (例: getItem)、データはディスクからではなくメモリから読み取られます。書き込み時 (たとえばsetItem)、データはメモリに書き込まれ、(非同期的に) ディスクにフラッシュされます。localStorage は同期であるため、この実装は完全に合理的です。すべての読み取りと書き込みのためにディスクに行った場合、高価なディスク IO を実行するために、すべての読み取り/書き込みで JavaScript がブロックされます。

問題は、フル スクリーン Web アプリ (FSWA と呼びましょう) が iOS ブラウザー エンジンの別のインスタンスを使用し、FSWA が localStorage データ用にディスク上の同じ場所を共有しているにもかかわらず、メモリ内キャッシュを共有していないことです。 Safari を使用した localStorage データの。

アクティブなアプリケーションになるたびに FSWA が完全にリロードされる (つまり、localStorage データがディスクからリロードされる) という事実を追加すると、見ている動作が得られます。

舞台裏はこちら…

  1. ユーザーは、Safari で localStorage にデータを書き込む変更を行います
  2. Safari はデータを Safari のメモリ内 localStorage キャッシュに書き込みます
  3. Safari は localStorage データをキャッシュからディスクにフラッシュします
  4. ユーザーがサファリを離れ、FSWA を起動する
  5. FSWA は、ローカル ストレージ データをディスクからインメモリ キャッシュにロードして読み取ります。
  6. ユーザーは、Safari で (手順 1 で) 変更されたデータを確認します。
  7. ユーザーが localStorage にデータを書き込む FSWA に変更を加える
  8. FSWA は localStorage キャッシュにデータを書き込みます (Safari のキャッシュは更新されません)。
  9. FSWA は localStorage キャッシュ データをディスクにフラッシュします
  10. ユーザーが Safari に戻る
  11. Safari はすでに実行されており、ディスクから localStorage データをリロードしません。
  12. Safari は既存のメモリ内キャッシュから古いデータを読み取ります
  13. 手順 7 で行った変更がユーザーに表示されない

これを証明するために、手順 4 と手順 10 の間でSafari を強制終了できます。その後、手順 11 で Safari を再起動すると、ディスクから localStorage がリロードされ、FSWA によって書き込まれたデータが表示されます。

于 2012-08-25T15:32:04.253 に答える
5

iOS5では、同じドメインに2つのフルスクリーンWebアプリを配置して、互いのlocalStorageを表示することができました。これは、フルスクリーンとSafariの違いを克服しました。

ただし、iOS6では、2つのフルスクリーンWebアプリを1つのアプリにマージする必要があります。

于 2012-10-24T11:48:22.887 に答える
3

あなたがローカル ストレージ データを正しく保存していると仮定すると、私が間違っていなければ、あなたが経験することはWeb アプリ開発者の間でやや一般的な問題です。Cookie、セッション、およびローカル ストレージは、モバイル サファリ経由で保存されたデータとは異なる方法で "Web アプリ" (ホーム画面から起動) に保存されているようです。

私はこれについてかなり徹底的なテストを過去にいくつか行ってきましたが、十分な回避策はないように思えます。私の同僚と私が同様の問題に直面した例を挙げてみましょう。最近開発した Web アプリでは、ユーザーはすべての機能にアクセスする前にログインする必要があります。モバイル サファリ経由でログインし、アプリのダウンロード バージョンに切り替えると、ログインが期待されますが、常にそうであるとは限りません。通常は再度ログインする必要があり、アプリを起動する方法や場所によっては、Cookie がさまざまな「データ バンク」に保存される可能性があることを示唆しています。

さらに、Calvin が言うように、これには単なるさまざまなデータ バンク以上のものがあります。ホーム画面から起動したアプリの起動が遅くなり、ホーム画面のアプリは起動時に常にリロードされ、マルチタスクのサポートがないことが示唆されます。 .

Apple による優れた機能ですが、ホームスクリーン Web アプリは期待どおりに、または期待どおりに機能しません (サファリで開いた場合など)。特定の問題がある場合は、次の代替案のいずれかをお勧めします。

  1. 代わりにmysqlデータベースを使用して r/w from/to する
  2. ユーザーがアプリを使用する前にダウンロードすることを強制します(この例のように)
  3. ユーザーにアプリのダウンロードを勧めたり、ほとんどのユーザーがモバイル サファリからアクセスすると想定したりしないでください。
  4. データが異なる可能性があるという事実を受け入れます (アプリの性質によっては、これが代替ではない場合があります)。
  5. 私のアプローチでは、Phonegap の組み込み機能を使用して、Web アプリをネイティブ アプリに "変換" しますもしそうなら、Jonathan Stark によるこのチュートリアルを見てください。

これが少なくともその一部を明確にするのに役立つことを願っています。

于 2012-07-23T00:13:19.840 に答える