IOS 開發之網路資料下載和JSON解析

來源:互聯網
上載者:User

標籤:

簡介

  在本文中,我將給大家介紹ios中如何運用NSURLConnection從網路上下載資料,以及解析JSON資料格式的資料,還有資料的顯示和圖片非同步下載。

  涉及到的知識點:

  1.NSURLConnection的非同步下載和資料要求方法的封裝。

  2.認識JSON格式和JSON格式的解析使用

  3.資料在模擬器上的顯示和圖片的非同步下載(使用SDWebImage非同步顯示圖片,SDWebImage是一個庫)

注意:

  在ios開發中,無論是資料還是圖片都是使用非同步下載方法,不能使用同步。

 

內容

  首先,要完成一個項目,你得需要素材,圖片,還有網路介面(網路介面其實就一下載資料的網址URL,因為你的app資料是通過網路從服務端請求過來的)

  1.網路下載基礎知識介紹

  (1)手機app網路應用

  玩過智能手機我們都知道,手機裡的app有本地應用和網路應用,說通俗點本地應用就是不需要網路也能使用,而一般,QQ等需要上網才能使用的就是網路應用,這些網路應用是需要網上下載資料才能啟動並執行。這裡我們只講網路應用。

  (2)網路應用的結構程式

  分兩種,一種是用戶端,一種是服務端。需要上網下載資料才能使用的網路應用就是用戶端,而為這個網路應用提供資料服務的就是服務端。

  (3)常見的網路介面模式

  ios網路應用的常見介面一半都是HTTP形式的URL地址,

  例如愛限免應用首頁的資料地址為http://iappfree.candou.com:8080/free/applications/limited?currency=rmb&page=1&category_id=

   在項目中一般使用一些開源庫(開源庫的時候往後再講)通過這種網址下載資料. 例如AFNetworking

  (4)常見資料格式

  iOS開發中常見的資料格式有兩種, 一種是JSON格式, 另外種是XML格式, 相對來說, JSON格式使用的比較多

  (5)app介面開發的一般流程

  ios中開發一個介面,需要介面,介面素材資源,網路介面這三項

  開發的流程一般如下:

  ***1.確定你要開發的步驟,一般可以先擷取資料,即從網路介面中下載資料

  ***2.然後把你下載的資料(JSON或XML資料)進行解析,建立資料模型model,一般用MVC這樣的設計模式來編程開發

  ***3.使用UI控制項顯示這些解析後的資料,一般都需要自訂cell顯示

  2.具體實現步驟  1.使用非同步下載資料的方法 (NSURLConnection非同步下載)把這個方法封裝起來,以後可以代碼複用

  ***1.先說普通簡單狀態下的非同步下載,網路介面以這個為例子

  http://iappfree.candou.com:8080/free/applications/limited?currency=rmb&page=1&category_id=

  

    [self testNSURLConnectionAsyncDownloadData];        //JSON文法    [self jsonFormat];}-(void)jsonFormat{    //JSON    //JavaScript Object Notation        /*    {        "count":20,        "data":[            "zhangsan",            "lisi",            "wangwu"        ]    }    */    //[]    表示數組,對應NSArray    //,     表示並列的資料    //{}    表示字典,對應NSDictionary    //:     表示索引值對    //"ta"  表示字串,對應NSString    //20    對應NSNumber        //JSON格式格式化工具    //  Jason    //  Json Editor    //  線上:  http://www.kjson.com/    }#pragma mark - 非同步下載-(void)testNSURLConnectionAsyncDownloadData{    NSString *urlString = @"http://iappfree.candou.com:8080/free/applications/limited?currency=rmb&page=1&category_id=";        //初始化    _data = [[NSMutableData alloc] init];    //發起了一個非同步URL串連請求    //非同步:   執行了方法之後開始下載,立即返回    //              下載過程在後台(多線程)執行    _connection = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]] delegate:self startImmediately:YES];    NSLog(@"initWithRequest 執行完成");    }

  當使用這個方法的時候,下載的過程就在程式後台進行,遵循 NSURLConnectionDataDelegate 這個協議就能調用相關方法了,比如下載完成後執行的方法,從而完成相關操作

  ***2.下面就是相關方法操作:

  

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{    NSLog(@"接收到那個方法initWithRequest,伺服器響應執行");}//接收到資料就執行這個方法,下載資料-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{    [_data appendData:data];}//資料下載完成後使用的方法,直接看英文意思-(void)connectionDidFinishLoading:(NSURLConnection *)connection{    NSString *str = [[NSString alloc]initWithData:_data encoding:NSUTF8StringEncoding];    NSLog(@"列印下載後的資料%@",str);    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:_data options:NSJSONReadingMutableContainers error:nil];    NSLog(@"%@",dic);    NSArray *arr = dic[@"applications"];    for (NSDictionary *dic2 in arr) {        NSLog(@"name = %@",dic2[@"name"]);    }}

 

  2.通過上面那個簡單的例子,我們認識了NSURLConnection非同步下載,接下來就介紹下非同步下載的封裝

  ***1.建立一個繼承NSObject的類

  ***2.定義一個儲存資料的屬性和處理這些資料的執行個體方法

#import <Foundation/Foundation.h>@interface ZJHttpRequest : NSObject//儲存下載的資料@property (copy,nonatomic) NSMutableData *data;//作用:傳入網址,下載完成後執行target對象中action方法  類比按鈕,點擊執行事件-(void)requestWithUrl:(NSString *)url               target:(id)target               action:(SEL)action;@end

  ***3..m檔案的實現步驟

#import "ZJHttpRequest.h"//消除performSelector的警告#pragma clang diagnostic ignored "-Warc-performSelector-leaks"//類擴充//項目實踐://  有些執行個體變數內部使用, 不想放在標頭檔中, 放在這兒@interface ZJHttpRequest ()<NSURLConnectionDataDelegate>{    NSURLConnection *_connection;    NSString *_url;    id _target;    SEL _action;}@end@implementation ZJHttpRequest//作用://  傳入網址, 下載完成執行後執行target對象中action方法-(void)requestWithUrl:(NSString *)url               target:(id)target               action:(SEL)action{    _url = url;    _target = target;    _action = action;        //發起URL請求    _data = [[NSMutableData alloc] init];    _connection = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]] delegate:self startImmediately:YES];}-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{    [_data appendData:data];}-(void)connectionDidFinishLoading:(NSURLConnection *)connection{    //下載完成了, 執行儲存的方法    if(_target && [_target respondsToSelector:_action])    {        [_target performSelector:_action withObject:self];    }    }@end

  ***4.如果不能很好的理解其中每段代碼代表是意思,可以看看下面我的注釋,如果有錯,非常歡迎各位看官的指教

  

#import "ZJHttpRequest.h"//消除performSelector的警告#pragma clang diagnostic ignored "-Warc-performSelector-leaks"//類擴充//項目實踐://有些執行個體變數內部使用,不想放在標頭檔中,放在這@interface    @end之間@interface ZJHttpRequest ()<NSURLConnectionDataDelegate>{    NSURLConnection *_connection;    NSString *_url;    id _target;    SEL _action;}@end@implementation ZJHttpRequest-(void)requestWithUrl:(NSString *)url               target:(id)target               action:(SEL)action{    _url = url;//把傳過來的參數網址URL,賦給新建立的 NSString *_url對象    _target = target;//傳過來的參數target   target    QFPXViewController *    0x8cea970    0x08cea970    _action = action;//傳過來的參數action    SEL    "dealDowloadFinish:"    0x00009a4f    _data = [[NSMutableData alloc]init];    //NSURLConnection非同步下載,執行了這個方法就在後台下載了    _connection = [[NSURLConnection alloc]initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]] delegate:self startImmediately:YES];//_connection    NSURLConnection *    0x8d79720    0x08d79720   記住,這個是非同步下載,當程式執行了這個方法後,下載資料就變成在後台下載了,(多線程),所以之後requestWithUrl之後就已經在下載資料,然後建立表格,表格則遵循協議,調用那兩個方法,返回資料行數,而在NSURLConnection非同步下載中,也需要遵循協議,就會有你下載了資料後可以執行這個方法didReceiveData        //程式走向就是,當在QFPXViewController,執行這個封裝的方法的時候,會把相應的參數傳過來,或者說,在QFPXViewController,調用了封裝的方法,就跑到這個封裝的方法中  --requestWithUrl,    //然後,建立表格,而後擷取資料,return _dataArray.count 後就到了下面這裡didReceiveData,            }-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{    //data    __NSCFData *    17088 bytes    0x08d8e140   17088位元組    [_data appendData:data];  //appendData 附加資料    //_data    NSConcreteMutableData *    17088 bytes    0x08d67980  _data也得到了這麼多位元組}-(void)connectionDidFinishLoading:(NSURLConnection *)connection{    //接收完資料了,已經下載完成,然後判斷傳過來的target和action這兩個參數有沒有賦給_target和_action,或者說_target和_action是不是空的,一個保障手段方法,如果傳過來了,就符合if判斷語句,則執行裡面的方法,也就是程式的邏輯思維裡,那邊QFPXViewController傳過來兩個參數,然後在這裡封裝的類ZJHttpRequest裡用非同步下載,下載完資料後判斷,是否傳了參數過來,如果不為空白的話就響應執行    //_action帶過來的方法dealDowloadFinish:,也就是再跳到那個類寫的方法裡,處理資料,這就是封裝了方法的一個作用,其實就是非同步請求下載資料,下載後再來個參數判斷,至於下載後的資料處理還是“彷彿“在QFPXViewController中處理,其實只不過是在QFPXViewController中寫處理常式邏輯而已    //self    ZJHttpRequest *    0x8c593c0    0x08c593c0    //_target    QFPXViewController *    0x8ce52b0    0x08ce52b0    //_action    SEL    "dealDowloadFinish:"    0x00009a4f    //_target是否為空白並且_target能否響應_action    if (_target && [_target respondsToSelector:_action]) {        //判斷傳過來參數了則執行這裡面帶過來的方法,執行了帶過來的方法dealDowloadFinish,則跳到這個方法裡         [_target performSelector:_action withObject:self];//這段代碼的意思就是讓這個類QFPXViewController  執行perform這個選擇的方法_action(dealDowloadFinish)用這個類self帶的參數    }       }@end

  這樣,我們就把這個非同步下載的方法封裝好了,下次就直接調用就可以了,引入標頭檔,建立該標頭檔對象,調用封裝的執行個體方法,傳過去參數,執行,並返回執行帶過去處理資料的方法。

- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.        //資料介面    NSString *urlString = @"http://iappfree.candou.com:8080/free/applications/limited?currency=rmb&page=1&category_id=";        _dataArray = [[NSMutableArray alloc] init];        //下載    _request = [[ZJHttpRequest alloc] init];    [_request requestWithUrl:urlString target:self action:@selector(dealDowloadFinish:)];        [self createTableView];}
- (void)viewDidLoad{    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.    //資料介面  網路介面    NSString *urlStr = @"http://iappfree.candou.com:8080/free/applications/limited?currency=rmb&page=1&category_id=";        _dataArray = [[NSMutableArray alloc]init];                //下載    _request = [[ZJHttpRequest alloc]init];    //self  self    QFPXViewController *    0x8cea970    0x08cea970    //urlStr    __NSCFConstantString *    @"http://iappfree.candou.com:8080/free/applications/limited?currency=rmb&page=1&category_id="    0x000106d4    //調用這個ZJHttpRequest類對象的要求方法,方法requestWithUrl已經是類ZJHttpRequest封裝好的,所有,你在這裡self    QFPXViewController *調用的話就是把當前的target,action這兩個參數還有網址URL傳入self  ZJHttpRequest這個類中    [_request requestWithUrl:urlStr target:self action:@selector(dealDowloadFinish:)];            [self createTabelView];        }

 

  下面是處理資料的方法dealDowloadFinish

//這個方法都相當於放在viewWillAppear裡面了,因為程式的走向是先下面這裡的方法,再給表返回return _dataArray.count;所以重新整理資料就在這裡重新整理-(void)dealDowloadFinish:(ZJHttpRequest *)request{    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:request.data options:NSJSONReadingMutableContainers error:nil];   // NSLog(@"dic = %@",dic);    NSArray *appList = dic[@"applications"];    for (NSDictionary *dic in appList) {        AppModel *model = [[AppModel alloc]init];        model.applicationId = dic[@"applicationId"];        model.name = dic[@"name"];        model.iconUrl = dic[@"iconUrl"];        [_dataArray addObject:model];    }    [_tabelView reloadData];}

 

  3.來到這裡,就順勢說到JSON資料格式的解析

  1.相信解析過JSON資料格式的朋友都知道,就有個Jason軟體非常好用,使用也很簡單

    ***1.通過網路介面得到未經處理資料,然後全選中這些資料,黏貼到

 

  com+v然後就回彈出這麼個視窗

 

  接著我們點擊左上方的Text就得到我們想要的格式化好後的JSON資料了

 

  4.接下來就是認識學習JSON資料格式,這樣就能完成以後的資料解析操作
    [self jsonFormat];}-(void)jsonFormat{    //JSON    //JavaScript Object Notation        /*    {        "count":20,        "data":[            "zhangsan",            "lisi",            "wangwu"        ]    }    */    //[]    表示數組,對應NSArray    //,     表示並列的資料    //{}    表示字典,對應NSDictionary    //:     表示索引值對    //"ta"  表示字串,對應NSString    //20    對應NSNumber        //JSON格式格式化工具    //  Jason    //  Json Editor    //  線上:  http://www.kjson.com/    }
  5.資料擷取,解析完後就用自訂cell來顯示

  1.用的石MVC程式設計模式來實現,建立一個基礎NSObject的資料類和基礎於UITableViewCell的自訂的cell,以下是部分代碼

       [self createTabelView];        }-(void)createTabelView{    _tabelView = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStylePlain];    _tabelView.dataSource = self;    _tabelView.delegate = self;    [self.view addSubview:_tabelView];}-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{    //   return _dataArray.count;後返回高度,返回了_dataArray.count次    return 80;}-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    return _dataArray.count;}-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    static NSString *identifer = @"cell";    //資料有10行,但是這裡的判斷顯示是建立了7個cell,顯示6個    AppCell *cell = [tableView dequeueReusableCellWithIdentifier:identifer];    if (cell == nil) {        cell = [[AppCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifer];    }    AppModel *model = _dataArray[indexPath.row];        //cell.textLabel.text = model.name;    cell.nameLabel.text = model.name;            [cell.iconImageView setImageWithURL:[NSURL URLWithString:model.iconUrl]];    return cell;        }

 

 

  6.完成

         7.圖片的下載實現用的是SDWebImage這個庫裡的方法

  1.選擇工程,點Build Phases,搜尋SDW,得到所有sd開頭的檔案

  2.全選擇,靠右邊雙擊彈出一個框,輸入-fno-objc-arc,使用這個模式

  3.然後再在實現的類下引入標頭檔#import "UIImageView+WebCache.h"

  4.最後,用這個方法實現圖片的載入顯示

  [cell.iconImageView setImageWithURL:[NSURL URLWithString:model.iconUrl]];

 

  總結:實現一個項目工程,簡單的介面顯示

  一.拿到介面素材,網路介面

  二.擷取資料,解析資料

  三.顯示資料

  其中NSURLConnection非同步下載和方法封裝,以及JSON資料的解析都是重點,實現的關鍵 

 

 

IOS 開發之網路資料下載和JSON解析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.