web-dev-qa-db-ja.com

iOSアプリケーションのグローバル定数をどこに保存しますか?

私のiOSアプリのほとんどのモデルはWebサーバーを照会します。サーバーのベースURLを格納する構成ファイルが必要です。次のようになります。

// production
// static NSString* const baseUrl = "http://website.com/"

// testing
static NSString* const baseUrl = "http://192.168.0.123/"

行をコメントアウトすることで、モデルが指すサーバーを即座に変更できます。私の質問は、iOSにグローバル定数を保存するためのベストプラクティスは何ですか? Androidプログラミングでは、この組み込みの stringsリソースファイル があります。 ActivityIViewController と同等)で、次の文字列定数を取得できます。

String string = this.getString(R.string.someConstant);

IOS SDKに定数を保存するための類似した場所があるかどうか疑問に思っていました。そうでない場合、Objective-Cのベストプラクティスは何ですか?

109
JoJo

またすることができます

#define kBaseURL @"http://192.168.0.123/"

「定数」ヘッダーファイルでは、constants.hと言います。それから

#include "constants.h"

この定数が必要なすべてのファイルの先頭。

このように、コンパイラフラグに応じて、サーバーを次のように切り替えることができます。

#ifdef DEBUG
    #define kBaseURL @"http://192.168.0.123/"
#else
    #define kBaseURL @"http://myproductionserver.com/"
#endif
145
Cyrille

さて、あなたはそれが関係するインターフェースに対してローカルな宣言が欲しいです-アプリ全体の定数ファイルは良いことではありません。

また、extern NSString* constを使用するのではなく、単に#defineシンボルを宣言することをお勧めします。


SomeFile.h

extern NSString* const MONAppsBaseUrl;

SomeFile.m

#import "SomeFile.h"

#ifdef DEBUG
NSString* const MONAppsBaseUrl = @"http://192.168.0.123/";
#else
NSString* const MONAppsBaseUrl = @"http://website.com/";
#endif

C++互換のExtern宣言の省略は別として、これはAppleのObj-Cフレームワークで一般的に使用されるものです。

定数を1つのファイルまたは関数のみに表示する必要がある場合は、static NSString* const baseUrl*.mが適切です。

167
justin

グローバル定数を定義する方法:


AppConstants.h

extern NSString* const kAppBaseURL;

AppConstants.m

#import "AppConstants.h"

#ifdef DEBUG
NSString* const kAppBaseURL = @"http://192.168.0.123/";
#else
NSString* const kAppBaseURL = @"http://website.com/";
#endif

次に、{$ APP} -Prefix.pchファイルで:

#ifdef __OBJC__
  #import <UIKit/UIKit.h>
  #import <Foundation/Foundation.h>
  #import "AppConstants.h"
#endif

問題が発生した場合は、まず、プリコンパイルプレフィックスヘッダーオプションがNOに設定されていることを確認してください。

39
Piotr Tomasik

次のように文字列定数を連結することもできます。

  #define kBaseURL @"http://myServer.com"
  #define kFullURL kBaseURL @"/api/request"
5
Martin Reichl

これを行う別の方法ははるかに簡単で、すべてのファイルではなく、.pchプレフィックスファイルのように、必要なファイルに含めるだけだと思います。

#ifndef Constants_h
#define Constants_h

//Some constants
static int const ZERO = 0;
static int const ONE = 1;
static int const TWO = 2;

#endif /* Constants_h */

その後、このヘッダーファイルを必要なヘッダーファイルに含めます。含める特定のクラスのヘッダーファイルにそれを含めます。

#include "Constants.h"
3
  1. YOURPROJECT-Prefix.pchファイルでグローバル定数を定義します。
  2. #define BASEURl @"http://myWebService.appspot.com/xyz/xx"
  3. 次に、プロジェクト内の任意の場所でBASEURLを使用します。

    NSString *LOGIN_URL= [BASEURl stringByAppendingString:@"/users/login"];
    

更新:Xcode 6では、プロジェクトで作成されたデフォルトの.pchファイルは見つかりません。 Xcode 6のPCHファイル を使用して、プロジェクトに.pchファイルを挿入してください。

更新:Swiftの場合

  1. 新しいSwiftファイルを作成する[クラスなしで空]と言う[AppGlobalMemebers]
  2. &すぐにメンバーを宣言/定義する

    例:

    var STATUS_BAR_GREEN : UIColor  = UIColor(red: 106/255.0, green: 161/255.0, blue: 7/255.0, alpha: 1)  //
    
    1. AppdelegateまたはSingletonクラスなどのクラスファイルでアプリのグローバルメンバーを定義する場合は、クラス定義の上に特定のメンバーを宣言します
3
Yogesh Lolusare

グローバル宣言は興味深いですが、私にとって、コードへの私の道を大きく変えたのは、クラスのグローバルインスタンスを持つことでした。作業方法を本当に理解するのに数日かかりましたので、ここで簡単にまとめました

クラスのグローバルインスタンス(必要に応じてプロジェクトごとに1つまたは2つ)を使用して、コアデータアクセスまたはいくつかの取引ロジックを再グループ化します。

たとえば、すべてのレストランのテーブルを処理する中央オブジェクトが必要な場合は、起動時にオブジェクトを作成します。このオブジェクトは、データベースアクセスを処理できますOR保存する必要がない場合は、メモリ内で処理します。それは一元化されており、有用なインターフェースのみを表示します...!

それは素晴らしい助けであり、オブジェクト指向であり、すべてを同じ場所に置く良い方法です

数行のコード:

@interface RestaurantManager : NSObject
    +(id) sharedInstance;
    -(void)registerForTable:(NSNumber *)tableId;
@end 

およびオブジェクトの実装:

@implementation RestaurantManager

+ (id) sharedInstance {
    static dispatch_once_t onceQueue;

    dispatch_once(&onceQueue, ^{
        sharedInstance = [[self alloc] init];
        NSLog(@"*** Shared instance initialisation ***");
    });
    return sharedInstance;
}

-(void)registerForTable:(NSNumber *)tableId {
}
@end

それを使用するためにそれは本当に簡単です:

[[RestaurantManager sharedInstance] registerForTable:[NsNumber numberWithInt:10]]

2

以前に使用したアプローチは、Settings.plistを使用して起動時にファイルregisterDefaults:を作成し、NSUserDefaultsにロードすることです。その後、次の方法でそのコンテンツにアクセスできます。

// Assuming you've defined some constant kMySettingKey.
[[NSUserDefaults standardUserDefaults] objectForKey:kMySettingKey];

Androidの開発は行っていませんが、説明した文字列リソースファイルに似ているように聞こえます。唯一の欠点は、プリプロセッサを使用して設定を切り替えることができないことです(例:DEBUGモード)。ただし、別のファイルをロードできると思います。

NSUserDefaultsドキュメント。

0
Chris Doble

構成オブジェクトを使用するplistから初期化します。無関係な外部のもので他のクラスを悩ませるのはなぜですか?

このため、 eppz!settigns soleyを作成しました。 plistのデフォルト値を組み込む方法については、 NSUserDefaults に保存する高度で簡単な方法を参照してください。

enter image description here

0
Geri

受け入れられた答えには2つの弱点があります。最初に、他の人が指摘したように、#defineの使用はデバッグが難しいため、代わりにextern NSString* const kBaseUrl構造を使用します。次に、定数用の単一ファイルを定義します。 IMO、ほとんどのクラスはそれらの定数にアクセスする必要がないか、すべての定数がそこに宣言されているとファイルに加えてすべてにアクセスする必要があるため、これは間違っています。より良い解決策は、3つの異なる層で定数をモジュール化することです。

  1. システム層:SystemConstants.hまたはAppConstants.hは、システム内の任意のクラスからアクセスできるグローバルスコープの定数を記述します。ここでは、関連していない異なるクラスからアクセスする必要がある定数のみを宣言します。

  2. モジュール/サブシステム層:ModuleNameConstants.hは、モジュール/サブシステム内の一連の関連クラスに典型的な定数のセットを記述します。

  3. クラス層:定数はクラス内にあり、クラスによってのみ使用されます。

1,2のみが質問に関連しています。

0
tesla

番号については、次のように使用できます

#define MAX_HEIGHT 12.5
0
Gihan