Ios 来自两个API的一个表视图';s
我有没有办法用两个独立的web API填充一个Ios 来自两个API的一个表视图';s,ios,objective-c,api,uitableview,Ios,Objective C,Api,Uitableview,我有没有办法用两个独立的web API填充一个UITableView?我肯定有,但我不太明白 目前,我完全从一个web API中提取;但我需要从另一个视图中提取,然后将它们合并到一个UITableView (我正在使用RestKit) (我尝试集成的第二个API是Instagram,它将从用户帐户中提取图片/文本) AppDelegate.m - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOption
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]);
};
}];
}
@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`
}
我假设我需要在AppDelegate.m
中对baseURL
执行一些不同的操作,因为它将有两个不同的基本url
谢谢!将根据需要发布任何额外的代码
编辑
根据alexandresoli的回答,以下是我迄今为止更新的内容,但仍然需要以下方面的帮助:
- (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];
}
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]);
};
}];
}
@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中。无论如何,这里有一个映射示例
映射.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
创建一个调用两个url的方法,并使用addObject方法将每个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的数据源
按要求更新:
- 您可以从viewDidLoad调用populateBothUrlsMethod
- 在此之后,将普通uitableview数据源方法NumberOfSectionsTableView和numberOfRowsInSection用于此新填充的数组
- (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];
}
几乎是完全正确的解释 假设
- 两种API的响应相似
- 最后的结果应该进行排序
- 在两个API调用完成加载之前,不应显示项
NSMutableArray
存储结果项。同时启动两个API请求,并将结果项添加到相应成功块中的数组中。两个API调用完成后,对数组排序并重新加载表
执行API调用
在视图控制器中执行API调用(可能在viewDidLoad
中),而不是在AppDelegate
中。RestKit对象请求的基本示例可以在中找到。让我们命名我们的API调用callAPI1
,callAPI2
。例如,[self callAPI1]
有以下步骤:
- 定义从API1到结果对象的映射
- 定义响应描述符
- 创建API请求并指定基本URL
- 创建请求操作并实现完成块
- 启动操作
@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一个。参考资料:您可以在WebListViewController中执行两次加载,无需在AppDelegate中执行。啊,在
ViewController
中执行加载是否比在AppDelgate
中执行加载更好?只是想知道。谢谢两个web服务是否返回相同类型的数据?结果是否应该依次排序或显示(第一个web结果,然后是第二个web结果)?@vokilam它们都是JSON,结果将被排序(第一个web结果和第二个web结果按日期排序)。基本上,每个表视图单元格中都有一个图像和一个文本标签。这有用吗?谢谢那么创建-(void)callBothURLs
,我会把你发布的代码放在里面?从这里开始,我将如何使用该数组作为数据源,是否将其放入viewDidLoad
?对不起,我相信你说的都是对的,我只是从来没有做过,我只是想把我的头绕过去。谢谢我编辑了我的答案,以显示到目前为止我所理解的内容,但仍然不能完全确定将NSMutableArray
放在哪里。感谢您继续提供帮助!另外,由于我不再只使用一个API
,我是否需要在AppDelegate
中删除baseURL
的代码?谢谢!你太棒了,谢谢你的帮助。我将尝试找出如何实现这一点。同时,我给了你50美元的悬赏!处理这个问题时,我是否需要扔掉我所有的viewDidLoad
代码并用它替换,或者哪些部分可用或不可用?想知道你建议我更换哪些零件,哪些零件还可以。谢谢非常感谢您的回复!假设:所有都是正确的。基本想法:我相信我在这里跟随你,并将其作为数组保存在我的“编辑”中。执行API调用:我想我正在关注您。在我的WebListVC
中,我正在打电话,但只是使用AppDelegate
中列出的baseURL
并附加到它。你建议我怎么做。。。从AppDelegate
中删除代码,然后将完整URL添加到WebListVC
我已有的代码?还有其他变化吗