SudzC показывает «действительный» ответ мыла, но нулевое значение на стороне iOS - PullRequest
1 голос
/ 31 марта 2012

Я довольно новичок в SOAP и iOS, поэтому, пожалуйста, потерпите меня.Я пытаюсь использовать SOAP WS с использованием исходного кода SudzC.

Глядя на вывод, кажется, что все почти работает.Я вижу нужные данные, поэтому кажется, что данные перемещаются по проводам:

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>
        &lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;&lt;!-- 
        &lt;[Quickbooks tag]&gt;Database Column Name&lt;/[Quickbooks tag]&gt;
        --&gt;&lt;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);

}

Значение равно NULL.

Где в процессе происходит разрушение?Похоже, что я получаю данные, которые мне нужны, но получить их в строку OBJ-C не удается.

Любая помощь будет принята,

Dane

1 Ответ

1 голос
/ 01 апреля 2012

В 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.После некоторого осмотра выясняется, что проблема заключалась в «Body»:

Ответ SOAP имеет «S: Body», поэтому изменение с помощью name на правильное имя тега исправляет все.

Это беспокоитмне, так как я не знаю, виноват ли мой WS или что-то еще, но я сейчас возьму его.

Кроме того, Soap.m, возможно, придется изменить, так как он использует "мыло" вместо, скажем, "soapenv" .Эти значения жестко запрограммированы, но изменение довольно простое.

Кроме того, пространство имен остается пустым:

[s appendFormat:@"=\"http://schemas.xmlsoap.org/soap/envelope/\" 
xmlns=\"%@\">", ns]; 

Это может быть xmlns: [namespace] = \ "%@ "... где пространство имен - это разделенное пространство имен.

То есть:

http://namespace/ => namespace

Кроме того, вы не можете получить строковый результат и использовать его, как в примерах, по крайней мере, с моей стороны.Например:

NSString* result = (NSString*) value;

должно выдавать ноль.Однако, похоже, это работает:

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:@"&amp;"], 
            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;
    }
}    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...