如何使用 AFNetworking 修改另一个类中的实例 - 创建 API 客户端
Posted
技术标签:
【中文标题】如何使用 AFNetworking 修改另一个类中的实例 - 创建 API 客户端【英文标题】:How to Modify an Instance in Another Class with AFNetworking - Creating API Client 【发布时间】:2015-07-06 22:28:32 【问题描述】:有这个问题,因为我正在尝试开发我的代码。之前,我在类中使用 AFNetworking 方法,但我得到了其中的 4 个。我想要 APIClient,而不是那个重复序列,它有方法。我实现了一些方法,但我的问题只是其中两个。
所以,在 APIClient.m 我有以下内容:
+(void)GetCurrencyInformationFrom:(NSString *)URLString to:(NSArray *) array inThe:(UITableView *) tableView
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; // User informations.
NSString *accessToken = [defaults objectForKey:@"accessToken"];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager.requestSerializer setValue:accessToken forHTTPHeaderField:@"Token"];
NSLog(@"access token: %@", accessToken);
NSLog(@"id: %@", [defaults objectForKey:@"ID"]);
[manager GET:URLString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
[self update:array withDictionary:responseObject inThe:tableView];
failure:^(AFHTTPRequestOperation *operation, NSError *error)
NSLog(@"Error 2: %@", error);
];
+(void)update:(NSArray *)array withDictionary:(NSDictionary *)dictionary inThe:(UITableView *) tableView
NSLog(@"Data Count: %lu", [dictionary[@"Data"] count]);
array = [[NSMutableArray alloc] initWithArray:dictionary[@"Data"]];
NSLog(@"Array Count: %lu", [array count]);
[tableView reloadData];
这些方法在表视图类中调用。例如,我在viewload
中调用的一个类:
NSString *URL = @"http://api-dvzalt.azurewebsites.net/api/Currency/Doviz";
[APIClient GetCurrencyInformationFrom:URL to:currencyArray inThe: tableView];
为了调试,我正在打印数据计数和数组计数(两者都可以在 update:withDictionary:inThe: 方法中找到)和行数(在表类中)。开始时行数为零是正常的,因为它是异步的,但是,在我重新加载我的 tableView 之后,即在一切都完成之后(参见 update:withDictionary:inThe 方法中的 [tableView reloatData])行数保持为零,其中 Data 和 Array 的计数为 20。当然,如果行数为零,则表上没有任何内容。所以,基本上我的问题是我给方法的 currencyArray 在它再次返回 tableView 后并没有改变,即使它在 APIClient 类中发生了变化。
我觉得这是一个简单的错误,但我看不出它在哪里。很高兴你能帮我找到它。
谢谢!
【问题讨论】:
你真的应该遵守可可编码约定 我没有正确使用什么? 可能你没有正确使用苹果的文档。 你能说得更具体些吗? 好吧,无论他反对谁很容易,解释是困难的部分。这个问题问得很好。你可能会告诉我它有什么问题。 【参考方案1】:您是否确保您的UITableView
具有正确的数据源集?
您的-numberOfSectionsInTableView:
和-tableView:numberOfRowsInSection:
方法是什么样的?
【讨论】:
numberOfSectionsInTableView 我做了一个,因为我需要一个。而tableView:numberOfRowsInSection 依赖于currencyArray,我打算通过调用APIClient 的get 方法来改变它 而-tableView:numberOfRowsInSection:
返回 20?
我有这个问题,没有。
array 在更新方法中变成了 20,但不幸的是,当它进入 table 时,它并没有保持 20。我不能把它带到tableView。【参考方案2】:
我真的不喜欢回答我的问题。但是在这种情况下,我敢打赌周围有太多新手,并且正在寻找与我相同的问题。我找不到任何解决方案 4 天。一直在网上搜索并在这里询问,但我没有找到我需要的解决方案。也许对你来说不是这样,但如果是第一次,肯定至少需要 1 天。所以,我会尝试让像我这样的初学者深入了解。
首先,创建并拥有一个像 APIClient 这样的类通常是一个好主意。当您要从 Internet 获取数据时,它只是一个可以轻松使用的类。但是,对于初学者来说,事情变得越来越复杂,因为我们大多习惯于同步执行。
如果您正在尝试修改任何类中的任何实例,那么您所要做的就是不要将该实例提供给像我这样的 APIClient(或具有块的类),而是尝试获取任何需要的信息来自 APIClient。就像,如果我们能实现从APIClient传来的信息,就很容易将那个实例放在实例自己的类中。例如。将currencyArray 提供给APIClient,并尝试更新APIClient 中的数组很困难。另一方面,很容易从 APIClient 获取响应对象,这正是来自您拥有的 URL 的 JSON 数据。
长话短说,通过这种方式,我将 APIClient.m 中的代码更改为:
+(void)GetCurrencyInformationFrom:(NSString *)URLString to:(NSArray *) array inThe:(UITableView *) tableView
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; // User informations.
NSString *accessToken = [defaults objectForKey:@"accessToken"];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager.requestSerializer setValue:accessToken forHTTPHeaderField:@"Token"];
NSLog(@"access token: %@", accessToken);
NSLog(@"id: %@", [defaults objectForKey:@"ID"]);
[manager GET:URLString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
if(success) success(operation, responseObject)
failure:^(AFHTTPRequestOperation *operation, NSError *error)
if(failure) failure(operation, error)
];
请注意,我不再有 update:withDictionary:inThe: 方法,因为计划将信息带到实例的类,并在那里更新。不在这里。
为了更新的目的,让我们调用实例类的viewLoad
。因此,该方法将如下所示:
[APIClient GetCurrencyInformationFrom:URL
success:^(AFHTTPRequestOperation *operation, id responseObject)
[self updateCurrencyArrayWithDictionary:responseObject];
failure:^(AFHTTPRequestOperation *operation, NSError *error)
NSLog(@"Error 2: %@", error);
];
再次出于更新的目的,我在这里也添加了更新方法,而不是 APIClient,这实际上并不是必需的;相反,我们会有块类型实例。
-(void)updateCurrencyArrayWithDictionary:(NSDictionary *)dictionary
currencyArray= [[NSMutableArray alloc] initWithArray:dictionary[@"Data"]];
[tableView reloadData];
请注意,dictionary[@"Data"]];
行可能会根据您的数据而改变。
所以,就是这样。这只是一个简单的示例,说明如何为我们的应用程序的网络目的创建 API 客户端。
希望,我以后可以通过这篇文章帮助某人。
【讨论】:
原始解决方案不起作用的原因是要修改 APIClient 类中 NSArray 的值,您需要通过引用传递它。在你的方法中设置“array”变量只会改变它在该方法中的值,这就是为什么 table view 控制器上的 array 属性没有被更新。块和单一职责绝对是更好的解决方案。以上是关于如何使用 AFNetworking 修改另一个类中的实例 - 创建 API 客户端的主要内容,如果未能解决你的问题,请参考以下文章
AFNetworking 2.0 - 如何从子类 AFHTTPSessionManager 成功将响应传递给另一个类