4

iOSとCocoaは初めてです。私の質問は、何かを機能させる方法ではなく、UXとパフォーマンスを向上させるためのデザインについてです。

既存のアプリに機能を追加しています。現在、アプリにはサーバーリクエストの作成を担当するクラス「RootViewController」(RVC)が1つあります。RVCは、json応答のためにサーバーを呼び出します。このjson応答は解析され、解析された応答は「array」と呼ばれるNSArrayオブジェクトによって参照されます。サーバーが「アレイ」に提供するデータは、他の顧客が購入できるライブインベントリを表すため、定期的に更新する必要があります。

アプリの存続期間中のさまざまな時点で、他のクラスの「配列」への参照を使用する必要があります。「配列」を使用または更新するたびにサーバーを呼び出したくありません。自分のデバイスでこのアプリをテストすると、サーバーの呼び出しが遅くなる可能性があるようです->アプリのパフォーマンスが低下します。

NSArrayへの参照を保持するためのデリゲートとして機能できるクラスを作成することを検討しました。これは、グローバル変数のように機能するようなものです。サーバーに非同期リクエストを送信し、このデリゲートクラスの応答に対応します。このアプローチが効率的であるか、またはベストプラクティスを考慮しているか(MVCを念頭に置いて)を判断する方法がわかりません。

ネットワークやメモリ使用量にあまり依存せずに他のクラスがすぐに使用できるように、「配列」を格納するのに最適な場所を探しています。「アレイ」は、サーバーから時々更新できる必要があります(「モデル」はインベントリの変更によって変更される可能性があるため)。私の調査によると、iOSのCoreDataを開始するのに最適な場所のようですが、アプリがアクティブでない場合にCoreDataを定期的に更新する方法がわかりません。つまり、CoreDataのデータが最近更新されていない場合は、古いデータをユーザーに提示したくありません。

jsonの応答は約20KB〜45KBです。

定期的に更新できるように軽量オブジェクトを保管するのに最適な/代替の場所はどこですか?私はセッションスタイル変数に傾倒していますが、これを行うためのより良い方法があるかどうかはわかりません。

4

3 に答える 3

2

MVCに従ってこれを見るには、次の2つの部分があります。

  • アレイ–これはモデルです
  • サーバーからインベントリをフェッチするコード–これはコントローラーです

このコントローラーコードは、実際にはモデルコントローラーであり、ビューコントローラーではありません。ビューコントローラクラスには入れません。コードが非常に単純な場合は、アプリデリゲートに配置できますが、完全に独自のクラスに配置することをお勧めします。

-applicationDidFinishLaunchingで:

[[InventoryController sharedInstance] reloadContent];
[[InventoryController sharedInstance] scheduleUpdates];

InventoryController.h

@interface InventoryController

@property (retain) NSArray *inventory;
@property (retain) NSTimer *reloadTimer;

+ (InventoryController *) sharedInstance;
- (void) reloadContent;
- (void) scheduleUpdates;

@end

InventoryController.m

@implmentation InventoryController

- (void) reloadContent {
    ...
}

+ (InventoryController *) sharedInstance {
    static InventoryController * singleton;
    if (!singleton)
        singleton = [[self.class alloc] init];
    return singleton;
}

- (void) scheduleUpdates {
    self.reloadTimer = ...;
}

@end

他のどこでも:

NSArray *inventory = [[InventoryController sharedInstance] inventory];

では-reloadContent、サーバーからコンテンツをプルする必要があります。では-scheduleUpdates、コントローラーに作用するタイマーを設定して、定期的にデータをリロードする必要があります。データが古くなったときにViewControllerの動作を調整する必要がある場合は、配列と一緒にNSDateを格納し-isStale、日付をチェックするようなメソッドを追加して、最初にそれを呼び出します。

バックグラウンドでURLをロードすることを忘れないでください。イベントまたはアクションの処理中にデータを停止して再読み込みしないでください。したがって、基本的に、View Controllerは、データを待機している間にactionメソッドから戻り、データを取得したときに表示を調整する必要があります。

データが更新された後にViewControllerが応答する必要がある場合は、View Controllerに通知を登録してもらい、インベントリコントローラがコンテンツの更新を終了したときに投稿できるようにします。

    [[NSNotificationCenter defaultCenter]
    postNotificationName:InventoryControllerDidReloadContent
                  object:self];

アプリがバックグラウンドになったときにメモリからインベントリデータを削除できるようにデバイスにインベントリデータをキャッシュする場合は、配列をプロパティリストに書き込むことでそれを行うことができますが、古いデータが役に立たない場合は、そうではない可能性があります気になりたい。

配列とプロパティリストの代わりにCoreDataを使用することもできますが、サーバーからデータをロードしてコンテキストにロードするコントローラーは不要です。配列を使用する代わりに、管理対象オブジェクトコンテキストとフェッチされた結果コントローラーを使用することもできます。アプリでそのコンテンツを編集していない場合、CoreDataが配列やプロパティリストよりも優れているとは思えません。

于 2012-11-16T22:42:42.460 に答える
0

これをアプリケーションデリゲートに保存することをお勧めします。配列を格納するのに適していて、アプリのどのクラスからでもアクセスできます。

于 2012-11-16T22:15:12.760 に答える
0

この「配列」が興味深い構造を持っている場合、CoreDataは良い選択です。この場合、CoreDataとplistは互いにほぼ同じ速さになると思います。最も単純と思われる方を使用し、遅すぎる場合はもう一方を試してください。

アプリの実行中にデータを更新する必要がないようにしてください。キャッシュされたデータとともに最終更新時刻を保存します。「古すぎる」場合は、「お待ちください」プレースホルダーを表示して更新してください。「古いが古すぎない」場合は、持っているものを表示し、非メインスレッドで更新します。または、そのUIの他のバリエーションを試してください(「古すぎる」==通知+読み取り専用モード)。

アプリのレビューを過ぎてバックグラウンドで更新するコツを見つけた場合は、これがユーザーのバッテリーをどれだけ消費するかについて、じっくり考えてください。それを無効にする方法を追加します。または、デフォルトで無効にして、有効にする方法を追加します。または単にそれをしないでください。:-)

于 2012-11-16T22:22:50.027 に答える