我对开发iOS应用程序有点新意,我在此应用程序中需要做的一件事就是连接到REST Web服务。我已经在邮差扩展中测试了WS,一切正常,但我似乎无法通过iOS应用程序做同样的事情。这是我用来尝试建立连接的代码:
NSString *wsAuth = [NSString stringWithFormat:@"Basic \%@", [[@"USER:PASS" dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:nil]];
NSMutableDictionary *post = [[NSMutableDictionary alloc]init];
[post setValue:login forKey:@"user"];
[post setValue:pass forKey:@"pass"];
NSArray *arr = [NSArray arrayWithObjects:post, nil];
NSData *jsonPost = [NSJSONSerialization dataWithJSONObject:arr options:0 error:nil];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://mywebservice.mywebsite.com/auth/"]];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:jsonPost];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:[NSString stringWithFormat:@"%d", [jsonPost length]] forHTTPHeaderField:@"Content-Length"];
[request setValue:wsAuth forHTTPHeaderField:@"Authorization"];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[conn start];
NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSData *urlData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if([response statusCode] >=200 && [response statusCode] <300) {
// Process data...
}
else {
// Present error...
}
我从Xcode收到以下错误:
2016-03-16 11:02:34.658 [31742:2969162] Response = (null)
2016-03-16 11:02:34.659 [31742:2969162] Error =
Error Domain=NSURLErrorDomain Code=-1001 "The request timed out."
UserInfo={NSErrorFailingURLStringKey=https://mywebservice.mywebsite.com/auth/,
_kCFStreamErrorCodeKey=-2102,
NSErrorFailingURLKey=https://mywebservice.mywebsite.com/auth/,
NSLocalizedDescription=The request timed out.,
_kCFStreamErrorDomainKey=4,
NSUnderlyingError=0x7aa5b510 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "The request timed out."
UserInfo={_kCFStreamErrorCodeKey=-2102,
NSErrorFailingURLStringKey=https://mywebservice.mywebsite.com/auth/,
NSErrorFailingURLKey=https://mywebservice.mywebsite.com/auth/,
NSLocalizedDescription=The request timed out.,
_kCFStreamErrorDomainKey=4}}}
2016-03-16 11:02:34.693 [31742:2969383] CFNetwork SSLHandshake failed (-9806)
2016-03-16 11:02:34.799 [31742:2969383] CFNetwork SSLHandshake failed (-9802)
2016-03-16 11:02:34.889 [31742:2969383] CFNetwork SSLHandshake failed (-9802)
2016-03-16 11:02:34.890 [31742:2969383] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
要了解一些额外的事情。我将其编程为需要与iOS 8或更高版本一起使用的iOS 9应用程序,我在Xcode 7中执行此操作。任何帮助都将不胜感激。
答案 0 :(得分:0)
答案 1 :(得分:0)
好的,所以我自己想出来了。我想同步请求不起作用,所以我切换到异步。这给了我一个更准确的错误,它告诉我不是传递JSON对象,而是传递一个数组,第一个唯一的条目是JSON对象,导致身份验证失败。
为了澄清,此解决方案包含几个与RESTful Web服务进行通信的对象。这是通过POST完成的,使用JSON对象作为POST变量。此Web服务需要基本身份验证,这是通过第1行和第15行的此代码实现的。最后,这都是基于安全连接和最新SSL证书背后的Web服务。我不是100%确定HTTP请求或自签名证书的工作原理......
附注:我从NSAllowsArbitraryLoads
文件中删除了NSAppTransportSecurity
密钥和info.plist
字典,此解决方案仍然有效。
以下代码为我提供了与安全Web服务的成功连接:
NSString *wsAuth = [NSString stringWithFormat:@"Basic \%@", [[@"USER:PASS" dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0]];
NSMutableDictionary *post = [[NSMutableDictionary alloc]init];
[post setValue:login forKey:@"user"];
[post setValue:pass forKey:@"pass"];
NSArray *arr = [NSArray arrayWithObjects:post, nil];
// Note the first value of the array is being referenced, not the entire array.
NSData *jsonPost = [NSJSONSerialization dataWithJSONObject:arr[0] options:0 error:nil];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://mywebservice.mywebsite.com/auth/"]];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:jsonPost];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:[NSString stringWithFormat:@"%d", [jsonPost length]] forHTTPHeaderField:@"Content-Length"];
[request setValue:wsAuth forHTTPHeaderField:@"Authorization"];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ([data length] >0 && error == nil) {
// Process data here...
}
else if ([data length] == 0 && error == nil) {
NSLog(@"Empty Response. Check your credentials.");
}
else if (error != nil) {
NSLog(@"Error = %@", error);
}
}];