segunda-feira, abril 25, 2011

WCF + Objective-C

Depois de muito tentar e procurar uma alternativa para fazer a conexão de um serviço WCF com minha aplicação, finalmente achei uma solução.

Bom primeiro devemos adicionar as variaveis no header da classe que irá conter a conexão.


NSMutableData *webData;
NSMutableString *soapResults;
NSURLConnection *conn;

NSXMLParser *xmlParser;
BOOL elementFound;


Depois na implementação o método que irá chamar o serviço.

NSString *SOAPEnvelope =
[NSString stringWithFormat:
@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<SOAP-ENV:Envelope \n"
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" \n"
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n" 
"xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" \n"
"SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" \n"
"xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"> \n"
"<SOAP-ENV:Body> \n"
"<HelloWorld xmlns=\"http://tempuri.org/\">"
"</HelloWorld> \n"
"</SOAP-ENV:Body> \n"
"</SOAP-ENV:Envelope>"];

//Debug
NSLog(@"SOAP ENVELOPE %@", SOAPEnvelope);

NSURL *url = [NSURL URLWithString:@"http://SERVER/WCFServiceName/ServiceName.svc"];  
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

//Header  
NSString *SOAPEnvelopeLength = [NSString stringWithFormat:@"%d", [SOAPEnvelope length]];  
[request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];  
[request addValue:@"http://tempuri.org/WCFServiceName/HelloWorld" forHTTPHeaderField:@"SOAPAction"];
[request addValue:SOAPEnvelopeLength forHTTPHeaderField:@"Content-Length"];

//Method & Body
[request setHTTPMethod:@"POST"];  
[request setHTTPBody:[SOAPEnvelope dataUsingEncoding:NSUTF8StringEncoding]];

// Connection
conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];

if (conn) {  
webData = [[NSMutableData data] retain];  
}

E depois adicione os métodos de comunicação com o serviço na mesma classe.

-(void) connection:(NSURLConnection *) connection
didReceiveResponse:(NSURLResponse *) response {
    [webData setLength: 0];
}

-(void) connection:(NSURLConnection *) connection
    didReceiveData:(NSData *) data {
    [webData appendData:data];
}

-(void) connection:(NSURLConnection *) connection
  didFailWithError:(NSError *) error {
    [webData release];
    [connection release];
}

-(void) connectionDidFinishLoading:(NSURLConnection *) connection {
    NSLog(@"DONE. Received Bytes: %d", [webData length]);
    NSString *theXML = [[NSString alloc]
            initWithBytes: [webData mutableBytes]
            length:[webData length]
            encoding:NSUTF8StringEncoding];
    //Debug
    NSLog(@"XML %@",theXML);
    [theXML release];

if (xmlParser) {
        [xmlParser release];
    }
    xmlParser = [[NSXMLParser alloc] initWithData: webData];
    [xmlParser setDelegate:self];
    [xmlParser setShouldResolveExternalEntities:YES];
    [xmlParser parse];
    [connection release];
    [webData release];
}

-(void) parser:(NSXMLParser *) parser
didStartElement:(NSString *) elementName
  namespaceURI:(NSString *) namespaceURI
 qualifiedName:(NSString *) qName
attributes:(NSDictionary *) attributeDict {
//Debug
NSLog(@"%@", elementName);
    if( [elementName isEqualToString:@"HelloWorldResult"]) {
        if (!soapResults) {
            soapResults = [[NSMutableString alloc] init];
        }
        elementFound = YES;
    }
}

-(void)parser:(NSXMLParser *) parser 
foundCharacters:(NSString *)string {
    if (elementFound) {
        [soapResults appendString: string];
    }
}

-(void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
 namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName {
    NSLog(@"SOAP RESULT %@", soapResults);
    if ([elementName isEqualToString:@"HelloWorldResult"]) {

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello"    
            message:soapResults   
            delegate:self  
            cancelButtonTitle:@"OK"
            otherButtonTitles:nil];
        [alert show];
        [alert release];
        [soapResults setString:@""];
        elementFound = FALSE;
    }
}