I'm using RestKit and was wondering how to combine two array's into one array.
I already have the data being pulled in separately from API1 and API2, but I don't know how to combine them into 1 tableView.
Each API is pulling in media, and I want the combined tableView to show the most recent media (like any standard timeline does these days).
I will post any extra code or help as necessary, thanks so much!
Below shows API1 + API2 being pulled in correctly, but not combined into the tableView. Only data from API1 shows in the tableView.
ViewController.m
@interface StackOverflowViewController ()
@property (strong, nonatomic) NSArray *hArray;
@property (strong, nonatomic) NSArray *springs;
@property (strong, nonatomic) RKObjectManager *eObjectManager;
@property (strong, nonatomic) NSArray *iArray;
@property (strong, nonatomic) NSArray *imagesArray;
@property (strong, nonatomic) RKObjectManager *iObjectManager;
// Wain
@property (strong, nonatomic) NSMutableArray *tableDataList;
// Laarme
@property (nonatomic, strong) NSMutableArray *contentArray;
@property (nonatomic, strong) NSDateFormatter *dateFormatter1;
// Dan
@property (nonatomic, strong) NSMutableArray *combinedModel;
@end
@implementation StackOverflowViewController
@synthesize tableView = _tableView;
@synthesize spring;
@synthesize leaf;
@synthesize theme;
@synthesize hArray;
@synthesize springs;
@synthesize eObjectManager;
@synthesize iArray;
@synthesize imagesArray;
@synthesize iObjectManager;
// Wain
@synthesize tableDataList;
// Laarme
@synthesize contentArray;
@synthesize dateFormatter1;
// Dan
@synthesize combinedModel;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self configureRestKit];
[self loadMediaDan];
[self sortCombinedModel];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)configureRestKit {
// API1
// initialize AFNetworking HTTPClient
NSURL *baseURLE = [NSURL URLWithString:@"https://api.e.com"];
AFHTTPClient *clientE = [[AFHTTPClient alloc] initWithBaseURL:baseURLE];
// initialize RestKit
RKObjectManager *eManager = [[RKObjectManager alloc] initWithHTTPClient:clientE];
self.eObjectManager = eManager;
// setup object mappings
RKObjectMapping *feedMapping = [RKObjectMapping mappingForClass:[Feed class]];
[feedMapping addAttributeMappingsFromArray:@[@"headline", @"premium", @"published", @"description"]];
RKObjectMapping *linksMapping = [RKObjectMapping mappingForClass:[Links class]];
RKObjectMapping *webMapping = [RKObjectMapping mappingForClass:[Web class]];
[webMapping addAttributeMappingsFromArray:@[@"href"]];
RKObjectMapping *mobileMapping = [RKObjectMapping mappingForClass:[Mobile class]];
[mobileMapping addAttributeMappingsFromArray:@[@"href"]];
RKObjectMapping *imagesMapping = [RKObjectMapping mappingForClass:[Images class]];
[imagesMapping addAttributeMappingsFromArray:@[@"height", @"width", @"url"]];
[feedMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"links" toKeyPath:@"links" withMapping:linksMapping]];
[feedMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"images" toKeyPath:@"images" withMapping:imagesMapping]];
[linksMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"web" toKeyPath:@"web" withMapping:webMapping]];
[linksMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"mobile" toKeyPath:@"mobile" withMapping:mobileMapping]];
// register mappings with the provider using a response descriptor
RKResponseDescriptor *responseDescriptor =
[RKResponseDescriptor responseDescriptorWithMapping:feedMapping
method:RKRequestMethodGET
pathPattern:nil
keyPath:@"feed"
statusCodes:[NSIndexSet indexSetWithIndex:200]];
[self.eObjectManager addResponseDescriptor:responseDescriptor];
// API2
// initialize AFNetworking HTTPClient
NSURL *baseURLI = [NSURL URLWithString:@"https://api.i.com"];
AFHTTPClient *clientI = [[AFHTTPClient alloc] initWithBaseURL:baseURLI];
// initialize RestKit
RKObjectManager *iManager = [[RKObjectManager alloc] initWithHTTPClient:clientI];
self.iObjectManager = iManager;
// setup object mappings
RKObjectMapping *dataMapping = [RKObjectMapping mappingForClass:[Data class]];
[dataMapping addAttributeMappingsFromArray:@[@"link", @"created_time"]];
RKObjectMapping *imagesMapping = [RKObjectMapping mappingForClass:[ImagesI class]];
[IMapping addAttributeMappingsFromArray:@[@""]];
RKObjectMapping *standardResolutionMapping = [RKObjectMapping mappingForClass:[StandardResolution class]];
[standardResolutionMapping addAttributeMappingsFromArray:@[@"url", @"width", @"height"]];
RKObjectMapping *captionMapping = [RKObjectMapping mappingForClass:[Caption class]];
[captionMapping addAttributeMappingsFromArray:@[@"text", @"created_time"]];
RKObjectMapping *userMapping = [RKObjectMapping mappingForClass:[User class]];
[userMapping addAttributeMappingsFromArray:@[@"username"]];
[dataMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"images" toKeyPath:@"images" withMapping:imagesMapping]];
[imagesMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"standard_resolution" toKeyPath:@"standard_resolution" withMapping:standardResolutionMapping]];
[dataMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"caption" toKeyPath:@"caption" withMapping:captionMapping]];
[dataMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"user" toKeyPath:@"user" withMapping:userMapping]];
// register mappings with the provider using a response descriptor
RKResponseDescriptor *responseDescriptor2 =
[RKResponseDescriptor responseDescriptorWithMapping:dataMapping
method:RKRequestMethodGET
pathPattern:nil
keyPath:@"data"
statusCodes:[NSIndexSet indexSetWithIndex:200]];
[self.iObjectManager addResponseDescriptor:responseDescriptor2];
}
- (void)loadMedia {
// Laarme
contentArray = [[NSMutableArray alloc] init];
[self sortByDates];
// API1
NSString *apikey = @kCLIENTKEY;
NSDictionary *queryParams = @{@"apikey" : apikey,};
[self.eObjectManager getObjectsAtPath:[NSString stringWithFormat:@"v1/n/?limit=4&leafs=%@&themes=%@", leafAbbreviation, themeID] // Changed limit to 4 for the time being
parameters:queryParams
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
hArray = mappingResult.array;
[self.tableView reloadData];
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"No?: %@", error);
}];
// API2
[self.iObjectManager getObjectsAtPath:[NSString stringWithFormat:@"v1/u/2/m/recent/?client_id=e999"]
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
iArray = mappingResult.array;
[self.tableView reloadData];
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"No: %@", error);
}];
}
// Laarme
- (void)sortByDates {
NSDateFormatter *dateFormatter2 = [[NSDateFormatter alloc] init];
//Do the dateFormatter settings, you may have to use 2 NSDateFormatters if the format is different for Data & Feed
//The initialization of the dateFormatter is done before the block, because its alloc/init take some time, and you may have to declare it with "__block"
//Since in your edit you do that and it seems it's the same format, just do @property (nonatomic, strong) NSDateFormatter dateFormatter;
NSArray *sortedArray = [contentArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b)
{
// Added Curly Braces around if else statements and used feedObject
NSDate *aDate, *bDate;
Feed *feedObject = (Feed *)a;
Data *dataObject = (Data *)b;
if ([a isKindOfClass:[Feed class]]) {
//Feed *feedObject = (Feed *)a;
aDate = [dateFormatter1 dateFromString:feedObject.published];}
else { //if ([a isKindOfClass:[Data class]])
aDate = [dateFormatter2 dateFromString:dataObject.created_time];}
if ([b isKindOfClass:[Feed class]]) {
bDate = [dateFormatter1 dateFromString:feedObject.published];}
else {//if ([b isKindOfClass:[Data class]])
bDate = [dateFormatter2 dateFromString:dataObject.created_time];}
return [aDate compare:bDate];
}];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// API1
//return hArray.count;
// API2
//return iArray.count;
// API1 + API2
return hArray.count + iArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
if(indexPath.row < hArray.count) {
// Date Change
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"MMMM d, yyyy h:mma"];
// API 1
TableViewCell *api1Cell = [tableView dequeueReusableCellWithIdentifier:@"YourAPI1Cell"];
// Do everything you need to do with the api1Cell
// Use the index in 'indexPath.row' to get the object from you array
// API1
Feed *feedLocal = [hArray objectAtIndex:indexPath.row];
// API1
NSString *dateString = [self timeSincePublished:feedLocal.published];
NSString *headlineText = [NSString stringWithFormat:@"%@", feedLocal.headline];
NSString *descriptionText = [NSString stringWithFormat:@"%@", feedLocal.description];
NSString *premiumText = [NSString stringWithFormat:@"%@", feedLocal.premium];
api1Cell.labelHeadline.text = [NSString stringWithFormat:@"%@", headlineText];
api1Cell.labelPublished.text = dateString;
api1Cell.labelDescription.text = descriptionText;
// SDWebImage API1
if ([feedLocal.images count] == 0) {
// Not sure anything needed here
}
else {
Images *imageLocal = [feedLocal.images objectAtIndex:0];
NSString *imageURL = [NSString stringWithFormat:@"%@", imageLocal.url];
NSString *imageWith = [NSString stringWithFormat:@"%@", imageLocal.width];
NSString *imageHeight = [NSString stringWithFormat:@"%@", imageLocal.height];
__weak UITableViewCell *wcell = cell;
[cell.imageView setImageWithURL:[NSURL URLWithString:imageURL]
placeholderImage:[UIImage imageNamed:@"X"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType)
{
// Something
}];
}
cell = api1Cell;
} else {
// Date Change
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"MMMM d, yyyy h:mma"];
// API 2
MRWebListTableViewCellTwo *api2Cell = [tableView dequeueReusableCellWithIdentifier:@"YourAPI2Cell"];
// Do everything you need to do with the api2Cell
// Remember to use 'indexPath.row - hArray.count' as the index for getting an object for your second array
// API 2
Data *dataLocal = [iArray objectAtIndex:indexPath.row - hArray.count];
// API 2
NSString *dateStringI = [self timeSincePublished:dataLocal.created_time];
NSString *captionTextI = [NSString stringWithFormat:@"%@", dataLocal.caption.text];
NSString *usernameI = [NSString stringWithFormat:@"%@", dataLocal.user.username];
api2Cell.labelHeadline.text = usernameI;
api2Cell.labelDescription.text = captionTextI;
api2Cell.labelPublished.text = dateStringI;
// SDWebImage API 2
if ([dataLocal.images count] == 0) {
NSLog(@"Images Count: %lu", (unsigned long)dataLocal.images.count);
// Not sure anything needed here
}
else {
ImagesI *imageLocalI = [dataLocal.images objectAtIndex:0];
StandardResolutionI *standardResolutionLocal = [imageLocalI.standard_resolution objectAtIndex:0];
NSString *imageURLI = [NSString stringWithFormat:@"%@", standardResolutionLocal.url];
NSString *imageWithI = [NSString stringWithFormat:@"%@", standardResolutionLocal.width];
NSString *imageHeightI = [NSString stringWithFormat:@"%@", standardResolutionLocal.height];
// 11.2
__weak UITableViewCell *wcell = cell;
[cell.imageView setImageWithURL:[NSURL URLWithString:imageURLI]
placeholderImage:[UIImage imageNamed:@"X"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType)
{
// Something
}];
}
cell = api2Cell;
}
return cell;
}
Feed.h
@property (nonatomic, strong) Links *links;
@property (nonatomic, strong) NSString *headline;
@property (nonatomic, strong) NSString *source;
@property (nonatomic, strong) NSDate *published;
@property (nonatomic, strong) NSString *description;
@property (nonatomic, strong) NSString *premium;
@property (nonatomic, strong) NSArray *images;
Data.h
@property (nonatomic, strong) NSString *link;
@property (nonatomic, strong) NSDate *created_time;
@property (nonatomic, strong) UserI *user;
@property (nonatomic, strong) NSArray *images;
@property (nonatomic, strong) CaptionI *caption;