我有办法使用两个单独的Web API填充一个UITableView
吗?我确定有,但我无法弄明白。
目前,我正在从一个Web API中完美地完成任务;但是我需要从另一个中提取,然后将它们合并为一个UITableView
。
(我正在使用RestKit)
(我试图整合的第二个API是Instagram,并将从用户帐户中提取图片/文字)
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// RestKit
NSString *baseURL = @"http://api.firstwebsite.com/v1";
RKObjectManager *manager = [RKObjectManager sharedManager];
if (!manager) {
manager = [RKObjectManager objectManagerWithBaseURLString:baseURL];
manager.client.serviceUnavailableAlertEnabled = YES;
manager.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;
} else {
manager.client.baseURL = [RKURL URLWithString:baseURL];
}
return YES;
}
WebListViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:
[NSString stringWithFormat:
@"/something/?limit=100&something=%@&something=%@&apikey=xxxx", var1, var2]
usingBlock:^(RKObjectLoader *loader) {
loader.onDidLoadObjects = ^(NSArray *objects){
hArray = objects;
[_tableView reloadData];
};
[loader.mappingProvider setMapping:[Fe mapping] forKeyPath:@"fe"];
loader.onDidLoadResponse = ^(RKResponse *response){
//NSLog(@"BodyAsString: %@", [response bodyAsString]);
};
}];
}
我假设我需要在AppDelegate.m
中使用baseURL
执行不同的操作,因为它会有两个不同的基本网址。
谢谢!将根据需要发布任何额外的代码!
修改
根据alexandresoli的回答,这是我到目前为止所做的更新,但仍然需要帮助:
WebListViewController.m
@property (strong, nonatomic) NSMutableArray *array;
@synthesize array;
- (void)callBothURLs {
// Call both #1 and #2 URL, not sure what specific code goes here
}
- (void)viewDidLoad {
[self callBothURLs];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// This is what I currently have, was pulling from a `Headlines` `NSArray` from web #1
return headlinesArray.count;
// I believe I need to change it to this next line...
//return array.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Not sure what to put here with the new `NSMutableArray`
}
编辑2
我已经为第一个网站设置了我的对象映射,所以我可以很容易地为Instagram API做这个部分。我所有的困惑/问题似乎都在WebListViewController中。无论如何这里是一个映射样本。
Mapping.h
@interface Mapping : NSObject
@property (nonatomic, strong) Links *links;
@property (nonatomic, strong) NSString *headline;
@property (nonatomic, strong) NSArray *images;
+ (RKObjectMapping *) mapping;
@end
Mapping.m
@implementation Mapping
+ (RKObjectMapping *)mapping {
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:[self class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapKeyPathsToAttributes:
@"headline", @"headline",
nil];
[mapping hasMany:@"images" withMapping:[Images mapping]];
}];
return objectMapping;
}
@end
答案 0 :(得分:1)
创建一个方法,该方法使用addObject方法调用两个url并将每个url的结果存储在同一个NSMutableArray中。
NSMutableArray *array = [NSMutableArray new];
// for each object from URL 1, call [array addObject:object];
// for each object from URL 2, call [array addObject:object];
使用此数组作为tableview的数据源;
按要求更新:
更新2:
- (void)viewDidLoad
{
[super viewDidLoad];
_array = [NSMutableArray new];
// fetch data from url 1
NSArray *arrayUrl1 = [self fetchUrl1];
// add url1 data to array
for (NSString *str in arrayUrl1) {
[_array addObject:str];
}
// fetch data from url 2
NSArray *arrayUrl2 = [self fetchUrl2];
// add url2 data to array
for (NSString *str in arrayUrl2) {
[_array addObject:str];
}
}
- (NSArray *)fetchUrl1
{
return [NSArray array];
}
- (NSArray *)fetchUrl2
{
return [NSArray array];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// total number of objects in array
return [_array count];
}
答案 1 :(得分:1)
几乎是A到Z的解释。
<强>假设强>
基本理念
使用NSMutableArray
存储结果项。同时启动两个API请求,并在适当的成功块中将结果项添加到数组中。两个API调用完成后,排序数组和重新加载表。
执行API调用
在视图控制器中执行API调用(可能在viewDidLoad
中),而不是在AppDelegate
中。可以在github page找到RestKit对象请求的基本示例。我们将API调用命名为callAPI1
,callAPI2
。例如,[self callAPI1]
有以下步骤:
尝试将单个类用于结果对象(您需要为每个API使用不同的映射)以简化排序。 [见下文]
回复API调用
现在我们需要知道两个请求何时完成,以便重新加载表。使用一个简单的计数器,该计数器最初设置为每次API调用完成时的请求数和减量数。
您的方法实现可能如下所示:
@implementation ViewController
{
NSMutableArray *_items;
NSInteger _numberOfPendingCalls;
}
- (void)loadItems
{
_numberOfPendingCalls = 2;
[_items removeAllObjects];
[self callAPI1];
[self callAPI2];
}
在成功阻止中,我们减少待处理的呼叫,添加项目并检查完成情况:
^(RKObjectRequestOperation *operation, RKMappingResult *result) {
_numberOfPendingCalls--;
[_items addObjectsFromArray:result.array];
if (_numberOfPendingCalls == 0) {
[self sortAndDisplayItems];
}
}
如果可变数组包含单个类的实例(或者至少项具有相同的属性),则可以使用NSSortDescriptor
进行排序:
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
[_items sortUsingDescriptors:@[sortDescriptor]];
其中name
是结果对象的属性。
我省略了表视图委托实现,因为它很简单。
进一步的步骤
如果要使用RestKit对象管理器,并且您的API具有不同的基本URL,则需要使用多个对象管理器,每个API一个。参考:More than one RKObjectManager at a time (RestKit)