【问题标题】:AFNetworking POST to REST webserviceAFNetworking POST 到 REST 网络服务
【发布时间】:2012-03-29 14:54:57
【问题描述】:

简短的背景故事,我们以前的开发人员使用 ASIHTTPRequest 发出 POST 请求并从我们的网络服务中检索数据。由于未知的原因,我们应用程序的这一部分停止工作。似乎有足够的时间来证明未来并与 AFNetworking 合作。 REST Web 服务在 CakePHP 框架上运行。

简而言之,我没有收到使用 AFNetworking 的请求响应字符串。

我知道 web 服务可以正常工作,因为我能够使用 curl 成功发布数据并接收正确的响应: curl -d "data[Model][field0]=field0value&data[Model][field1]=field1value" https://example.com/api/class/function.plist

根据之前开发人员的说明,我想出了以下内容。

#import "AFHTTPRequestOperation.h"    

…

- (IBAction)loginButtonPressed {

    NSURL *url = [NSURL URLWithString:@"https://example.com/api/class/function.plist"];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    [request setHTTPMethod:@"POST"];

    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

    [request setValue:[usernameTextField text] forHTTPHeaderField:@"data[User][email]"];

    [request setValue:[passwordTextField text] forHTTPHeaderField:@"data[User][password]"];

    AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {  

        NSLog(@"operation hasAcceptableStatusCode: %d", [operation.response statusCode]);

        NSLog(@"response string: %@ ", operation.responseString);

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        NSLog(@"error: %@", operation.responseString);

    }];

    [operation start];

}

输出: 操作 hasAcceptableStatusCode: 200 响应字符串:一个空白的 plist 文件

尝试的解决方案 1: AFNetworking Post Request 建议的解决方案使用了一个名为 operationWithRequest 的 AFHTTPRequestOperation 函数。但是,当我尝试使用上述解决方案时,我收到警告“类方法 '+operationWithRequest:completion:' not found (return type defaults to 'id'”

尝试的解决方案 2:NSURLConnection。输出:我可以打印成功日志消息,但不能打印响应字符串。 *update - 返回空白 plist。

NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSString *httpBodyData = @"data[User][email]=username@example.com&data[User][password]=awesomepassword";
[httpBodyData dataUsingEncoding:NSUTF8StringEncoding];
[req setHTTPMethod:@"POST"];
[req setHTTPBody:[NSData dataWithContentsOfFile:httpBodyData]];
NSHTTPURLResponse __autoreleasing *response;
NSError __autoreleasing *error;
[NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];

// *update - returns blank plist
NSData *responseData = [NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil];
NSString *str = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(@"responseData %@",str);

if (error == nil && response.statusCode == 200) {
    // Process response
    NSLog(@"success");//returns success code of 200 but blank
    NSLog(@"resp %@", response );
} else {
    // Process error
    NSLog(@"error");
}

【问题讨论】:

  • 您好,Pouria,您是否尝试过使用 NSURLConnection 发送同步请求?
  • 尝试的解决方案 2:我是如何尝试 NSURLConnection 的。
  • 服务器端的一切设置是否正确?像扩展解析、响应的布局和它们的视图?这似乎更像是服务器问题而不是客户端问题。
  • 我最终解决了这个问题。我现在正在工作,稍后会发布更新。

标签: iphone cakephp rest post afnetworking


【解决方案1】:

这些是最终满足我对 Web 服务的请求的基本(删除了我为自己使用的条件)的行。感谢@8vius 和@mattt 的建议!

- (IBAction)loginButtonPressed {        
    NSURL *baseURL = [NSURL URLWithString:@"https://www.example.com/api/class"];

    //build normal NSMutableURLRequest objects
    //make sure to setHTTPMethod to "POST". 
    //from https://github.com/AFNetworking/AFNetworking
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
    [httpClient defaultValueForHeader:@"Accept"];

    NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
                            [usernameTextField text], kUsernameField, 
                            [passwordTextField text], kPasswordField, 
                            nil];

    NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST" 
          path:@"https://www.example.com/api/class/function" parameters:params];

    //Add your request object to an AFHTTPRequestOperation
    AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] 
                                      initWithRequest:request] autorelease];

    //"Why don't I get JSON / XML / Property List in my HTTP client callbacks?"
    //see: https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ
    //mattt's suggestion http://stackoverflow.com/a/9931815/1004227 -
    //-still didn't prevent me from receiving plist data
    //[httpClient registerHTTPOperationClass:
    //         [AFPropertyListParameterEncoding class]];

    [httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];

    [operation setCompletionBlockWithSuccess:
      ^(AFHTTPRequestOperation *operation, 
      id responseObject) {
        NSString *response = [operation responseString];
        NSLog(@"response: [%@]",response);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"error: %@", [operation error]);
    }];

    //call start on your request operation
    [operation start];
    [httpClient release];
}

【讨论】:

  • 注册 plist 操作只会影响使用 AFHTTPClient -HTTPRequestOperationWithRequest:success:failure: 创建的请求操作。 alloc init-ing AFHTTPRequestOperation 总是会给你一个AFHTTPRequestOperation
  • @pouria,这里的路径是什么。是不是像同一个网址。请帮助我,我被困在 Path 中。
  • @G.Ganesh 我有点晚了。 Path 只是类的一个方法,它使用给定的参数集响应 HTTP POST。希望您解决了您的问题。
【解决方案2】:

使用AFHTTPClient -postPath:parameters:success:failure:,传递你的参数(嵌套字典/数组很好)。如果您希望收到 plist,请务必让客户注册 AFPropertyListRequestOperation

无论如何,setValue:forHTTPHeaderField: 不是你想要的。 HTTP headers 用于指定有关请求本身的信息;数据是请求正文的一部分。 AFHTTPClient 自动将参数转换为GET 请求的查询字符串或POST 等的HTTP 正文。

【讨论】:

  • 我解决了这个问题,但我感觉我仍然在做错事或效率低下。如果您快速查看我的解决方案,我将不胜感激。谢谢!
猜你喜欢
  • 2012-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-17
  • 2015-01-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多