Ios AFNetworking 2.0响应对象处理
我有个问题。也许有两个问题 第一个与这段代码有关:Ios AFNetworking 2.0响应对象处理,ios,objective-c,afnetworking,afnetworking-2,Ios,Objective C,Afnetworking,Afnetworking 2,我有个问题。也许有两个问题 第一个与这段代码有关: -(void)isLoggedIn { NSString *urlString = [NSString stringWithFormat:@"%@%@%@", kBaseURL, kAPI, kUserIsLogged]; AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; manager.responseSerializer = [
-(void)isLoggedIn {
NSString *urlString = [NSString stringWithFormat:@"%@%@%@", kBaseURL, kAPI, kUserIsLogged];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
[manager GET:urlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
}
-(void)detail {
NSString *urlString = [NSString stringWithFormat:@"%@%@%@", kBaseURL, kAPI, kUser];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
[manager GET:urlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
}
我希望这个方法不是无效的,我希望它返回BOOL或者我可以使用的东西,比如:用户登录>确定在应用程序的某个地方做些什么;用户未登录>确定提示用户进入屏幕,用户可以在屏幕上介绍其凭据并登录
第二个问题与这段代码有关:
-(void)isLoggedIn {
NSString *urlString = [NSString stringWithFormat:@"%@%@%@", kBaseURL, kAPI, kUserIsLogged];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
[manager GET:urlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
}
-(void)detail {
NSString *urlString = [NSString stringWithFormat:@"%@%@%@", kBaseURL, kAPI, kUser];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
[manager GET:urlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
}
我希望这个方法返回一个带有解析JSON的NSArray,我可以在任何地方使用它
这些方法包含在名为NetworkModel(NSObject子类)的模型中。我只是想知道为什么我应该在街区里做所有的事情。我应该让作品与各地的网络互动,而不是组织在一个独特的地方/班级。有没有办法做到这一点。我不希望每个ViewController都有5行请求。我想定义可以从任何ViewController调用的方法(显然是在需要时导入头文件)
有什么建议吗?
谢谢你的建议 您的方法应该采用一个(或两个)块,该块将从AFNetworking success(或failure)块执行。这种方法包含了您试图做的事情的异步性质。由于这种异步性,无法向方法添加返回值
因此,您可以将方法更改为:
-(void)isLoggedInWithCompletion:(LoginCompletionBlock)completion {
...
[manager GET:urlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
completion(/* whatever parameters your block specifies */);
} ...
}
不久前我问过类似的问题。我相信你会在那里找到解决办法。 一般来说,您需要将您认为获取数据的方式从“if logged In return BOOL”更改为“check if I can logy In,if it fails In,do In the AFNetworking block”
上面的链接也回答了您的第二个问题。您可以通过两种方法来实现这一点,一种是更改方法以使用块或使用信号量来等待异步请求: 使用信号灯(丑陋的方式) 正确的方法
-(void)isLoggedIn:(void(^)(BOOL isLoggedIn))completionBlock {
NSString *urlString = [NSString stringWithFormat:@"%@%@%@", kBaseURL, kAPI, kUserIsLogged];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
[manager GET:urlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
completionBlock(YES);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
completionBlock(NO);
}];
}
对于第二个问题,您可以在网络类上设置一个block变量,当请求完成或失败时将调用该变量
无论如何,我认为你对积木不太熟悉(因为你的第二个问题)我认为在几个块之后,你会开始喜欢它们,你会发现代码并不复杂,如果你有执行请求和解析的小代码片段,你会发现调试它们和发现问题非常容易,我的意思是,这也是我开始使用块时的情况
使用块变量
@interface YourNetworkClass:NSObject {
void(^resultHandlerBlock)(NSArray *results); //this block has as param a NSArray, you can change it to whatever you want
}
-(void)setResultHandlerBlock:(void(^)(NSArray *array))handlerBlock;
@implementation YourNetworkClass
-(void)setResultHandlerBlock:(void(^)(NSArray *array))handlerBlock {
resultHandlerBlock = block;
}
-(void)anotherMethodThatDoesNetworkOperationsAndReturnsAnArray {
....
resultHandlerBlock(arrayOfResults);
}
@interface AViewControllerThatUseNetwork: UIViewController {
}
@implementation AViewControllerThatUseNetwork
-(void)initNetworkClass {
YourNetworkClass *networkClass = [[YourNetworkClass alloc] init]; //or other init methods
[networkClass setResultHandlerBlock:^(NSArray *results) {
//do whatever you want with the array
}];
}
现在,我的代码看起来是这样的(在我的NetworkModel.m中,显然我已经将该方法添加到NetworkModel.h中,以便我可以在任何地方调用它): 在我的AppDelegate.h中,我包含了我的NetworkModel.h,在我的AppDelegate.m中,我现在有以下代码:
[[self model] isLoggedIn:^(BOOL isLoggedIn) {
if (isLoggedIn == YES) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *controller = [storyboard instantiateViewControllerWithIdentifier:@"Start01"];
[self.window setRootViewController:controller];
} else {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *controller = [storyboard instantiateViewControllerWithIdentifier:@"Start00"];
[self.window setRootViewController:controller];
}
}];
但现在我有另一个问题。当我运行应用程序时,出现了一些奇怪的情况。一旦它检索到有关用户登录状态的信息,它就会从VC(我故事板上指定的InitialView控制器-Start00)跳到VC(我故事板上的loggedInVC-Start01)。有没有办法不向用户显示这种跳转?或者这是一种正常行为?现在用户看到第一个屏幕,然后是他应该看到的屏幕(因为他已登录)
但我想处理块最简单的方法就是在我需要的地方使用它们。而不是试图将它们封装到方法或类或其他任何东西中。数据一到,我就会直接在成功或失败块中做我所做的事情。我想对了吗?我意识到了异步性,这就是我为什么要问的原因这是最好的方法,尊重这一事实。你能给我一个我用代码问的例子吗?谢谢你的建议。有趣的建议!谢谢!嗯…我的问题是如果我“检查我是否可以登录”“,我的服务器将根据我是否实际登录,在成功块中回答TRUE或FALSE。我该怎么处理呢?无论用户是否在,它都将是成功的。只有当服务器因某种原因关闭或我查询了无效链接或其他内容时,才会失败。您需要使用用户登录密码发送请求,如果登录成功与否,则需要在成功块内获得响应。例如,发送a@a.com123到服务器,服务器将返回:嘿!我认识那个家伙!你将进入成功区。然后您可以移动到已登录的ViewController。谢谢!这正是我所做的。我发布了我的问题的答案。我会检查一下。关于我对积木的熟悉程度,你完全正确。而且我习惯于在需要数据的时候使用数据,而这种异步的东西现在正困扰着我的头脑……但我会习惯的。首先我需要理解:这就是为什么我问了一个可能是假的问题。所以,关于第二个问题,你建议我做一个块变量,然后,在成功块中,做:blockVariable=responceObject?非常感谢!伟大的非常有用的建议@user1447316很高兴我能帮上忙。有一个“')”丢失了吗?那么它应该是这样的吗+(void)注册表链接:(void(^)(BOOL isLoggedIn))完成块