Posts Tagged Web Service

iPhone ile Web Service Kullanımı

iPhone uygulaması yazarken “Web Service” leri kullanmak isterseniz giriş niteliğinde kabul edilebilecek bu belgeyi kullanabilirsiniz.

Önce çalışan bir “Web Service” örneğine ihtiyacımız var. Asıl amaç “Web Service” yazmak olmadığından, elinizin altında da olmaması durumunda, birde bununla uğraşmamak için aşağıdaki örneği kullabilirsiniz. Bu dokümanın devamında bu örnek üzerinden anlatım yapılacaktır.

http://www.w3schools.com/webservices/tempconvert.asmx?op=CelsiusToFahrenheit

Bu adresi web tarayıcınıza yazdığınızda gelecek sayfada XML mesajlarını(sırasıyla request & response) görebilirsiniz. Öncelikle buradan “request” mesajını alıp koda yerleştirmekle işe başlayabilirsiniz.

webservice1

NSString *soapMessage = @"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
			"<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/\">\n"
			"<soap:Body >\n"
			"<CelsiusToFahrenheit xmlns=\"http://tempuri.org/\">\n"
			"<Celsius>25</Celsius>\n"
			"</CelsiusToFahrenheit>\n"
			"</soap:Body>\n"
			"</soap:Envelope>\n";

XML datayı oluşturduktan sonra “Web Service URL” i ile bir URL objesi ve “request” oluşturmak gerekecek. Bu request için “HTTP Header” alanlarını tanımlayabilirsiniz.

“Content-Type”
“SOAPAction”
“Content-Length”

Bunları XML mesajının üzerinde bulabilirsiniz. “HTTP Method” ve “HTTP Body” yi de tanımladıtan sonra “request” i kullanarak bağlantıyı oluşturmaya başlayabilirsiniz.

webservice2

	NSURL *url = [NSURL URLWithString:@"http://www.w3schools.com/webservices/tempconvert.asmx?op=CelsiusToFahrenheit"];
 
	NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
	NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMessage length]];
 
	[theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
	[theRequest addValue: @"http://tempuri.org/CelsiusToFahrenheit" forHTTPHeaderField:@"SOAPAction"];
	[theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"];
	[theRequest setHTTPMethod:@"POST"];
	[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
 
	NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

Artık yapılması gereken bir bağlantı kurup, dönen XML cevabı parse etmek. Bağlantıyı “NSURLConnection” ile sağlıyoruz. Bağlantı sağladığında “NSURLConnection” in bazı methodlarını düzenlemek gerekmektedir. Dönen veriyi alabilmek için bu methodlar kullanılabilir. Cevabı “NSMutableData” objesine alarak, içinden istediğimiz değeri alabilirsiniz.

“NSURLConnection” methodları:

  • “didReceiveResponse” bağlantı kurulabiliyorsa çalışır. Bağlantı kurulabildiğini anladığımızda bizde Data’mızı sıfırlıyoruz.
  • “didReceiveData” herhangi bir data alınabildiğinde çalışır. Burada dönen datayı objenize alabilirsiniz.
  • “didFailWithError” ile herhangi bir hata durumunda “connection” ve “data” objelerini release etmek için uygun yer olacaktır.
  • Son method ise “connectionDidFinishLoading” bağlantı sona erdiğinde çalışacaktır. Burada dönen datadan bir xml metin oluşturabilir ve bu xml metni parse edebilirsiniz.
// Bağlantı kurulabiliyor mu?
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
	[webData setLength: 0];
}
// Dönen datayı alabileceğimiz method.
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
	[webData appendData:data];
}
// Bağlantıda herhangi bir hata olursa çalışacak method.
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
	NSLog(@"ERROR with theConnection");
	[connection release];
	[webData release];
}
// Bağlantı cevabı döndüğünde çalışan method. XML parse işlemini burada gerçekleştiriyoruz.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
	NSLog(@"DONE. Received Bytes: %d", [webData length]);
	NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
	NSLog(theXML);
	[theXML release];
 
	if( xmlParser )
	{
		[xmlParser release];
	}
 
	xmlParser = [[NSXMLParser alloc] initWithData: webData];
	[xmlParser setDelegate: self];
	[xmlParser setShouldResolveExternalEntities: YES];
	[xmlParser parse];
 
	[connection release];
	[webData release];
}

“connectiondidFinishLoading” methodunda görebileceğiniz gibi dönüş değeri olan XML datayı NSXMLParser ile ayrıştırabilirsiniz. Bunu yapmak içinde NSXMLParser’ın methodlarını çağırmanız gerekmektedir:

  • “didStartElement” ile XML içindeki elementlerin başlangıcına bakıyoruz. Burada “CelsiusToFahrenheitResult” elementini arıyoruz. (recordResults = TRUE;)
  • “foundCharacters” elementin içindeki değeri eğer doğru element ise alacak method.
  • Son method elementin bitişine bakıyor. Burada aldğımız değeri ekrana yerleştirecek kod parçasını yazabilirsiniz.
// XML Element başlangıcı.
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qName
attributes: (NSDictionary *)attributeDict
{
	if( [elementName isEqualToString:@"CelsiusToFahrenheitResult"])
	{
		if(!results)
		{
			results = [[NSMutableString alloc] init];
		}
		recordResults = TRUE;
	}
}
// Elementin içinde yazılı değer aldığımız method.
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
	if( recordResults )
	{
		[results appendString: string];
	}
}
// XML içinde .... ile Element bittiğinde aldığımız değeri ekranda bir component(Label, TextField vb.) içinde
// gösteriyoruz.
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
	if( [elementName isEqualToString:@"CelsiusToFahrenheitResult"])
	{
		recordResults = FALSE;
		myLabel.text = results;
		[results release];
		results = nil;
	}
}

“Web Service” örneğimiz dönüş değerini XML metni içinde isimli “Tag” ile vermekte. Bu değeri XML içinde alabilmek için yukarıda görüdüğümüz “didStartElement” ve “didEndElement” methodlarını yazdık. Start methodunda elementini gördüğümüz yerde bir “result” objesi oluşturuyor ve doğru elementi bulduğumuzu belirten bir sonuç değişkenine “TRUE” değerini atıyoruz. Sonra doğru elementte ise o elementin değerini “results(NSMutableString)” içine alıyoruz. En sonda ise “myLabel(UILabel)” üstüne yazdırıyoruz.

Bu yazıda geçen kavramlar ile ilgili ayrıntılı bilgi için aşağıdaki bağlantıları kullanabilirsiniz:

http://developer.apple.com/documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html
http://developer.apple.com/documentation/Cocoa/Conceptual/XMLParsing/XMLParsing.html
http://www.w3schools.com/soap/default.asp

,

7 Comments