Objective-C如何使用 Web 服务之学习系列五

学习摘要:
使用 NSURL 下载文件
通过 XML JSON 使用 Web 服务
解析 XML JSON 数据
通过 NSURLConnection 异步地使用 Web 服务

7.1 下载文件

问题

你想从网上下载文件。

解决方案

使用 NSURL 指定文件的 URL,然后使用 NSData 将文件的内容下载到文件系统中。

注意:

URL 代表的是统一资源定位符(Uniform Resource Locator)URL 是字符串,指定了网上资源的位置。NSURL Foundation 类,可以通过它在 Objective-C 中使用 URL。 


说明

对于本攻略来说,网上必须要有可供下载的文件存在。我在自己的博客上放置了一个文本文件,该文件的 URL 是:

http://howtomakeiphoneapps.com/wp-content/uploads/2012/03/objective-c-recipes-

    example-file.txt

首先要通过待下载资源的 URL 新建 NSURL 对象,使用方才提供 URL,代码如下所示:

NSURL *remoteTextFileURL = [NSURLURLWithString:@"http://howtomakeiphoneapps.com/wp-content/uploads/2012/03/objective-c-recipes-example-file.txt"];

接下来,使用 NSURL 对象的内容新建如下 NSData 对象:

NSData *remoteTextFileData = [NSData dataWithContentsOfURL:remoteTextFileURL];

可以在 Objective-C 程序中使用 NSData 对象(参见 4.11 节以了解如何使用 NSData)或是将其保存到文件系统中,代码如下所示:

[remoteTextFileData writeToFile:@"/Users/Shared/objective-c-recipes-example-file.txt"atomically:YES];

参见程序清单 7-1代码

程序清单7-1 main.m

#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]){

       
       
@autoreleasepool {
NSURL *remoteTextFileURL = [NSURL URLWithString:

@"http://howtomakeiphoneapps.com/wp-content/uploads/2012/03/objective-c-

recipes-example-file.txt"];
NSData *remoteTextFileData = [NSData dataWithContentsOfURL:remoteTextFileURL];[remoteTextFileData writeToFile:@"/Users/Shared/objective-c-recipes-

       
       
example-file.txt" atomically:YES];
}

return 0;}

使用

要想运行上述代码,创建 Mac 命令行 Xcode 项目并将 main.m 文件的内容改为程序清单 7-1 中的代码。构建并运行该命令行应用,将文件下载到自己的 Mac 上:

/Users/Shared/objective-c-recipes-example-file.txt

  如果下载成功,找到并打开文件,查看其中的内容。
       
       

7.2 通过 XML 使用 Web 服务

问题

你想将使用了 XML 数据的 Web 服务添加到应用中。

注意:

互联网公司发布 Web 服务,这样开发者就可以将他们的服务包含到自己的应用中。Web服务的工作方式类似于 Web 浏览器。在 Web 浏览器中,你输入 Web 地址(请求),按下回车键,等待网上远程计算机的响应。当响应返回时,Web 浏览器会使用响应中的规则与内容显示网页。Web 服务的工作方式与之相同,只不过由应用发送请求并接收响应。

互联网公司会尽自己最大努力通过标准格式来规划 Web 服务的请求与响应,使应用能够更轻松地使用他们的服务。Web 请求是字符串(类似于 Web 地址),Web 响应是格式化为XML JSON 的字符串。后面会详细介绍 XML JSON

解决方案

根据 Web 服务发布者提供的文档规划请求字符串。根据请求字符串创建 NSURL 对象与 NSData,从 Web 服务下载响应。使用 NSXMLParser 遍历返回的 XML 文档。

说明

本攻略将会介绍如何使用 bitly 公司提供的 Web 服务。bitly 公司发布了用于缩短 URLWeb 服务。你只需要向 bitly 公司的 Web 服务发送请求,同时传递长 URL 及其所要求格式的 bitly 认证信息即可;bitly 会返回一个 XML 文件,其中的内容包含了缩短后的 URL。 

注意:

你需要创建免费的 bitly 账户并获得自己的 API 键与用户名。请访问 https://bit.ly 以申请账户。 

我打算通过基于命令行的 Mac 应用来讲解本攻略,但可以使用任何类型的项目。由于NSXMLParser 使用了委托设计模式,因此你使用的类需要采用协议并支持委托。通过菜单File | New File | Objective-C class 向项目中添加新类,将新类命名为 LinkShortener

LinkShortener 的接口需要包含名为 recorderString NSMutableString 前置声明,进而记录从 Web 服务获得的数据。LinkShortener 还需要有字符串以记录 XML 解析器当前查找的 XML 文件区域。将那个变量声明为 currentElement,并将 currentElement recorderString设为私有。此外,需要为用于缩短 URL 的函数定义前置声明,将函数声明为 getTheShort-UrlVersionOfThisLongURLLinkShortener 的接口如下所示:

    #import <Foundation/Foundation.h>
              
              
@interface LinkShortener : NSObject{
@private
           NSMutableString *recorderString;
              
              
NSString *currentElement;
}

-(NSString *)getTheShortURLVersionOfThisLongURL:(NSString *)longURL;@end

XML 的解析方式

首先介绍一下什么是 XML 以及 NSXMLParser 如何读取 XML 文档。XML 表示可扩展标记语言(EXtensible Markup Language),用于存储和传输数据。XML 的使用需要通过开始和结束标签来包含数据。开始标签是通过字符<>包围的字符,结束标签是通过字符</>包围的字符。标签与数据总称为元素。

例如,假设存在 Person 这种 XML 数据类型,那么开始标签是<Person>,结束标签是</Person>,中间的字符就是数据。总体看起来代码如下所示:

       <Person>Matthew J. Campbell</Person>

XML 标签具有描述作用,因此标签的含义是显而易见的。整个文档会有多个带有数据的标签,这些标签以层次化的结构组织。可以在其他标签数据中放置标签数据,如下所示:

              
              
<Person>
<Name>Matthew J. Campbell</Name>
<Gender>Male</Gender>

</Person>

NSXMLParser 会从头读取 XML 文档,一个元素接一个元素地读取,直到文档结束为止。如果 NSXMLParser 读取上面的 XML 文档,那么会从 Person 元素开始,然后是 Name 元素,接下来是 Gender 元素。这种用来解析 XML 文档的方式叫做 Simple API for XML(SAX)

我们将会使用委托来解析从 bitly 得到的 XML 数据。由于解析器查询文档中的每个元素,因此会向委托对象 LinkShortener 发送消息,这样就可以从每个元素中提取数据了。

LinkShortener 需要作为 NSXMLParser 的委托,这意味着 LinkShortener 需要采用NSXMLParserDelegate 协议。请将协议名放在父类 NSObject 之后:

#import <Foundation/Foundation.h>
@interface LinkShortener : NSObject <NSXMLParserDelegate> {

              
              
@private
NSMutableString *recorderString;
NSString *currentElement;

}
-(NSString *)getTheShortURLVersionOfThisLongURL:(NSString *)longURL;

@end

既然采用了 NSXML<ParserDelegate>协议,你至少需要实现如下两个委托方法:parser:190 

didStartElement:namespaceURI:qualifiedName:attributes:parser:foundCharacters:。由于应用只需要 XML 文件中某个元素的内容,因此这两个委托方法足矣。但如果有必要,可以实现 parser:didEndElement:namespaceURI:qualifiedName:方法。这样一来,当解

析器遇到 XML 数据的结束标签时,就会通知你。打开 LinkShortener.m,实现第一个委托方法:

              
              
- (void) parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName

namespaceURI:(NSString *)namespaceURIqualifiedName:(NSString *)qName

attributes:(NSDictionary *)attributeDict{currentElement = [elementName copy];
if ([elementName isEqualToString:@"shortUrl"]) {

recorderString = [[NSMutableString alloc] init];

}}

该委托方法会在读到每个新的 XML 元素时执行一次(大多数 XML 文件都有多个元素)。出于这个原因,我们将参数 elementName 复制一份并赋给 currentElement。你希望在其他委托方法执行时能够追踪到当前的元素。

上述代码中的另一个重要之处是 if 语句,你在这里测试当前元素是否是 shortUrlbitly会将缩短后的 URL 字符串放到该元素所在位置。如果遇到 shortUrl 元素,就会创建并初始化新的 NSMutableString 以记录元素中的内容。

现在可以实现下一个委托方法了。该委托方法会在每次遇到文件中 XML 元素的数据时执行。可以测试 XML 解析器是否位于 shortUrl 元素中,如果是,就将遇到的字符附加到 NSMutableString 对象 recorderString 的后面:

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{if ([currentElement isEqualToString:@"shortUrl"])

[recorderString appendString:string];

}

以上做法会让 LinkShortener 准备开始接收 XML 数据。现在可以准备请求并将请求发送给 Web 服务器以下载响应。所有这些都位于函数 getTheShortUrlVersionOfThisLongURL:中,可以开始在 LinkShortener 实现文件中进行编码了:

-(NSString *)getTheShortUrlVersionOfThisLongURL:(NSString *)longURL{}

首先构造请求字符串。需要根据 bitly 需要的请求字符串、longURL 参数和自己的 API键与 API 登录来构建字符串:

#warning Get your API Login from https://bitly.com/a/your_api_key and putit here before running

NSString *APILogin = @"[YOUR API LOGIN]";
#warning Get your API key from https://bitly.com/a/your_api_key and put ithere before running

NSString *APIKey = @"[YOUR API KEY]";
NSString *requestString = [[NSString alloc] initWithFormat:@"http://api.bit.ly/shorten?version=2.0.1&longUrl=%@&login=%@&apiKey=%@&format=xml",

     longURL, APILogin, APIKey];

我已经在示例代码中写了警告,这样你就知道此处应该使用自己的认证信息。此外,如果仔细查看请求字符串的第一部分,你就会发现有个 format 参数,其值是xml(format=xml)。通过 format 参数,告诉 bitly 响应要以 XML 的格式返回。

接下来需要创建 NSURL 对象,可以根据请求字符串来创建 NSURL 对象: NSURL *requestURL = [NSURL URLWithString:requestString]; 要想下载数据,请按照 7.1 节那样使用 NSData :
recorderString = nil;

NSData *responseData = [NSData dataWithContentsOfURL:requestURL];

这里将 recorderString 设为 nil 是为了防止该函数在对象的生命周期前被使用。既然下载了数据,因而可以使用 NSXMLParser 遍历 XML 并获取到 shortUrl 元素中的数据。

为了做到这一点,使用下载的 NSData 对象实例化新的 NSXMLParser,将 NSXMLParser对象的 delegate 设为 self,然后向 NSXMLParser 对象发送 parse 消息:

NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:responseData];xmlParser.delegate = self;
[xmlParser parse];

现在,XML 解析器会遍历数据并使用之前编写的委托方法获取有意义的内容。XML解析器找到的所有内容都会记录在 recorderString 中。一旦 XML 解析器遍历完毕,你就可以将结果返回给调用者:

                 
                 
if(recorderString)
return [recorderString copy];
                 
                 
else
return nil;

如果找到数据,就可以通过 if 语句发送 recorderString 的副本。

最后,要想使用程序另一部分的功能,需要导入 LinkShortener 头文件,实例化LinkShortener 对象,然后使用带有长 URL 的函数版本。下面的 main.m 展示了如何实现:

                 
                 
#import <Foundation/Foundation.h>
#import "LinkShortener.h"
                 
                 
int main(int argc, const char * argv[]){
@autoreleasepool {

NSString *longURL = @"http://howtomakeiphoneapps.com/how-to-asynchronously-add-web-content-to-uitableview-in-ios/1732/";

LinkShortener *linkShortener = [[LinkShortener alloc] init];NSString *shortURL = [linkShortener

getTheShortURLVersionOfThisLongURL:longURL];

                  
                  
NSLog(@"shortURL = %@", shortURL);
}

return 0;}

参见程序清单 7-2~7-4代码

程序清单7-2 LinkShortener.h

    #import <Foundation/Foundation.h>

@interface LinkShortener : NSObject<NSXMLParserDelegate>{@private

       NSMutableString *recorderString;
                  
                  
NSString *currentElement;
}

-(NSString *)getTheShortURLVersionOfThisLongURL:(NSString *)longURL;

@end
程序清单 7-3 LinkShortener.m

                  
                  
#import "LinkShortener.h"
@implementation LinkShortener

-(NSString *)getTheShortURLVersionOfThisLongURL:(NSString *)longURL{#warning Get your API Login from https://bitly.com/ and put it here before runningNSString *APILogin = @"[YOUR API LOGIN]";
#warning Get your API key from https://bitly.com/ and put it here before runningNSString *APIKey = @"[YOUR API KEY]";

NSString *requestString = [[NSString alloc] initWithFormat:@"http://api.bit.ly/shorten?version=2.0.1&longUrl=%@&login=%@&apiKey=%@&format=xml",
longURL, APILogin, APIKey];

NSURL *requestURL = [NSURL URLWithString:requestString];recorderString = nil;
NSData *responseData = [NSData dataWithContentsOfURL:requestURL];NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:responseData];xmlParser.delegate = self;
[xmlParser parse];

                  
                  
if(recorderString)
return [recorderString copy];
                  
                  
else
return nil;;

- (void) parser:(NSXMLParser *)parserdidStartElement:(NSString *)elementNamenamespaceURI:(NSString *)namespaceURIqualifiedName:(NSString *)qName

attributes:(NSDictionary *)attributeDict{currentElement = [elementName copy];
if ([elementName isEqualToString:@"shortUrl"]) {

recorderString = [[NSMutableString alloc] init];

}}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{if ([currentElement isEqualToString:@"shortUrl"])

                 [recorderString appendString:string];

}

@end
程序清单 7-4 main.m

                  
                  
#import <Foundation/Foundation.h>
#import "LinkShortener.h"
                  
                  
int main(int argc, const char * argv[]){
@autoreleasepool {

NSString *longURL = @"http://howtomakeiphoneapps.com/how-to-asynchronously-add-web-content-to-uitableview-in-ios/1732/";

LinkShortener *linkShortener = [[LinkShortener alloc] init];NSString *shortURL = [linkShortener getTheShortURLVersionOfThisLongURL:longURL];NSLog(@"shortURL = %@", shortURL);

}

return 0;}

代码

要想使用上述 URL 缩短功能,请将头文件导入到使用该功能的类中。接下来从LinkShortener 类实例化 LinkShortener 对象。最后,要想使用该功能,请向 LinkShortener对象发送消息 getTheShortURLVersionOfThisLongURL:并将长 URL 作为参数。如果 Web 请求成功,那么该函数会返回缩短后的 URL;如果失败,会返回 nil。下面是在控制台日志中打印出的内容:

    shortURL = http://bit.ly/yFmJFh

注意:

通过测试可以发现,你从 bitly 接收到的缩短后的 URL 可能与我接收到的不太一样。 


7.3 通过 JSON 使用 Web 服务

问题

你想将使用了 JSON 数据的 Web 服务添加到应用中。 

注意:

JSON XML 的替代方案,很多互联网公司在实现 Web 服务时都会使用 JSONJSON代表 JavaScript Object Notation,用于数据的存储与传输。以 REST(REpresentational StateTransfer)方式实现的 Web 服务会提供 XML JSON 响应数据。其他类型的 Web 服务可能只会提供其中的一种。

解决方案

7.2 节一样,根据 Web 服务发布者提供的文档规划请求字符串。根据请求字符串创建 NSURL 对象并使用 NSData Web 服务下载响应。使用 NSJSONSerialization 解析返回的 JSON 数据。 


注意:

NSJSONSerialization Mac OSX 10.7 iOS 5.0 中才被引入进来。 


说明

本攻略使用同样的 bitly Web 服务,与 7.2 节介绍的过程一样,请求并下载结果。然而,NSJSONSerialization 并没有使用委托,因此无须添加新的文件或类来实现 NSJSONSeriali-zation JSON 解析。

由于无需单独的类,因此可以将用于构建请求字符串的代码放在应用中需要使用 Web服务的地方。如果继续使用命令行 Mac 应用,那么可以将这些代码放在 main.m 文件中。下述代码展示了如何构建请求字符串:

NSString *longURL = @"http://howtomakeiphoneapps.com/how-to-asynchronously-add-web-content-to-uitableview-in-ios/1732/";

#warning Get your API Login from https://bitly.com/ and put it here before runningNSString *APILogin = @"[YOUR API LOGIN]";
#warning Get your API key from https://bitly.com/ and put it here before runningNSString *APIKey = @"[YOUR API KEY]";

NSString *requestString = [[NSString alloc] initWithFormat:@"http://api.bit.ly/shorten?version=2.0.1&longUrl=%@&login=%@&apiKey=%@&format=json", longURL, APILogin, APIKey];

然后,可以使用 NSURL NSData 根据请求字符串获得响应:


注意:

JSON XML 的替代方案,很多互联网公司在实现 Web 服务时都会使用 JSONJSON代表 JavaScript Object Notation,用于数据的存储与传输。以 REST(REpresentational StateTransfer)方式实现的 Web 服务会提供 XML JSON 响应数据。其他类型的 Web 服务可能只会提供其中的一种。


注意:

NSJSONSerialization Mac OSX 10.7 iOS 5.0 中才被引入进来。


NSURL *requestURL = [NSURL URLWithString:requestString];

NSData *responseData = [NSData dataWithContentsOfURL:requestURL];

JSON 解析

接下来介绍如何解析 JSON。相对于 XML 使用的标签数据模式,JSON 根据两种结构来组织内容:名-值对的集合与有序的值列表。JSON 的名-值对集合遵循与 Objective-CNSDictionary 相同的模式,而 JSON 的有序值列表则对应于 Objective-C NSArray

如果查看 JSON 文件,就会看到这些类型的结构是通过花括号而非 XML 文件的标签数据组织的。例如,7.2 节中介绍的 Person 元素的 JSON 版本如下所示:

    {"Person":"Matthew J. Campbell","Gender":"Male"}

由于 JSON 数据是通过这种方式输入的,而且字典与数组结构能很自然地映射到编程语言,因此通常情况下 JSON 更易于解析。稍后就会看到,有个 Foundation 函数可以轻松将 JSON 响应的内容转换为 NSDictionary

首先需要有 NSError 对象,在向 NSJSONSerialization 发送 JSONObjectWithData:options:error:消息时需要传递 NSError 对象:

NSError *error = nil;
NSDictionary *bitlyJSON = [NSJSONSerialization JSONObjectWithData:responseData

                          
                          
options:0
error:&error];

将上述函数的返回结果赋给 NSDictionary 对象,这个对象持有 JSON 数据的内容。要想获得所需内容,只需要访问字典中的各个对象即可。通常情况下,这需要引用嵌套的字典、数组与对象。需要检查响应数据以找到所需内容。下述代码展示了如何从响应数据得到 bitly 的短 URL:

if(!error){
NSDictionary *results = [bitlyJSON objectForKey:@"results"];NSDictionary *resultsForLongURL = [results objectForKey:longURL];NSString *shortURL = [resultsForLongURL objectForKey:@"shortUrl"];NSLog(@"shortURL = %@", shortURL);

}else{

                          
                          
NSLog(@"There was an error parsing the JSON");
}

参见程序清单 7-5代码

程序清单 7-5 main.m
#import <Foundation/Foundation.h>

    int main(int argc, const char * argv[]){

@autoreleasepool {
NSString *longURL = @"http://howtomakeiphoneapps.com/how-to-

asynchronously-add-web-content-to-uitableview-in-ios/1732/";

#warning Get your API Login from https://bitly.com/ and put it herebefore running
NSString *APILogin = @"[YOUR API LOGIN]";
#warning Get your API key from https://bitly.com/ and put it herebefore running

NSString *APIKey = @"[YOUR API KEY]";
NSString *requestString = [[NSString alloc] initWithFormat:

@"http://api.bit.ly/shorten?version=2.0.1&longUrl=%@&login=%@&apiKey=%@&format=json",longURL, APILogin, APIKey];

NSURL *requestURL = [NSURL URLWithString:requestString];
NSData *responseData = [NSData dataWithContentsOfURL:requestURL];NSError *error = nil;
NSDictionary *bitlyJSON = [NSJSONSerialization

                          
                          
JSONObjectWithData:responseData
options:0
                             error:&error];

if(!error){
NSDictionary *results = [bitlyJSON objectForKey:@"results"];NSDictionary *resultsForLongURL = [results

                          
                          
objectForKey:longURL];
NSString *shortURL = [resultsForLongURL
                          
                          
objectForKey:@"shortUrl"];
NSLog(@"shortURL = %@", shortURL);

}else{

NSLog(@"There was an error parsing the JSON");}

}

return 0;}

使用

可以在应用中的任何地方使用上述代码。如果使用 Mac 命令行应用进行测试,那么只需要将上述代码放到 main.m 文件中即可,但需要从 bitly 获得 API 键与登录。通过控制台日志窗口可以查看 Web 服务的请求结果,如下所示:

    shortURL = http://bit.ly/yFmJFh

注意:

JSON 的解析步骤要比 XML 少很多,是处理 Web 服务的首选(如果可用)。然而请注意,Web 服务并非总是使用 JSON,并且只有 Mac OSX 10.7iOS 5 以及它们的更高版本才能使用 JSON。 


7.4 异步地使用 Web 服务

问题

你想以后台处理的方式使用 Web 服务,这样网络活动就不会影响到用户界面了。解决方案

如果想要异步地使用网络或是对网络连接和 Web 请求的使用进行更多控制,那么请使用 NSURLConnection NSURLRequest

说明

首先需要有发送给 Web 服务器的请求字符串。可以使用 Web 服务的请求字符串(就像你在 7.2 7.3 节中所做的那样),甚至还可以放在网页中。对于该例来说,我使用自己的博客的 RSS 源,因为我知道这里能提供一些 XML 数据供下载。

 

注意:

RSS 表示 Really Simple SyndicationRSS 用于发布诸如博客和播客之类的内容。RSS文件通常都是基于 XML 的大文件,而且遵循一些附加规范,这些规范对于发布内容会起到帮助作用。向应用添加 RSS 源是向用户发布信息的一种简单方式,因为大多数博客软件都内置了 RSS 特性。 

本攻略会使用 Mac Cocoa 应用,也可以使用 iOS 应用。但如果使用命令行 Mac 应用,就会遇到问题。这是因为 NSURLConnection 使用的异步方法的执行时间比 Mac 命令行应用的生命周期还要长,所以无法在控制台日志中看到结果。

代码位于 Mac Cocoa 应用的 AppDelegate.m 文件的 applicationDidFinishLaunching:委托方法中。首先需要的是请求字符串(对于该例来说,也就是笔者的博客的 RSS ):

NSString *requestString = @"http://www.howtomakeiphoneapps.com/feed/";

接下来,根据请求字符串构造 NSURL 对象:
NSURL *requestURL = [NSURL URLWithString:requestString]; 使用 requestURL 对象实例化新的 NSURLRequest :

NSURLRequest *request = [[NSURLRequest alloc] initWithURL:requestURLcachePolicy:NSURLRequestReload IgnoringLocalCacheData

                    timeoutInterval:10];

还可以在这里指定请求如何处理缓存与超时间隔。接下来需要创建 NSOperationQueue,用来与 NSURLConnection 一起执行 Web 请求: 

NSOperationQueue *backgroundQueue =[[NSOperationQueue alloc] init]; 

最后,使用类方法异步地执行 Web 请求。这里需要 3 个参数:NSURLRequest 对象、NSOperationQueue 对象与代码块。NSURLConnection 通过代码块可以知道,在获取到数据后该执行哪些代码:

[NSURLConnection sendAsynchronousRequest:requestqueue:backgroundQueue

completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

if(!error){
NSString *requestResults = [[NSString alloc] initWithData:data

encoding:NSStringEncodingConversionAllowLossy];NSLog(@"requestResults=%@", requestResults);

}else

                            
                            
NSLog(@"error=%@", error);
}];

注意:

该特性在 Mac OSX 10.7 iOS 5.0 中才被引入进来。 


仔细查看 completionHandler 块,看看如何处理返回的 NSData 对象。通常情况下,测试 NSError 对象以在处理数据之前判断是否一切正常。这里所做的是将整个 RSS 源写到控制台日志中。但如果想要处理 RSS 源,那么可以创建类似 7.2 节中的 XML 解析器。参见程序清单 7-6~7-8

代码

程序清单7-6 main.m

    #import <Cocoa/Cocoa.h>

int main(int argc, char *argv[]){
return NSApplicationMain(argc, (const char **)argv);

}
程序清单 7-7 AppDelegate.h

    #import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate>@property (assign) IBOutlet NSWindow *window;

@end
程序清单 7-8 AppDelegate.m

    #import "AppDelegate.h"
                         
                         
NSLog(@"error=%@", error);
}];

@implementation AppDelegate
@synthesize window = _window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{

NSString *requestString = @"http://www.howtomakeiphoneapps.com/feed/";NSURL *requestURL = [NSURL URLWithString:requestString];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: requestURL

cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];NSOperationQueue *backgroundQueue =[[NSOperationQueue alloc] init];[NSURLConnection sendAsynchronousRequest:request

queue:backgroundQueuecompletionHandler:^(NSURLResponse *response, NSData *data,

                         
                         
NSError *error) {
if(!error){

NSString *requestResults = [[NSString alloc] initWithData:dataencoding:NSStringEncodingConversionAllowLossy];

}@end

使用

}];

NSLog(@"requestResults=%@", requestResults);}

                         
                         
else{
NSLog(@"error=%@", error);

}

要想尝试本攻略,请将上述代码放到 Mac iOS 应用的应用委托中。通过日志查看Web 下载的数据。要想测试错误处理,请将 Mac 断网并通过日志查看错误对象报告。如果Web 请求成功,控制台日志会打印出如下内容:

requestResults=<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"

xmlns:content="http://purl.org/rss/1.0/modules/content/"xmlns:wfw="http://wellformedweb.org/CommentAPI/"xmlns:dc="http://purl.org/dc/elements/1.1/"xmlns:atom="http://www.w3.org/2005/Atom"xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"xmlns:slash="http://purl.org/rss/1.0/modules/slash/"

>

<channel>
<title>How to Make iPhone Apps</title>
<atom:link href="http://howtomakeiphoneapps.com/feed/" rel="self"

                     type="application/rss+xml" />

...

  可以在应用中的任何地方使用上述代码,但不要妨碍或阻塞用户界面等其他处理。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值