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))完成块