iOS Attributes in the data model I am working on a product-related app where the data model for a product attribute feels too heavy. But I can't split it into several small data models because they are all about goods. 

At present, my approach is to parse network data directly into a data model. The properties of the data model are readwrite. For example, when I want to modify a property, I will directly modify it, without copying or reinitializing the new data model. 
 I know there may be problems with this, but I don't have a better way, if you have, please help me.


ATProductModel.h


#import "ATBaseModel.h"

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSUInteger, ATFilterType) {
    ATFilterTypeComplex = 0,
    ATFilterTypeSales,
    ATFilterTypePrice,
    ATFilterTypeVoucher,
};

typedef NS_ENUM(NSUInteger, ATFilterLayoutType) {
    ATFilterLayoutTypeNone = 0,
    ATFilterLayoutTypeOneRows, 
    ATFilterLayoutTypeMoreRows, 
};

@interface ATProductSubModel : ATBaseModel

@property (copy, nonatomic) NSString *productId;
@property (copy, nonatomic) NSString *productURL;
@property (copy, nonatomic) NSString *productURLShort;
@property (copy, nonatomic) NSString *productIcon;
@property (copy, nonatomic) NSString *title;
@property (copy, nonatomic) NSString *voucher;
@property (copy, nonatomic) NSString *currentPrice;
@property (copy, nonatomic) NSString *price;
@property (copy, nonatomic) NSString *couponURL;
@property (copy, nonatomic) NSString *discountRate;
@property (copy, nonatomic) NSString *endTime;
@property (copy, nonatomic) NSString *couponInfo;
@property (copy, nonatomic) NSString *volume;
@property (copy, nonatomic) NSString *couponStartTime;
@property (copy, nonatomic) NSString *couponEndTime;
@property (copy, nonatomic) NSArray &lt;NSString *&gt;* smallImages;
@property (copy, nonatomic) NSString *shopName;
@property (copy, nonatomic) NSString *shopLogo;
@property (copy, nonatomic) NSString *platType;
@property (copy, nonatomic) NSString *shopScore;
@property (copy, nonatomic) NSString *share;
@property (copy, nonatomic) NSString *shareFee;
@property (copy, nonatomic) NSString *income;
@property (copy, nonatomic) NSString *upIncome;
@property (strong, nonatomic) NSNumber *finished;

+ (instancetype)defaultModel;

@end

@interface ATProductModel : ATBaseModel

@property (strong, nonatomic) NSArray &lt;ATProductSubModel *&gt;* products;
@property (assign, nonatomic) ATFilterLayoutType layoutType;
@property (assign, nonatomic) BOOL recommended;

@end

NS_ASSUME_NONNULL_END




ATProductViewController.h


#import "ATProductModel.h"

NS_ASSUME_NONNULL_BEGIN

@interface ATProductViewController : UIViewController

@property (strong, nonatomic) ATProductSubModel *model;

@end




ATProductViewController.m


#import "ATStringUtil.h"

@implementation ATProductViewController

@property (strong, nonatomic) ATProductModel *productModel;

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self defaultModels];
}

- (void)defaultModels{

    NSMutableArray *smallImages = [NSMutableArray arrayWithArray:self.model.smallImages];
    if (![ATStringUtil containStr:self.model.icon inArr:self.model.smallImages]) {
        [smallImages insertObject:self.model.icon atIndex:0];
    }
    self.model.smallImages = smallImages;
}

@end
```
In terms of number of properties, I wouldn’t worry about that. There are situations where you can have lots of properties. As the philosopher says, “it is what it is.”

Obviously, from a data modeling perspective, what doesn’t feel quite right is to combine product info, coupon info, shop info, etc. into a single object. E.g. products sometimes are eligible for multiple coupons. Or perhaps you’ll be repeating the “shop” information multiple times in your result set.

That having been said, it depends upon what this feed is for: If this is a search result employed within a particular view within the app, then perhaps a fairly flat structure, like yours, is fine (though I might call the object a “search result” rather than a “product”). But if this is for populating a local data store that users can search locally, then I might expect separate objects for the different entity types (a product object, a shop object, etc.). I’d ask myself how often can the same information be repeated in a particular result set. But whether you have a denormalized/flat result set, or a more normalized product database, just depends upon the nature of the API and how this is being used within the app.

The only change that really jumps out at me is that there are several properties that would appear to be numeric types that are captured as strings (e.g. prices, rates, fees, income, etc.). Perhaps your feed returns them as strings, but within your app, you don’t want to have to sprinkle your code with string-to-number conversions so that you can do things like show the user grand totals, convert rates to totals, or the like. I might be inclined to do that string-to-number conversion while parsing the feed (or, better, change the feed to actually return numeric types) and then I’m working purely with numeric types within the app.