標籤:
1、概述
JSON
(1) 作為一種輕量級的資料交換格式,正在逐步取代XML,成為網路資料的通用格式
(2) 基於JavaScript的一個子集
(3) 易讀性略差,編碼手寫難度大,資料量小
(4) JSON格式取代了XML給網路傳輸帶來了很大的便利,但是卻沒有了XML的一目瞭然,尤其是JSON資料很長的時候,我們會陷入繁瑣複雜的資料節點尋找中
XML
(1)可延伸標記語言 (XML)
(2)用於標記電子檔案使其具有結構性的標記語言,可以用來標記資料、定義資料類型,是一種允許使用者對自己的標記語言進行定義的源語言
(3)易讀性高,編碼手寫難度小,資料量大
用戶端與伺服器資料轉送:
2、JSON格式說明
n 對象
n {}
n 格式 {key : value, key : value,...} 的索引值對的結構
n 可以還原序列化為OC中的NSDictionary
n 數組
n []
n 格式 ["java","javascript","vb",...]
n 可以還原序列化為OC中的NSArray
n 提示
n JSON的資料格式與OC中的快速封裝方法非常類似
n JSON的資料格式同樣支援嵌套
3、解析伺服器端返回JSON資料
n 從iOS 5開始,使用NSJSONSerialization對JSON解析
n 其他常見的三種JSON解析第三方庫:
n SBJson 因為API簡單易用,可能還會有一些應用中留存
n JSONKit JSONKit的開發人員稱:JSONKit的效能優於蘋果
n TouchJson
4、JSON的序列化和還原序列化
還原序列化
[NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
例如:
- (void)getLogon2
{
[self.view endEditing:YES];
// 1. URL
NSString *urlStr =
[NSString stringWithFormat:@"http://192.168.40.2/
login.php?username=%@&password=%@", self.userName.text, self.userPwd.text];
// 如果URL中包含中文字元或者特殊字元,例如空格,需要添加百分比符號轉義
urlStr =
[urlStr stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlStr];
// 2. NSURLRequest
/**
參數:
timeoutInterval:開發中一定要指定逾時時間長度,預設60秒,通常靠考慮到使用者的網路環境,可以設定到10~20秒,不能太長,也不能太短
*/
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:5.0f];
// 3. 發送非同步請求
[NSURLConnection sendAsynchronousRequest:request queue:
[[NSOperationQueue alloc] init] completionHandler:
^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError) {
[self showAlertViewWithMsg:@"網路不給力"];
return;
} else {
// 將接收到的位元據還原序列化為資料字典
NSDictionary *dict =
[NSJSONSerialization JSONObjectWithData:data
options:nil error:NULL];
LoginUser *user = [[LoginUser alloc] initWithDict:dict];
// 如果使用者有頭像就載入頭像
if (user.userImage) {
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image =
[user loadImageWithURL:user.userImage];
});
}
// 使用者登入錯誤?不會網路連接失敗!
if (!user.userId) {
[self showAlertViewWithMsg:@"使用者名稱或者密碼不正確"];
return;
}
[[NSOperationQueue mainQueue]
addOperationWithBlock:^{
self.logonResult.text = @"登入完成";
}];
}
}];
}
序列化
[NSJSONSerialization dataWithJSONObject:array options:0 error:NULL];
5、NSXMLParser
1、NSXMLParser解析方法
n NSXMLParser是SAX方法解析
n SAX(Simple API for XML)
n 只能讀,不能修改,只能順序訪問,適合解析大型XML,解析速度快
n 常應用於處理大量資料的XML,實現異構系統的資料訪問,實現跨平台
n 從文檔的開始通過每一節點移動,定位一個特定的節點
n DOM(Document Object Model)
n 不僅能讀,還能修改,而且能夠實現隨機訪問,缺點是解析速度慢,適合解析小型文檔
n 一般應用與小型的配置XML,方便操作
n 為載入到記憶體的文檔節點建立類型描述,呈現可橫向移動、潛在巨大的樹型結構
n 在記憶體中產生節點樹操作代價昂貴
1、 解析步驟:
【備忘】屬性:
@property (nonatomic, strong) NSMutableArray *dataList;
// 來回拼接
@property (nonatomic, strong) NSMutableString *elementString;
// 當前視頻資訊的對象
@property (nonatomic, strong) Video *v;
還要遵守代理協議:NSXMLParserDelegate
範例程式碼:
- (IBAction)loadData
{
// 1. URL
NSURL *url =
[NSURL URLWithString:@"http://localhost/videos.php"];
// 2. Request
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:10.0f];
// 3. 發送請求
[NSURLConnection sendAsynchronousRequest:request queue:
[[NSOperationQueue alloc] init]completionHandler:
^(NSURLResponse *response, NSData *data, NSError *connectionError) {
//第一步:執行個體化NSXMLParser,傳入從伺服器接收的XML資料
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
//第二步:定義解析器代理
parser.delegate = self;
//第三步:解析器解析
[parser parse];
}];
}
//第四步:通過解析代理方法完成XML資料的解析
#pragma mark 1. 開始
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
// 準備工作
// 1> dataList
if (!self.dataList) {
self.dataList = [NSMutableArray array];
} else {
[self.dataList removeAllObjects];
}
// 2> elementString
if (!self.elementString) {
self.elementString = [NSMutableString string];
} else {
// 清空可變字串不要設定成nil,使用setString只是清空內容,下次不會再次執行個體化
[self.elementString setString:@""];
}
}
#pragma mark 2. 所有開始一個節點:<element>
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
// 如果是<video>建立對象
if ([elementName isEqualToString:@"video"]) {
self.v = [[Video alloc] init];
self.v.videoId = attributeDict[@"videoId"];
}
// 每開始一個新節點之前都清空elementString
// 避免上一次的結果被重複拼接
[self.elementString setString:@""];
}
#pragma mark 3. 尋找內容,可能會重複多次
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
// 拼接字串
[self.elementString appendString:string];
}
#pragma mark 4. 節點結束 </element>
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSLog(@"結束節點 %@", elementName);
// 判斷如果是<name>要複製
if ([elementName isEqualToString:@"video"]) {
[self.dataList addObject:self.v];
} else if (![elementName isEqualToString:@"videos"]) {
[self.v setValue:self.elementString forKey:elementName];
}
}
#pragma mark 5. 文檔結束
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(@"解析結束 %@ %@", self.dataList, [NSThread currentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
// 關閉重新整理控制項的重新整理
[self.refreshControl endRefreshing];
});
}
#pragma mark 6. 出錯處理
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
NSLog(@"%@", parseError.localizedDescription);
}
3、NSXMLParser解析代理方法
// 1. 開始解析XML文檔
- (void)parserDidStartDocument:
// 2. 開始解析某個元素,會遍曆整個XML,識別元素節點名稱
- (void)parser:didStartElement:namespaceURI:qualifiedName:attributes:
// 3. 文本節點,得到文本節點裡儲存的資訊資料,對於大資料可能會接收多次!為了節約記憶體開銷
- (void)parser:foundCharacters:
// 4. 結束某個節點,儲存從parser:foundCharacters:方法中擷取到的資訊
- (void)parser:didEndElement:namespaceURI:qualifiedName:
注意:在解析過程中,2、3、4三個方法會不停的重複執行,直到遍曆完成為止
// 5. 解析XML文檔結束
- (void)parserDidEndDocument:
// 6. 解析出錯
- (void)parser:parseErrorOccurred:
iOS開發之JSON & XML