【问题标题】:create data model for JSON - IOS/Objective-C为 JSON 创建数据模型 - IOS/Objective-C
【发布时间】:2015-11-19 23:19:12
【问题描述】:

我正在用 Objective C 开发一个 IOS 应用程序,我将在其中调用一个 URL 来检索数组 JSON 对象(餐厅)。我想将它们解析为一个objective-C Model。使用它们填充到我已经设计的 UICollectionView 上。我的任务要求我设计这个模型来存储 Json 对象,然后使用它们填充到 UICollectionView。我不知道如何在 Objective-C 中实现这一点,请帮助我。检索到的JSON如下。

"restaurants" : [
{
    "name": "Burger Bar",
    "backgroundImageURL": "http://somthing.com/Images/1.png",
    "category" : "Burgers",
        "contact": {
            "phone": "1231231231",
            "formattedPhone": "(123) 123-1231",
            "twitter": "1twitter"
        },
        "location": {
            "address": "5100 Belt Line Road, STE 502",
            "crossStreet": "Dallas North Tollway",
            "lat": 32.950787,
            "lng": -96.821118,
            "postalCode": "75254",
            "cc": "US",
            "city": "Addison",
            "state": "TX",
            "country": "United States",
            "formattedAddress": [
                "5100 Belt Line Road, STE 502 (Dallas North Tollway)",
                "Addison, TX 75254",
                "United States"
            ]
        }
},
{
    "name": "seafood Kitchen",
    "backgroundImageURL": "http://somthing.com/Images/2.png",
    "category": "Seafood",
        "contact": {
            "phone": "3213213213",
            "formattedPhone": "(321) 321-3213",
            "twitter": "2twitter"
        },
        "location": {
            "address": "18349 Dallas Pkwy",
            "crossStreet": "at Frankford Rd.",
            "lat": 32.99908456526653,
            "lng": -96.83018780592823,
            "postalCode": "33331",
            "cc": "US",
            "city": "Dallas",
            "state": "TX",
            "country": "United States",
            "formattedAddress": [
                "18349 Dallas Pkwy (at Frankford Rd.)",
                "Dallas, TX 75287",
                "United States"
            ]
        }
}

]

以下代码展示了如何调用 URL 并检索和打印 parse JSON 对象。

NSString *urlString = @"http://somthing.com/Images/collection.json";
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
                                   queue:[NSOperationQueue mainQueue]
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                           if (!error) {
                               NSError* parseError;
                               id parse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&parseError];  
                               NSLog(@"%@", parse);
                           }
                       }];

如何创建餐厅数据模型。或者还有其他方法可以解决这个问题吗?

【问题讨论】:

  • Objective-C 模型是什么意思?你是说普通班吗?还是您想使用 Core Data 来存储它?
  • 抱歉含糊不清,我是说普通班。

标签: ios objective-c json uicollectionview


【解决方案1】:

不需要任何外部库。查看您获得的数据,很明显您想要一个类,每个类代表一个联系人、一个位置、一家餐厅,并且您想要将 JSON 响应转换为一组餐厅。联系人、位置和餐厅应该具有哪些属性是显而易见的。

对于每个类,您根本不需要 init 方法,因此请声明一个带有使其使用非法的标志的 init 方法。对于每个类,声明一个方法initWithJSONDictionary:(NSDictionary*)dict,它将适当的字典作为参数,从字典中提取所有属性,如果值不是您期望的则记录,如果数据错误则返回nil。

使用NSJSONSerialization解析完整的JSON数据,检查它是一个数组并且每个数组元素都是一个字典,并为每个字典调用[[MyRestaurant alloc] initWithJSONDictionary:...]

这绝对是直截了当的,对于像您的案例这样简单的事情,您应该需要一两个小时来为此编写防弹代码。

【讨论】:

    【解决方案2】:

    您可以从这里使用 Json2Model https://github.com/fredlo2010/Json2Model

    它会为你生成 4 个对象: 餐厅.h 餐厅.h 联系人.h 位置.h

    这是 Contact.h 和 Contact.n 的示例

    #import <Foundation/Foundation.h>
    
    @interface Contact : NSObject
    
    @property (strong, nonatomic) NSString *twitter;
    @property (strong, nonatomic) NSString *phone;
    @property (strong, nonatomic) NSString *formattedPhone;
    
    - (instancetype) initWithTwitter: (NSString *)twitter andPhone: (NSString *)phone andFormattedPhone: (NSString *)formattedPhone;
    
    @end
    
    #import "Contact.h"
    
    @implementation Contact
    
    - (instancetype) initWithTwitter: (NSString *)twitter andPhone: (NSString *)phone andFormattedPhone: (NSString *)formattedPhone {
    
        self = [super init];
    
        if (self) {
            self.twitter = twitter;
            self.phone = phone;
            self.formattedPhone = formattedPhone;
        }
        return self;
    }
    
    @end
    

    【讨论】:

    • 我们可以使用复制而不是强属性吗?
    【解决方案3】:

    使用 JSONModel https://github.com/icanzilb/JSONModel

    .h 文件

    #import "JSONModel.h"
    
    
    
    
    @interface location : JSONModel
    {
    
    }
    
    @property (nonatomic,strong) NSString *address;
    @property (nonatomic,strong) NSString *crossStreet;
    @property (nonatomic,strong) NSString *lat;
    @property (nonatomic,strong) NSString *lng;
    @property (nonatomic,strong) NSString *postalCode;
    @property (nonatomic,strong) NSString *cc;
    @property (nonatomic,strong) NSString *city;
    @property (nonatomic,strong) NSString *state;
    @property (nonatomic,strong) NSString *country;
    @property (nonatomic,strong) NSArray *formattedAddress;
    @end
    
    
    
    
    @interface contact:JSONModel
    {
    
    }
    @property (nonatomic,strong) NSString *phone;
    @property (nonatomic,strong) NSString *formattedPhone;
    @property (nonatomic,strong) NSString *twitter;
    @end
    
    @interface Restaurant : JSONModel
    @property (nonatomic,strong) location *objectLocation;
    @property (nonatomic,strong) contact *objContact;
    @property (nonatomic,strong) NSString *name;
    @property (nonatomic,strong) NSString *backgroundImageURL;
    @property (nonatomic,strong) NSString *category;
    

    @结束

    .m 文件

    @implementation Restaurant
    -(id)init{
     self = [super init];
    if (self) {
       _category = @"";
        _name = @"";
        _backgroundImageURL = @"";
    
    
     }
     return self;
    }
    @end
    @implementation contact
    -(id)init{
    self = [super init];
    if (self) {
        _phone = @"";
        _formattedPhone = @"";
        _twitter = @"";
    
    
    }
    return self;
    }
    
    
    
    @end
    @implementation location
    -(id)init{
    self = [super init];
    if (self) {
        _address = @"";
        _crossStreet = @"";
        _lat = @"";
        _lng= @"";
        _postalCode = @"";
        _city = @"";
        _state = @"";
        _cc = @"";
        _country = @"";
    
    
    
    
    
    
     }
    return self;
    }
    
    //objects is the response object
     NSArray* models = [Restaurant arrayOfModelsFromDictionaries: objects];
    

    【讨论】:

    • 我试过上面的代码。 models 结果为空。这里的响应对象是 NSData,我正在使用此代码转换它并使用 parse 代替 objectsid parse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&amp;parseError];NSArray* models = [Restaurant arrayOfModelsFromDictionaries: parse]。附带说明一下,如果我不使用任何自定义数据模型(例如本例中的 Restaurant),我将把 JSON 放到 NSArray 上。但我的任务需要我使用 Restaurant 模型。我将所有这些代码放在 ViewDidLoad 中。
    • 不知何故首先调用了 numberOfItemsInSection,我试图通过 [models count] 分配数字,它总是返回 0。我哪里出错了?跨度>
    【解决方案4】:

    将来自 json 的餐厅数组存储在模型对象中,然后您可以从模型中检索集合视图所需的数据,以便所有解析内容都保留在您的模型中。

    .h 
    @interface Model : NSObject
    
    @property(nonatomic,strong)NSArray *restaurants;
    
    @end
    
    .m
    @implementation Model
    
    -(NSIteger)getRestaurantsCount{
        return restaurants.count;
    }
    
    //getRestaurantAtIndex:
    //getRestaurantNameAtIndex:
    
    @end
    

    【讨论】:

      【解决方案5】:

      查看示例 JSON,您将根据 [ ] 括号获得一组餐馆。您可以使用以下方法检索数组:

       NSArray *restArray= [parse objectForKey:@"restaurants"];
      

      现在您要遍历该数组并解析结构,如下所示:

      for (NSDictionary *restaurant in restArray){
           NSString* name = [restaurant objectForKey:@"name"];
           NSDictionary* location = [restaurant objectForKey:"location"];
          //etc...
      }
      

      【讨论】:

      • 感谢您。我确定不使用自定义模型与此代码一起使用,但我的任务需要我使用自定义模型,正如@poojathorat 回答的那样。但这不起作用,请查看该答案的评论,也许您可​​以更多地了解我想要什么。谢谢
      【解决方案6】:

      您可以将回调中获得的数据解析为 NSDictionary 对象:

      NSData *response = someData; // data you are getting in callback
      NSError *error;
      NSDictionary *json = [NSJSONSerialization JSONObjectWithData:response options:kNilOptions error:&error];
      NSArray *restaurants = [json objectForKey:@"restaurants"];
      

      【讨论】:

        【解决方案7】:

        查看这个 repo,它还带有简单的 coredata 集成 https://github.com/BadChoice/daikiri

        【讨论】:

          猜你喜欢
          • 2014-09-26
          • 1970-01-01
          • 2015-03-13
          • 2021-11-22
          • 2023-03-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多