Get one NSArray

后端 未结 4 1416
夕颜
夕颜 2021-01-24 00:48

I was wondering how to combine two array\'s into one array.

I want the combined tableView to show the most recent

4条回答
  •  独厮守ぢ
    2021-01-24 01:19

    The cause of the complexity in this question is that the data is coming from two different sources asynchronously. Get our arms around that and we've got the problem under control. My suggestion differs from the others in that it aims to take care of the multiple asynch sources right away, leaving simpler code in all the other areas.

    The way to handle two asynch sources is to serialize them with a nested completion. Here, I just took your posted code and factored it into two methods, one for each api. Each takes a success and failure block matching the object manager's interface...

    - (void)loadOneWithSuccess:(void (^)(RKObjectRequestOperation *operation, RKMappingResult *mappingResult))success
                       failure:(void (^)(RKObjectRequestOperation *operation, NSError *error))failure {
    
        NSString *apikey = @kCLIENTKEY;
        NSDictionary *queryParams = @{@"apikey" : apikey};
        NSString *path = [NSString stringWithFormat:@"v1/n/?limit=4&leafs=%@&themes=%@", leafAbbreviation, themeID];
    
        [self.eObjectManager getObjectsAtPath:path parameters:queryParams success:success failure:failure];
    }
    
    - (void)loadTwoWithSuccess:(void (^)(RKObjectRequestOperation *operation, RKMappingResult *mappingResult))success
                       failure:(void (^)(RKObjectRequestOperation *operation, NSError *error))failure {
    
        NSString *path = @"v1/u/2/m/recent/?client_id=e999";
        [self.iObjectManager getObjectsAtPath:path parameters:nil success:success failure:failure];
    }
    

    Now we can make loadMedia do what we need, which is to load from each api, combine and sort as a single model. Declare an NSMutableArray property called combinedModel. Other answers have suggested this as tableDataList or contentArray. The key difference in my suggestion is to take care of the combination as part of a combined fetch.

    - (void)loadMedia {
    
        self.combinedModel = [NSMutableArray array];
    
        [self loadOneWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
    
            [self.combinedModel addObjectsFromArray:mappingResult];
    
            // here's the trick.  call API2 here.  Doing so will serialize these two requests
            [self loadTwoWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
    
                [self.combinedModel addObjectsFromArray:mappingResult];
                [self sortCombinedModel];
                [self.tableView reloadData];
    
            } failure:^(RKObjectRequestOperation *operation, NSError *error) {
                NSLog(@"No?: %@", error);
            }];
    
        } failure:^(RKObjectRequestOperation *operation, NSError *error) {
            NSLog(@"No?: %@", error);
        }];
    }
    

    Now only two problems remain (1) sorting an array of heterogenous objects, (2) rendering heterogenous objects in a table view. First sort:

    - (void)sortCombinedModel {
        [self.combinedModel sortUsingComparator:^NSComparisonResult(id a, id b) {
            NSDate *dateA, *dateB;
            dateA = ([a isKindOfClass:[Feed self]])? ((Feed *)a).published : ((Data *)a).created_time;
            dateB = ([b isKindOfClass:[Feed self]])? ((Feed *)b).published : ((Data *)b).created_time;
            return [dateA compare:dateB];
        }];
    }
    

    Now for the table, self.combinedModel is the new model for the table view. All the datasource methods should refer to it. cellForRowAtIndexPath: should behave just like the sort:. In a nutshell...

    id model = self.combinedModel[indexPath.row];
    if ([model isKindOfClass:[Feed self]) {
        Feed *feed = (Feed *)model;
        // configure cell with feed
    } else {
        Data *data = (Data *)model;
        // configure cell with data
    }
    

提交回复
热议问题