在iPhone的开发过程中,我们经常会遇到需要从服务器获取数据或者把已有数据传到服务器的情况。如何实现这些呢。一般情况下,我们会有两种选择,同步调用和异步调用服务器中提供的service。本文内容参考苹果公司文档《URL Loading System》。
做此事情之前,我们需要熟悉了解NSURLConnection类。因为我们首先需要使用NSURLConnection创建一个连接,连接到服务器的service。
连接创建成功侯,再创建一个NSMutableData实例来存储从服务器得到的数据。
代码1如下:
view plaincopy to clipboardprint?
// create the request
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL
URLWithString:@"http://www.apple.com/"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// create the connection with the request
// and start loading the data
NSURLConnection *theConnection=[[NSURLConnection alloc]initWithRequest:theRequest
delegate:self];
if (theConnection) {
// Create the NSMutableData that will hold
// the received data
// receivedData is declared as a method instance elsewhere
receivedData=[[NSMutableData data] retain];
} else {
// inform the user that the download could not be made
}
通过上面的代码可以看到,NSURLConnection创建的时候需要一个delegate来实现相应的操作。通常情况下,完成一个服务器的连接,到下载数据到本地device上,需要至少实现connection:didReceiveResponse:,connection:didReceiveData:, connection:didFailWithError: 和
connectionDidFinishLoading: 四个相应的方法。
代码2如下:
view plaincopy to clipboardprint?
- (void)connection:(NSURLConnection *)connectiondidReceiveResponse:(NSURLResponse *)response
{
// this method is called when the server has determined thatit
// has enough information to create the NSURLResponse
// it can be called multiple times, for example in the case ofa
// redirect, so each time we reset the data.
// receivedData is declared as a method instance elsewhere
[receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data
{
// append the new data to the receivedData
// receivedData is declared as a method instance elsewhere
[receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError*)error
{
// release the connection, and the data object
[connection release];
// receivedData is declared as a method instance elsewhere
[receivedData release];
// inform the user
NSLog(@"Connection failed! Error - %@ %@",
[error localizedDescription],
[[error userInfo]objectForKey:NSErrorFailingURLStringKey]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// do something with the data
// receivedData is declared as a method instance elsewhere
NSLog(@"Succeeded! Received %d bytes ofdata",[receivedData length]);
// release the connection, and the data object
[connection release];
[receivedData release];
}
同时我们需要在.h文件中声明receivedData变量。如果要使本程序运行成功,我想还需要添加一个触发时间的按钮button在view上。把代码1中的内容放入button事件中,相应的程序就会异步调用到http://www.apple.com/中的内容了。
当然,我们上文的内容还只是宽泛的列出了苹果文档中的相应的代码。如果你想实现自己的service调用的话,首先需要配制自己的服务器端的servie。本文以作者的建立的service为例,大致更新一下代码1中的内容。使用的朋友可以相应的参考代码3。
代码3如下:
view plaincopy to clipboardprint?
- (IBAction)Download:(id)sender
{
NSString *table = @"DownloadCity";
//NSAutoreleasePool *requestPoll =[[NSAutoreleasePool alloc]init];
NSMutableString *sRequest = [[NSMutableStringalloc] init];
// Create the SOAP body
[sRequest appendString:@"<soap:Envelopexmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"];
// This is the header section it is expecting inthe body
[sRequest appendString:@"<soap:Body>"];
[sRequest appendString:[NSStringstringWithFormat:@"<%@xmlns=\"http://www.MySite.com/webservices\">",table]];
[sRequest appendString:[NSStringstringWithFormat:@"</%@>",table]];
[sRequest appendString:@"</soap:Body>"];
[sRequestappendString:@"</soap:Envelope>"];
// create the request
NSMutableURLRequest *request=[NSMutableURLRequestrequestWithURL:[NSURL URLWithString:[NSStringstringWithFormat:@"https://MySiteIP/test.asmx?op=%@",table]]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60];
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[[NSURLURLWithString:[NSStringstringWithFormat:@"https://MySiteIP/test.asmx?op=%@",table]]host]];
// Add the Required WCF Header Values. Thisis what the WCF service expects in the header.
[request addValue:@"text/xml; charset=utf-8"forHTTPHeaderField:@"Content-Type"];
[request addValue:[NSStringstringWithFormat:@"http://www.MySite.com/webservices/%@",table]forHTTPHeaderField:@"SOAPAction"];
//set the Soap Header: user name and password
[request setValue:@"MyName"forHTTPHeaderField:@"UserName"];
[request setValue:@"MyPassword"forHTTPHeaderField:@"Password"];
// Set the action to Post
[request setHTTPMethod:@"POST"];
// Set the body
[request setHTTPBody:[sRequestdataUsingEncoding:NSUTF8StringEncoding]];
[sRequest release];
// create the connection with the request
// and start loading the data
conn=[[NSURLConnection alloc] initWithRequest:requestdelegate:self startImmediately:YES];
if (conn)
{
receivedData=[[NSMutableData data] retain];
}
else
{
}
}
}
代码3相应内容需要换成你自己service的相应内容。 相比异步调用,同步调用要简单的多,但是相应的功能也不入异步灵活。