在iPhone的開發過程中,我們經常會遇到需要從伺服器擷取資料或者把已有資料傳到伺服器的情況。如何?這些呢。一般情況下,我們會有兩種選擇,同步
調用和非同步呼叫伺服器中提供的service。本文內容參考蘋果公司文檔《URL Loading System》。
做此事情之前,我們需要熟悉瞭解NSURLConnection類。因為我們首先需要使用NSURLConnection建立一個串連,串連到伺服器的service。
串連建立成功侯,再建立一個NSMutableData執行個體來儲存從伺服器得到的資料。
代碼1如下:
view plaincopy to clipboardprint?<br />// create the request<br />NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL<br />URLWithString:@"http://www.apple.com/"]<br /> cachePolicy:NSURLRequestUseProtocolCachePolicy<br /> timeoutInterval:60.0];<br />// create the connection with the request<br />// and start loading the data<br />NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest<br />delegate:self];<br />if (theConnection) {<br /> // Create the NSMutableData that will hold<br /> // the received data<br /> // receivedData is declared as a method instance elsewhere<br /> receivedData=[[NSMutableData data] retain];<br />} else {<br /> // inform the user that the download could not be made<br />}<br />
通過上面的代碼可以看到,NSURLConnection建立的時候需要一個delegate來實現相應的操作。通常情況下,完成一個伺服器的串連,到下
載資料到本地device上,需要至少實現connection:didReceiveResponse:,
connection:didReceiveData:, connection:didFailWithError: 和
connectionDidFinishLoading: 四個相應的方法。
代碼2如下:
view plaincopy to clipboardprint?<br />- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response<br />{<br /> // this method is called when the server has determined that it<br /> // has enough information to create the NSURLResponse<br /> // it can be called multiple times, for example in the case of a<br /> // redirect, so each time we reset the data.<br /> // receivedData is declared as a method instance elsewhere<br /> [receivedData setLength:0];<br />}<br />- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data<br />{<br /> // append the new data to the receivedData<br /> // receivedData is declared as a method instance elsewhere<br /> [receivedData appendData:data];<br />}<br />- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error<br />{<br /> // release the connection, and the data object<br /> [connection release];<br /> // receivedData is declared as a method instance elsewhere<br /> [receivedData release];<br /> // inform the user<br /> NSLog(@"Connection failed! Error - %@ %@",<br /> [error localizedDescription],<br /> [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);<br />}<br />- (void)connectionDidFinishLoading:(NSURLConnection *)connection<br />{<br /> // do something with the data<br /> // receivedData is declared as a method instance elsewhere<br /> NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);<br /> // release the connection, and the data object<br /> [connection release];<br /> [receivedData release];<br />}
同時我們需要在.h檔案中聲明receivedData變數。如果要使本程式運行成功,我想還需要添加一個觸發時間的按鈕button在view上。把代碼1中的內容放入button事件中,相應的程式就會非同步呼叫到http://www.apple.com/
中的內容了。
當然,我們上文的內容還只是寬泛的列出了蘋果文檔中的相應的代碼。如果你想實現自己的service調用的話,首先需要配製自己的伺服器端的servie。本文以作者的建立的service為例,大致更新一下代碼1中的內容。使用的朋友可以相應的參考代碼3。
代碼3如下:
view plaincopy to clipboardprint?<br />- (IBAction)Download:(id)sender<br />{<br /> NSString *table = @"DownloadCity"; </p><p> //NSAutoreleasePool *requestPoll = [[NSAutoreleasePool alloc]init];<br /> NSMutableString *sRequest = [[NSMutableString alloc] init];<br /> // Create the SOAP body<br /> [sRequest appendString:@"<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//">"];<br /> // This is the header section it is expecting in the body<br /> [sRequest appendString:@"<soap:Body>"];<br /> [sRequest appendString:[NSString stringWithFormat:@"<%@ xmlns=/"http://www.MySite.com/webservices/">",table]];<br /> [sRequest appendString:[NSString stringWithFormat:@"</%@>",table]];<br /> [sRequest appendString:@"</soap:Body>"];<br /> [sRequest appendString:@"</soap:Envelope>"];<br /> // create the request<br /> NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://MySiteIP/test.asmx?op=%@",table]]<br /> cachePolicy:NSURLRequestUseProtocolCachePolicy<br /> timeoutInterval:60];<br /> [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[[NSURL URLWithString:[NSString stringWithFormat:@"https://MySiteIP/test.asmx?op=%@",table]] host]];<br /> // Add the Required WCF Header Values. This is what the WCF service expects in the header.<br /> [request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];<br /> [request addValue:[NSString stringWithFormat:@"http://www.MySite.com/webservices/%@",table] forHTTPHeaderField:@"SOAPAction"];<br /> //set the Soap Header: user name and password<br /> [request setValue:@"MyName" forHTTPHeaderField:@"UserName"];<br /> [request setValue:@"MyPassword" forHTTPHeaderField:@"Password"];<br /> // Set the action to Post<br /> [request setHTTPMethod:@"POST"];<br /> // Set the body<br /> [request setHTTPBody:[sRequest dataUsingEncoding:NSUTF8StringEncoding]];<br /> [sRequest release];<br /> // create the connection with the request<br /> // and start loading the data<br /> conn=[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];<br /> if (conn)<br /> {<br /> receivedData=[[NSMutableData data] retain];<br /> }<br /> else<br /> { </p><p> } </p><p> }<br />}
代碼3相應內容需要換成你自己service的相應內容。
相比非同步呼叫,同步調用要簡單的多,但是相應的功能也不入非同步靈活。