使用 NSURLSession POST, post 变量的正确方法是什么?
Using NSURLSession to POST, what is the correct way to post the variables?
我正在学习本教程:http://www.raywenderlich.com/2965/how-to-write-an-ios-app-that-uses-a-web-service。试图建立一个基本的网络服务。好像教程是旧的 material 并且 ASIHTTPRequest 不再继续。我一直在尝试改用 NSURLRequest。第一个问题,NSURLRequest 是一种非常标准的方法吗?我只是想要一些基本的 GET,POST 等,我应该用不同的方式来做吗?
我的代码是:
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
NSLog(@"We want to unlock for the code %@",self.textField.text);
//Get a device ID, (actually can't do this aymore)
NSString *uniqueIdentifier = @"My iPhone";
NSString *code = self.textField.text;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.madasd.co/promos/"]];
request.HTTPMethod=@"POST";
//Set the header fields
[request setValue:@"application/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
NSString *myString = [NSString stringWithFormat:@"rw_app_id=1&code=%@&device_id=%@",code,uniqueIdentifier];
NSLog(@"%@",myString);
NSData *requestBodyData = [myString dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody=requestBodyData;
//Create url and fire request
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[conn start];
return TRUE;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",string);
}
第二个问题,我已经使用 curl 测试了后端,所以我知道它工作正常,但是我得到的响应是 "Invalid Request",我认为这是因为我发送的字符串不正确。我使用 var 名称和 & 运算符是否正确?对此的任何指示都会很棒!谢谢。 (运行 Linode 上的 LAMP 服务器!)
编辑:
也尝试发送为 JSON:
[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
NSDictionary *mapData = [[NSDictionary alloc]initWithObjectsAndKeys:@"1",@"rw_app_id",code,@"code",uniqueIdentifier,@"device_id", nil];
NSError *error = nil;
NSData *requestBodyData = [NSJSONSerialization dataWithJSONObject:mapData options:0 error:&error];
request.HTTPBody=requestBodyData;
仍然出现同样的错误。
您可能需要将字符串包装到字典中,并通过调用 NSJSONSerialization 获取 NSData 对象。虽然这取决于服务器期望的形式。
几个想法:
不要使用 NSURLConnection
。自 iOS 起已弃用 9. 使用 NSURLSession
。请参阅 URL 加载系统编程指南中的 Using NSURLSession。
确定您需要准备的请求类型。您在 header 中指定了 application/xml
,但正在创建 application/x-www-form-urlencoded
请求。您的 Content-Type
header 必须与您构建 HTTPBody
.
的方式相匹配
您的服务器需要什么类型的请求? x-www-form-urlencoded
? XML? JSON?
此外,您的服务器提供什么类型的响应?
如果构建 application/x-www-form-urlencoded
请求(如您请求的 body 所建议),您没有正确地转义值百分比(请参阅 https://whosebug.com/a/20398755/1271826) .
如果你使用基于 NSURLConnection
或 NSURLSession
的委托,你不应该只获取 didReceiveData
中的结果。你需要做的是
在开始请求之前实例化一个NSMutableData
;
didReceiveData
仅附加到 NSMutableData
;
只有当 connectionDidFinishLoading:
(在 NSURLConnection
中)或 URLSession:task:didCompleteWithError:
(在 NSURLSession
中)被调用时,才应该使用 NSMutableData
.
或者,如果使用 block-based NSURLSession
,这个问题就完全消除了(因为您没有实现任何委托方法)。使用 NSURLSession
的基于 completionHandler
的方法要容易得多。
如果所有这些都太复杂,您可以考虑使用 AFNetworking's AFHTTPSessionManager
(但不是 AFHTTPRequestOperationManager
)来构建您的请求。它可以让您摆脱正确构建请求、实现委托方法等的困境。
我正在学习本教程:http://www.raywenderlich.com/2965/how-to-write-an-ios-app-that-uses-a-web-service。试图建立一个基本的网络服务。好像教程是旧的 material 并且 ASIHTTPRequest 不再继续。我一直在尝试改用 NSURLRequest。第一个问题,NSURLRequest 是一种非常标准的方法吗?我只是想要一些基本的 GET,POST 等,我应该用不同的方式来做吗?
我的代码是:
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
NSLog(@"We want to unlock for the code %@",self.textField.text);
//Get a device ID, (actually can't do this aymore)
NSString *uniqueIdentifier = @"My iPhone";
NSString *code = self.textField.text;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.madasd.co/promos/"]];
request.HTTPMethod=@"POST";
//Set the header fields
[request setValue:@"application/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
NSString *myString = [NSString stringWithFormat:@"rw_app_id=1&code=%@&device_id=%@",code,uniqueIdentifier];
NSLog(@"%@",myString);
NSData *requestBodyData = [myString dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody=requestBodyData;
//Create url and fire request
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[conn start];
return TRUE;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",string);
}
第二个问题,我已经使用 curl 测试了后端,所以我知道它工作正常,但是我得到的响应是 "Invalid Request",我认为这是因为我发送的字符串不正确。我使用 var 名称和 & 运算符是否正确?对此的任何指示都会很棒!谢谢。 (运行 Linode 上的 LAMP 服务器!)
编辑:
也尝试发送为 JSON:
[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
NSDictionary *mapData = [[NSDictionary alloc]initWithObjectsAndKeys:@"1",@"rw_app_id",code,@"code",uniqueIdentifier,@"device_id", nil];
NSError *error = nil;
NSData *requestBodyData = [NSJSONSerialization dataWithJSONObject:mapData options:0 error:&error];
request.HTTPBody=requestBodyData;
仍然出现同样的错误。
您可能需要将字符串包装到字典中,并通过调用 NSJSONSerialization 获取 NSData 对象。虽然这取决于服务器期望的形式。
几个想法:
不要使用
NSURLConnection
。自 iOS 起已弃用 9. 使用NSURLSession
。请参阅 URL 加载系统编程指南中的 Using NSURLSession。确定您需要准备的请求类型。您在 header 中指定了
的方式相匹配application/xml
,但正在创建application/x-www-form-urlencoded
请求。您的Content-Type
header 必须与您构建HTTPBody
.您的服务器需要什么类型的请求?
x-www-form-urlencoded
? XML? JSON?此外,您的服务器提供什么类型的响应?
如果构建
application/x-www-form-urlencoded
请求(如您请求的 body 所建议),您没有正确地转义值百分比(请参阅 https://whosebug.com/a/20398755/1271826) .如果你使用基于
NSURLConnection
或NSURLSession
的委托,你不应该只获取didReceiveData
中的结果。你需要做的是在开始请求之前实例化一个
NSMutableData
;didReceiveData
仅附加到NSMutableData
;只有当
connectionDidFinishLoading:
(在NSURLConnection
中)或URLSession:task:didCompleteWithError:
(在NSURLSession
中)被调用时,才应该使用NSMutableData
.
或者,如果使用 block-based
NSURLSession
,这个问题就完全消除了(因为您没有实现任何委托方法)。使用NSURLSession
的基于completionHandler
的方法要容易得多。如果所有这些都太复杂,您可以考虑使用 AFNetworking's
AFHTTPSessionManager
(但不是AFHTTPRequestOperationManager
)来构建您的请求。它可以让您摆脱正确构建请求、实现委托方法等的困境。