I have seen many codes where set ViewModel as a table view data source, and many which don't.
1.Setting data source to the ViewModel some time makes sense as the data source methods mainly deal with the presentation logic.
2.On the other hand setting the ViewModel as the data source implies that you are implementing cellForRowAtIndexPath
etc which makes it not independent of UIKit
.
What is the best way to architecture your apps, Kindly clarify?
The answer would be, there is no best way to architecture an app. There are many good ways to organize your classes according to your needs. Here is an example of how I organize my viewModel in order to show data in the table view:
PaymentSectionItem is my ViewModel
PaymentSectionItem.h
@interface PaymentSectionItem : NSObject
@property (assign, nonatomic) NSUInteger itemID;
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSArray *elements;
@property (assign, nonatomic) kTransactionType transactionType;
+ (NSArray<PaymentSectionItem *> *)allSectionItemsWithData;
@end
PaymentSectionItem.m
@implementation PaymentSectionItem
#pragma mark - Custom Accessors
- (NSString *)localizedTitle {
NSString *title = [NSString stringWithFormat:@"%@_section_title", self.name];
return NSLocalizedString(title, @"Section title");
}
- (NSString *)localizedDescription {
NSString *title = [NSString stringWithFormat:@"%@_section_description", self.name];
return NSLocalizedString(title, @"Section description");
}
#pragma mark - Constructor
- (instancetype)initWithSectionItem:(kSectionItem)sectionItem {
self = [super init];
if (self) {
[self setupFromHomeSectionItem:sectionItem];
}
return self;
}
#pragma mark - Private
- (void)setupFromHomeSectionItem:(kSectionItem)sectionItem {
self.itemID = sectionItem;
switch (sectionItem) {
case kSectionItem1: {
self.name = @"phones";
self.elements = [Payment findPaymentsType1];
break;
}
case kSectionItem2: {
self.name = @"autopay";
self.elements = [Payment findPaymentsType2];
break;
}
case kSectionItem3: {
self.name = @"trustfund";
self.elements = [Payment findPaymentsType3];
self.transactionType = kTransactionTypeTrustFund;
break;
}
case kSectionItem4: {
self.name = @"debitlink";
self.elements = [Payment findPaymentsType4];
self.transactionType = kTransactionTypeDebitLink;
break;
}
case kSectionItem5: {
self.name = @"pindebit";
self.elements = [Payment findPaymentsType5];
self.transactionType = kTransactionTypePINDebit;
break;
}
}
}
#pragma mark - Public
+ (NSArray<PaymentSectionItem *> *)allSectionItemsWithData {
NSMutableArray *items = [NSMutableArray new];
[items addObject:[[PaymentSectionItem alloc] initWithSectionItem:kSectionItem1]];
[items addObject:[[PaymentSectionItem alloc] initWithSectionItem:kSectionItem2]];
[items addObject:[[PaymentSectionItem alloc] initWithSectionItem:kSectionItem3]];
[items addObject:[[PaymentSectionItem alloc] initWithSectionItem:kSectionItem4]];
[items addObject:[[PaymentSectionItem alloc] initWithSectionItem:kSectionItem5]];
return items;
}
ViewController.h
- (void)viewDidLoad {
[super viewDidLoad];
self.items = [PaymentSectionItem allSectionItemsWithData];
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.items.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.items[section].elements.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
GTLAutoPaySectionItem *sectionItem = self.items[indexPath.section];
NSString *identifier = [self identifierForSectionItem:sectionItem atIndex:indexPath];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
UITableViewCell<PaymentCellProtocol> *paymentCell = (UITableViewCell<PaymentCellProtocol> *)cell;
[paymentCell setupCellFromValue:sectionItem.elements[indexPath.row] withSectionItem:sectionItem];
return cell;
}
As you see, in my case I have a table view with many sections and each section has elements. That's exactly what I do in my ViewModel. Feel free to ask if you have any other question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With