我是SOAP和iOS的新手,所以请耐心等待。 我正在尝试使用生成的源SudzC来使用SOAP WS。
看看输出,事情看起来几乎正常。我可以看到我需要的数据,因此数据似乎正在跨越线路:
2012-03-30 17:26:14.131 EZSystem[892:707]
Loading: http://xx.xx.xx.xxx:xxxx/service
2012-03-30 17:26:14.137 EZSystem[892:707]
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns="http://database.usah.com/">
<soap:Body>
<getQB2012CustomerDictionaryXML></getQB2012CustomerDictionaryXML>
</soap:Body>
</soap:Envelope>
2012-03-30 17:26:14.485 EZSystem[892:707]
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getQB2012CustomerDictionaryXMLResponse
xmlns:ns2="http://xxxxxx/">
<return>
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!--
<[Quickbooks tag]>Database Column Name</[Quickbooks tag]>
--><CustomerRet database_root_tag="Customers" id="id_customers"
...
...
...
</return>
</ns2:getQB2012CustomerDictionaryXMLResponse>
</S:Body>
</S:Envelope>
我发送的是一个表示XML的字符串,或者是XML。
但是,以下代码返回null:
-(void)logIn{
DictionaryQB2012DatabaseKeyService* service =
[DictionaryQB2012DatabaseKeyService service];
service.logging = YES;
// Returns NSString*.
[service getQB2012CustomerDictionaryXML:self
action:@selector(getQB2012CustomerDictionaryXMLHandler:)];
}
// Handle the response from getQB2012CustomerDictionaryXML.
- (void) getQB2012CustomerDictionaryXMLHandler: (id) value {
// Handle errors
if([value isKindOfClass:[NSError class]]) {
NSLog(@"%@", value);
return;
}
// Handle faults
if([value isKindOfClass:[SoapFault class]]) {
NSLog(@"%@", value);
return;
}
// Do something with the NSString* result
NSString* result = (NSString*)value;
NSLog(@"getQB2012CustomerDictionaryXML returned the value: %@", result);
}
该值为空。
在这个过程中它崩溃了吗?似乎我收到了我需要的数据,但是将它转换为OBJ-C字符串失败了。
任何帮助将不胜感激,
戴恩
答案 0 :(得分:1)
在SudzC中生成了SoapRequest.m:
- (void) connectionDidFinishLoading:(NSURLConnection *) connection {
...
if(self.logging == YES){
NSString* response = [[NSString alloc] initWithData: self.receivedData
encoding: NSUTF8StringEncoding];
NSLog(@"%@", response);
}
...
}
响应是原始SOAP响应,它包含预期的数据。
用同样的方法,
CXMLNode* element = [[Soap getNode: [doc rootElement] withName: @"Body"]
childAtIndex:0];
此行从SOAP响应中获取返回值。经过一番探讨,事实证明“身体”是问题所在:
SOAP响应具有“S:Body”,因此将withName更改为正确的标记名称可以修复所有内容。
这让我感到困扰,因为我不知道我的WS是错还是什么,但我现在就把它拿走。
此外,可能必须修改Soap.m,因为它使用“soap”而不是“soapenv”。这些值是硬编码的,但变化相当容易。
此外,命名空间保留为空:
[s appendFormat:@"=\"http://schemas.xmlsoap.org/soap/envelope/\"
xmlns=\"%@\">", ns];
这可能必须是xmlns:[namespace] = \“%@”... 其中namespace是剥离的命名空间。
那是:
http://namespace/ => namespace
此外,您无法接收字符串结果并在示例中使用它,至少在我的结尾。 例如:
NSString* result = (NSString*) value;
应该产生null。然而,这似乎有效:
NSDictionary* result = (NSDictionary*)value;
NSString* finalResult = [[result allValues] objectAtIndex:0];
如果有人有兴趣,这里是对我制作的Soap.m的修改。
// Soap.m
NSString* const SOAP_PREFIX = @"soapenv";
NSString* const HTTP_PREFIX = @"http://";
NSUInteger const FORWARD_FLASH_CHARACTER_VALUE = 47;
// Creates the XML request for the SOAP envelope with optional SOAP headers.
+ (NSString*) createEnvelope: (NSString*) method forNamespace: (NSString*) ns
forParameters: (NSString*) params withHeaders: (NSDictionary*) headers
{
NSMutableString* s = [NSMutableString string];
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendString: @"<"];
[s appendString: SOAP_PREFIX];
[s appendString:@":Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-
instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""];
[s appendString:@" xmlns:"];
[s appendString: SOAP_PREFIX];
NSString* rawNamespace = [Soap getRawNamespace:ns];
[s appendFormat:@"=\"http://schemas.xmlsoap.org/soap/envelope/\"
xmlns:%@=\"%@\">", rawNamespace, ns];
if(headers != nil && headers.count > 0) {
[s appendString: @"<"];
[s appendString: SOAP_PREFIX];
[s appendString:@":Header>"];
for(id key in [headers allKeys]) {
if([[headers objectForKey: key] isMemberOfClass: [SoapNil class]])
{
[s appendFormat: @"<%@ xsi:nil=\"true\"/>", key];
} else {
[s appendString:[Soap serializeHeader:headers forKey:key]];
}
}
[s appendString: @"</"];
[s appendString: SOAP_PREFIX];
[s appendString:@":Header>"];
}
[s appendString: @"<"];
[s appendString: SOAP_PREFIX];
[s appendString:@":Body>"];
NSMutableString* fullMethodName = [NSMutableString string];
[fullMethodName appendString:rawNamespace];
[fullMethodName appendString:@":"];
[fullMethodName appendString:method];
[s appendFormat: @"<%@>%@</%@>", fullMethodName,[params
stringByReplacingOccurrencesOfString:@"&" withString:@"&"],
fullMethodName];
[s appendString: @"</"];
[s appendString: SOAP_PREFIX];
[s appendString:@":Body>"];
[s appendString: @"</"];
[s appendString: SOAP_PREFIX];
[s appendString:@":Envelope>"];
return s;
}
+(NSString*)getRawNamespace:(NSString *)value{
if([value hasPrefix:HTTP_PREFIX]){
NSString* rawNamespace = [value substringFromIndex:([HTTP_PREFIX length])];
if([rawNamespace length] == 0){
return @"";
}
// strip out a trailing slash
if([rawNamespace characterAtIndex:([rawNamespace length]- 1)] ==
FORWARD_FLASH_CHARACTER_VALUE){
NSRange range = NSMakeRange (0, [rawNamespace length] - 1);
rawNamespace = [rawNamespace substringWithRange:(range)];
}
return rawNamespace;
}
else{
return value;
}
}