如何使用 AFNetworking 在另一个 Class 中修改实例 - 创建 API 客户端

How to Modify an Instance in Another Class with AFNetworking - Creating API Client

遇到这个问题,因为我正在尝试开发我的代码。之前,我在 classes 中使用 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];
}

这些方法在 Table 视图 class 中调用。例如,我在 viewload 中调用的 classes 之一:

NSString *URL = @"http://api-dvzalt.azurewebsites.net/api/Currency/Doviz";

[APIClient GetCurrencyInformationFrom:URL to:currencyArray inThe: tableView];

为了调试,我正在打印数据计数和数组计数(都可以在 update:withDictionary:inThe: 方法中找到)和行数(在 table class 中)。开始时行数为零是正常的,因为它是异步的,但是,在我重新加载 tableView 之后,即在完成所有操作后(请参阅 [=27 中的 [tableView reloatData] =] 方法)行数保持为零,其中数据和数组的计数为 20。当然,对于零行,table 上什么也没有显示。所以,基本上我的问题是我给方法的 currencyArray 在它再次返回 tableView 后不会改变,即使它在 APIClient class.

中发生变化

我觉得这是一个简单的错误,但我看不出它在哪里。很高兴你能帮我找到它。

谢谢!

您确定您的 UITableView 设置了正确的数据源吗?

您的 -numberOfSectionsInTableView:-tableView:numberOfRowsInSection: 方法是什么样的?

我不太喜欢回答我的问题。但是在这种情况下,我敢打赌周围有太多新手在寻找我遇到的相同问题。我找不到任何解决方案 4 天。一直在网上搜索并在这里询问,但我在任何地方都找不到我需要的解决方案。也许对你来说不是这样,但如果是第一次,肯定至少需要 1 天的时间。所以,我会尝试让像我这样的初学者深入理解。

首先,创建并拥有一个像 APIClient 这样的 class 通常是个好主意。它只是一个 class ,当你要从互联网上获取数据时,你可以很容易地使用它。然而,对于初学者来说事情变得越来越复杂,因为我们大多习惯于同步执行。

如果您正在尝试修改任何 class 中的任何实例,您要做的就是简单地不要将该实例提供给 APIClient(或 class 像我一样有块),而不是尝试从 APIClient 获取任何需要的信息。就像,如果我们可以实现来自 APIClient 的信息,那么很容易在实例自己的 class 中访问该实例。例如。将 currencyArray 提供给 APIClient,然后尝试更新 APIClient 中的数组是很困难的。另一方面,从 APIClient 获取 responceObject 很容易,这正是来自您拥有的 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: 方法,因为计划将信息带到实例的 class,并在那里进行更新。不在这里。

为了更新目的,让我们调用实例 class 的 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 客户端。

希望以后我可以用这个 post 帮助别人。