2016-03-25 13 views
0

コアデータのユーザー設定を保存するためのJSONレスポンスの下に届きます。Objective-cとベストプラクティスでJSON解析の実装を改善しましたか?

preferences={ 
     1={ 
     children=({ 
      3=Samsung;4=Nokia; 
     });id=1;name=Mobiles; 
     };2={ 
     children=({ 
      5="Samsung Curve TV"; 
     });id=2;name=Electronics; 
     }; 
    }; 

これは私のコードスニペットがうまくいきます。しかし、これは非常に冗長なコードだと思います。

NSLog(@"Preferences: %@", [response objectForKey:@"preferences"]); 

    for (NSDictionary *dic in [response objectForKey:@"preferences"]) { 
     NSLog(@"ID: %@", [[[response objectForKey:@"preferences"] objectForKey:dic] objectForKey:@"id"]); 
     NSLog(@"NAME: %@", [[[response objectForKey:@"preferences"] objectForKey:dic] objectForKey:@"name"]); 

     NSLog(@"Children DIC: %@", [[[[[response objectForKey:@"preferences"] 
            objectForKey:dic] objectForKey:@"children"] objectAtIndex:0] objectForKey:@"3"]); 

     for (NSDictionary *childDic in [[[[response objectForKey:@"preferences"] 
              objectForKey:dic] objectForKey:@"children"] objectAtIndex:0]) { 
      NSLog(@"Child Name: %@", [[[[[response objectForKey:@"preferences"] 
             objectForKey:dic] objectForKey:@"children"] objectAtIndex:0] objectForKey:childDic]); 
     } 
    } 

私には3つの質問があります。

  1. コードスニペットを改善するにはどうすればよいですか?これを実装するための方法はありますか?

  2. これはJSONレスポンスがモバイルの解析に適していますか?それは良いJSON形式ですか?コアデータを使用するという点でモバイル開発者として従うべきJSON応答形式はありますか?

  3. Objective-cからこのようにJSON文字列を再構築するにはどうすればよいですか?

+0

他人とどうやって学ぶか、第三者などhttps://github.com/icanzilb/JSONModel – Injectios

+0

質問には回答があります。 – user3182143

+0

@Injectios何をお勧めしますか?JSONModelへのJSONレスポンスの上に変換できますか?私はJSONModelを認識していますが、この応答がこれとどのように互換性があるのか​​わかりません。 – happycoder

答えて

0

[OK]をので、(深くない分析のために申し訳ありません)まず第一に、あなたのJSONを動的eleのためにdictionaryを含まないように修正したいメント(サムスンキー3を持っているというように、それは意味を成して、配列すべきですか?)

私は私見より良いJSON構造を思い付く:

{ 
    "preferences":[ 
     { 
     "items":[ 
      { 
      "id" : "3", 
      "name" : "Samsung" 
      }, 
      { 
      "id" : "3", 
      "name" : "Nokia" 
      } 
     ], 
     "id":"1", 
     "name":"Mobiles" 
     }, 
     { 
     "items":[ 
      { 
      "id" : "3", 
      "name" : "Nokia" 
      } 
     ], 
     "id":"2", 
     "name":"Electronics" 
     } 
] 
} 

それはJSONModelを持つオブジェクトにマッピングするために、今は本当に簡単ですあなたが気を付けるべきことは、キーをマッピングすることだけです。

NSString *JSONString = @" {  \"preferences\":[  {   \"items\":[   {    \"id\" : \"3\",    \"name\" : \"Samsung\"   },   {    \"id\" : \"3\",    \"name\" : \"Nokia\"   }   ],   \"id\":\"1\",   \"name\":\"Mobiles\"  },  {   \"items\":[   {    \"id\" : \"3\",    \"name\" : \"Nokia\"   }   ],   \"id\":\"2\",   \"name\":\"Electronics\"  }  ] }"; 


    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:[JSONString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; 

    NSError *mapError; 
    GlobalPreferences *globalPreferences = [[GlobalPreferences alloc] initWithDictionary:dictionary error:&mapError]; 
    if (mapError) { 
     NSLog(@"Something went wrong with mapping model %@", mapError); 
    } 

    NSLog(@"Your mapped model: %@", globalPreferences); 

モデル:

ちょっとGlobalPreference、ルートモデルは、ケースにはuが余分に何か

#import <JSONModel/JSONModel.h> 
    #import "Preference.h" 

    @interface GlobalPreferences : JSONModel 

    @property (nonatomic, strong) NSArray<Preference> *preferences; // using protocol here you specifying to which model data should be mapped 
    @property (nonatomic, strong) NSArray<Optional> *somethingElse; // some other settings may be here 

    @end 

    #import "GlobalPreferences.h" 

    @implementation GlobalPreferences 

    @end 

好み

#import <JSONModel/JSONModel.h> 
    #import "PreferenceItem.h" 

    @protocol Preference <NSObject> 

    @end 

    @interface Preference : JSONModel 

    @property (nonatomic, strong) NSNumber *ID; // required 
    @property (nonatomic, strong) NSString *name; // required 
    @property (nonatomic, strong) NSArray<PreferenceItem> *items; 

    @end 

    #import "Preference.h" 

    @implementation Preference 

    #pragma mark - JSONModel 

    + (JSONKeyMapper *)keyMapper { 
     return [[JSONKeyMapper alloc] initWithDictionary:@{ 
                  @"id": @"ID", 
                  }]; 
    } 

    @end 

PreferenceItem

を追加することにした場合

coreDataには問題ありません。

多分あなたのためにこれは必要ではありませんが、例えばdata typesmissing keyserror handlingなどのネットワーク応答を解析/マッピングするときに気をつける必要があることがたくさんあります。あなたが手動でそれをマップするなら - あなたはいつかアプリを壊してしまう危険性があります。

+0

詳細な回答ありがとうございます。あなたが意味することは、「アイテム」を持たないことです:応答すると、この種類のキー(例:id)は解析が難しいというこの種類のキー(例:id):[ { "id": "3"、 "name": "Nokia"} ] ?バックエンドの人は、JSON形式を変更したくないと思っています。 JSONモデルでもそのレスポンスを使用できますか?これをどうやって説明するのですか? :D(つまり、実際に他のエキスパートが何をしているかを示す信頼できる情報源を質問する理由) – happycoder

+0

データベースからの値を単純にコレクションのキーにしないといけないと思います。これらのキーでjsonを解析するためのプロパティを作成する必要があります。あなたは値を知らないのではなく、データベース内のフィールドを知っている(ID、名前など) – Injectios

+0

JSONを使用する場合、カスタムモデルを持つことはできません。NSDictionaryをモデルオブジェクトとして使用するだけです簡単に、あなたと同じようにほとんど同じことをしました。または、model.id = dictionary.keyのように手動でマップする必要があります。私はこれがAPIを行う適切な方法ではないと思うf.eをこれをチェックアウトhttp://stackoverflow.com/questions/12806386/standard-json-api-response-format – Injectios

0

私はあなたのObjective-Cのためのベストプラクティスを求めて知っているが、私は、スウィフトに切り替えるとSwiftyJSONを使用してお勧めします。 Swiftでは、Objective-Cよりもコードがはるかに読みやすくなります。

let prefs = json["preferences"] 
let userName = prefs["id"].stringValue 
let name = prefs["name"].stringValue 
let child = prefs["children"].arrayValue[0].arrayValue[3] 

https://github.com/SwiftyJSON/SwiftyJSON

あなたは簡単に独自のJSONの構造を構築し、Alamofireでそれらを送信することができます

let parameters: [String : AnyObject] = [ 
    "preferences": [ 
    "id": "123", 
    "name": "John", 
    "children": [ 
     ["3": "Three"] 
    ] 
    ] 
] 

let urlReq = NSMutableURLRequest(url) 
urlReq.HTTPMethod = .POST 

let req = Alamofire.ParameterEncoding.JSON.encode(urlReq, parameters: parameters).0 
let request = Alamofire.request(req) 

https://github.com/Alamofire/Alamofire

+0

ありがとうございます。私は得ることができるアプローチ? – happycoder

関連する問題