国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

IOS開發(fā)之新浪圍脖

2019-11-14 20:04:13
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

  IOS開發(fā)和Web開發(fā)一樣,網(wǎng)絡(luò)請(qǐng)求方式包括Get和Post方式。Get和Post兩者有和特點(diǎn)和區(qū)別,在本篇博客中不做過(guò)多的論述,本篇的重點(diǎn)在于如何GET數(shù)據(jù)和POST數(shù)據(jù)。下面還會(huì)提到如何在我們的項(xiàng)目中使用CocoaPods, CocoaPods的安裝和使用教程請(qǐng)參考鏈接http://code4app.com/article/cocoapods-install-usage。上面詳細(xì)的介紹了CocoaPods的安裝過(guò)程和如何通過(guò)CocoaPods引入第三方類庫(kù)。在本篇博客中提到CocoaPods,是因?yàn)槲覀冃枰肅ocoaPods來(lái)引入AFNetWorking,然后在網(wǎng)絡(luò)請(qǐng)求中使用AFNetWorking來(lái)實(shí)現(xiàn)我們圖片的提交。

  下面用的API是由新浪微博提供的官方API,鏈接地址:http://open.weibo.com/wiki/微博API, 想使用新浪微博的API首先得注冊(cè)成開發(fā)者獲取一個(gè)和自己新浪微博綁定的access_token,我們可以通過(guò)這個(gè)令牌來(lái)使用新浪微博提供的API.

  1.Get方式的請(qǐng)求

    (1)下面會(huì)使用公共服務(wù)的國(guó)家,省份,和城市的接口,來(lái)學(xué)習(xí)一下GET請(qǐng)求方式

    (2)我們要完成什么要的任務(wù)呢?少說(shuō)點(diǎn)吧,上幾張圖最為直接

    (3)上面的數(shù)據(jù)是通過(guò)API獲取的,獲取完后再顯示在我們的tableView中,將會(huì)提供一些關(guān)鍵的實(shí)現(xiàn)代碼,準(zhǔn)備工作是新建三個(gè)TabelViewController然后配置相應(yīng)的cell。下面就以第一個(gè)TableView為例,因?yàn)楹髢蓚€(gè)和第一個(gè)差不多,所以就不做贅述,下面是網(wǎng)路請(qǐng)求的關(guān)鍵代碼:

 1     //網(wǎng)絡(luò)請(qǐng)求用的API 2     NSString *urlString = @"https://api.weibo.com/2/common/get_country.json?access_token=你自己的access_token"; 3      4     //把urlString轉(zhuǎn)換成url 5     NSURL *url = [NSURL URLWithString:urlString]; 6      7     //創(chuàng)建URL請(qǐng)求 8     NSURLRequest *request = [NSURLRequest requestWithURL:url]; 9     10     //copy_self在Block中使用,避免強(qiáng)引用循環(huán)11     __weak __block ChinaTableViewController *copy_self = self;12     13     //執(zhí)行請(qǐng)求14     [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {15         16         //連接失敗時(shí)17         if (connectionError) {18             NSLog(@"%@", [connectionError localizedDescription]);19             return ;20         }21         22         23         NSError *error = nil;24         //把json轉(zhuǎn)換成數(shù)組25         copy_self.dataSource = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];26         27         //轉(zhuǎn)換失敗28         if (error) {29             NSLog(@"%@", [error localizedDescription]);30             return;31         }32         33         //tableView的重載34         [copy_self.tableView reloadData];35         36     }];

    代碼說(shuō)明:

      1.創(chuàng)建要請(qǐng)求的API,根據(jù)你要獲取的數(shù)據(jù)參考API來(lái)拼接你要的URL.

      2.根據(jù)拼接的URL來(lái)創(chuàng)建URL請(qǐng)求對(duì)象;

      3.發(fā)送請(qǐng)求,上面用的是異步請(qǐng)求方式,同步請(qǐng)求會(huì)阻塞線程。

      4.在block回調(diào)中把返回的JSON解析成數(shù)組并加載到我們的表示圖

  

    (4).把數(shù)據(jù)顯示在表視圖上

 1 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 2 { 3     return 1; 4 } 5  6 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 7 { 8     return self.dataSource.count; 9 }10 11 12 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath13 {14     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];15     16     NSString *key = [NSString stringWithFormat:@"%03d",indexPath.row+1];17     cell.textLabel.text = self.dataSource[indexPath.row][key];18     19     20     return cell;21 }

    

    (5)因?yàn)樵谙乱粋€(gè)頁(yè)面要請(qǐng)求數(shù)據(jù)的時(shí)候得用到第一個(gè)頁(yè)面的數(shù)據(jù),也就是在請(qǐng)求省份的時(shí)候得知道國(guó)家的編碼,所以要把國(guó)家的編碼傳到第二個(gè)頁(yè)面中,第三個(gè)頁(yè)面和第二個(gè)頁(yè)面也是類似。下面是通過(guò)KVC傳值的代碼

 1 // In a storyboard-based application, you will often want to do a little PReparation before navigation 2 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 3 { 4      5     UITableViewCell *cell = sender; 6      7     //獲取點(diǎn)擊Cell的索引 8     NSIndexPath * indexPath = [self.tableView indexPathForCell:cell]; 9     10     //獲取請(qǐng)求的數(shù)據(jù)11     NSDictionary *dic = self.dataSource[indexPath.row];12     13     id vc = [segue destinationViewController];14     [vc setValue:dic forKey:@"country"];15     16 }

   后兩個(gè)顯示頁(yè)面和上面的代碼相似,在這就不做贅述,Get數(shù)據(jù)的關(guān)鍵是讀懂API,通過(guò)API獲取你想要的數(shù)據(jù)

 

  2.POST請(qǐng)求方式

    我們下面通過(guò)調(diào)用新浪微博發(fā)微博的API來(lái)了解一下通過(guò)POST提交表單中的數(shù)據(jù),在用第三方的類庫(kù)AFNetWorking來(lái)提交圖片,至于發(fā)微博的API如何使用請(qǐng)參照新浪官方的API開發(fā)文檔。

    (1)通過(guò)POST提交純表單數(shù)據(jù)

      a.用POST方式提交,不需要往URL中拼接參數(shù),首先我們要獲取url(API中提供的發(fā)布微博的URL,下面用的宏定義的URL)

    //獲取url    NSURL *url = [NSURL URLWithString:SendMessage];

      b.通過(guò)URL創(chuàng)建一個(gè)可變的請(qǐng)求:

    //創(chuàng)建POST請(qǐng)求    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

       c.把請(qǐng)求方式設(shè)置成POST

     //設(shè)置POST請(qǐng)求    [request setHTTPMethod:@"POST"];

       d.拼接要提交的參數(shù)

    //拼接要POST提交的字符串    NSString *string = [NSString stringWithFormat:@"access_token=%@&status=%@", access_token, self.blogTextField.text];

      e.在網(wǎng)絡(luò)傳輸中我們使用的時(shí)二進(jìn)制所以要轉(zhuǎn)換成NSData類型

   //把string轉(zhuǎn)變成NSData類型    NSData *bodyData = [string dataUsingEncoding:NSUTF8StringEncoding];

      f.把參數(shù)添加到請(qǐng)求中

  //把bodyData添加到request中    request.HTTPBody = bodyData;

    g.發(fā)送請(qǐng)求

    //執(zhí)行request    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {        NSError *error;        NSDictionary *dic =[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];        if (error) {            NSLog(@"%@", [error localizedDescription]);        }        NSLog(@"%@", dic);    }];

 

  到此微博發(fā)送成功,會(huì)在我們自己的新浪微博的主頁(yè)中顯示我們?cè)谀M器中的文本輸入的東西了,因?yàn)槲姨砑拥膽?yīng)用的access_token沒有申請(qǐng)審核,所以會(huì)顯示“來(lái)自未通過(guò)審核應(yīng)用”,截圖如下:

 

  2.我們?nèi)绾瓮ㄟ^(guò)調(diào)用可以發(fā)圖片的API上傳本地圖片呢?為了簡(jiǎn)化我們APP的圖片的上傳,我們就得用到AFNetWorking中的東西了,如何配置和使用CocoaPods請(qǐng)參考上面的鏈接。

    a.用AFHTTPRequestOperationManager來(lái)組織我們的數(shù)據(jù),數(shù)據(jù)是存儲(chǔ)在字典中的

      NSDictionary *dic = @{@"access_token": access_token, @"status":self.blogTextField.text};

    

    b.獲取請(qǐng)求操作,并傳入字典,POST后面跟的時(shí)API中提供的URL。 self.manager是我們之前定義的屬性@property (strong, nonatomic) AFHTTPRequestOperationManager * manager; 并在viewDidLoad中分配內(nèi)存

    AFHTTPRequestOperation *op = [self.manager POST:SendImage parameters:dic constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {        //把圖片轉(zhuǎn)換成NSData類型的數(shù)據(jù)        NSData *imageData = UIImagePNGRepresentation(self.buttonImage.imageView.image);
//把圖片拼接到數(shù)據(jù)中 [formData appendPartWithFileData:imageData name:@"pic" fileName:@"123" mimeType:@"image/png"]; } success:^(AFHTTPRequestOperation *operation, id responSEObject) { NSLog(@"%@", responseObject); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"%@",[error localizedDescription]); }];

    

    c.得啟動(dòng)才可提交

    //配置解析過(guò)程    op.responseSerializer = [AFCompoundResponseSerializer serializer];    //啟動(dòng)請(qǐng)求    [op start];

  效果如下:

 

  3.如果我們的圍脖到這那不太簡(jiǎn)單了蠻,如果到這就結(jié)束的話,下面又該有小伙伴評(píng)論“這有什么意義呢?”,下面就請(qǐng)求一下我的圍脖的內(nèi)容,點(diǎn)進(jìn)去是本條圍脖的評(píng)論,效果圖如下:

  上面的內(nèi)容是用新浪微博提供的API用我自己的token請(qǐng)求的內(nèi)容,和我登陸圍脖賬號(hào)的首頁(yè)是一樣的數(shù)據(jù),點(diǎn)進(jìn)去是該微博的所有評(píng)論,當(dāng)然啦,上面為了省事,我們用Cell是在Storyboard中設(shè)置的。真正實(shí)現(xiàn)起來(lái)需要新建TableViewCell根據(jù)數(shù)據(jù)來(lái)定制我們想要的cell, 之后在TableViewController中進(jìn)行注冊(cè)一下就可以用了。獲取微博內(nèi)容的代碼和上面國(guó)家的代碼類似,在這就不往上貼代碼了。我們往cell中添加網(wǎng)絡(luò)請(qǐng)求的圖片時(shí)用的時(shí)AFNetWorking中的UIKit+AFNetworking.h類目,大大簡(jiǎn)化了我們網(wǎng)絡(luò)請(qǐng)求圖片的操作。設(shè)置圖片的代碼如下:

1     NSURL *url = [NSURL URLWithString:dic[@"user"][@"profile_image_url"]];2     [cell.imageView setImageWithURL:url];

 

  如果你感覺到這這篇博文就結(jié)束啦?不可能的啦!!上面的博文都顯示不出來(lái),還有發(fā)布時(shí)間,圖片等最基本的信息都沒有。在之前的博客中有一篇“IOS開發(fā)之自動(dòng)布局顯示網(wǎng)絡(luò)請(qǐng)求內(nèi)容” ,用的網(wǎng)絡(luò)請(qǐng)求是模擬的微博請(qǐng)求,博文的內(nèi)容也是模擬的,接下來(lái)要用到上一篇博文的知識(shí):根據(jù)請(qǐng)求內(nèi)容來(lái)動(dòng)態(tài)的設(shè)置Cell的高度。下面就讓我們自定義兩種Cell來(lái)把上面的TableView完善一下吧:

  1.創(chuàng)建兩種Cell,并給Cell中的各個(gè)控件設(shè)置約束

  2.上面的cell是我們自定義的cell,需要關(guān)聯(lián)兩個(gè)UITableViewCell類,然后在Cell對(duì)象中進(jìn)行控件的配置和賦值,其中的一個(gè)自定義Cell的關(guān)鍵代碼如下,在TableView中我們只需要調(diào)用setCellContent方法把存有數(shù)據(jù)的字典傳到cell中中由cell賦值即可:

 1 @interface TextTableViewCell() 2  3 @property (strong, nonatomic) IBOutlet UIImageView *image; 4  5  6 @property (strong, nonatomic) IBOutlet UILabel *titleLable; 7 @property (strong, nonatomic) IBOutlet UILabel *dateLabel; 8 @property (strong, nonatomic) IBOutlet UILabel *contentLable; 9 10 @end11 12 @implementation TextTableViewCell13 14 -(void)setCellContent:(NSDictionary *)dic15 {16     17     NSDateFormatter *iosDateFormater=[[NSDateFormatter alloc]init];18     iosDateFormater.dateFormat=@"EEE MMM d HH:mm:ss Z yyyy";19     //必須設(shè)置,否則無(wú)法解析20     iosDateFormater.locale=[[NSLocale alloc]initWithLocaleIdentifier:@"en_US"];21     NSDate *date=[iosDateFormater dateFromString:dic[@"created_at"]];22     23     //目的格式24     NSDateFormatter *resultFormatter=[[NSDateFormatter alloc]init];25     [resultFormatter setDateFormat:@"MM月dd日 HH:mm"];26     27     self.dateLabel.text = [resultFormatter stringFromDate:date];28 29     self.titleLable.text = dic[@"user"][@"name"];30     31     self.contentLable.text = dic[@"text"];32     33     NSURL *imgURL = [NSURL URLWithString:dic[@"user"][@"profile_image_url"]];34     [self.image setImageWithURL:imgURL];35     36 }

 

  3、我們需要在原來(lái)顯示微博的TableView中根據(jù)請(qǐng)求的數(shù)據(jù)來(lái)選擇用哪一個(gè)Cell,選擇代碼如下:

 1 //選擇判斷用哪個(gè)cell 2 -(UITableViewCell *)selectCell:(NSDictionary *)dic cellForRowAtIndexPath:(NSIndexPath *)indexPath 3 { 4     UITableViewCell *cell = nil; 5      6     //根據(jù)下面是否有圖片來(lái)判斷選擇哪一個(gè)Cell 7     if (dic[@"thumbnail_pic" ] == nil) 8     { 9         cell = [self.tableView dequeueReusableCellWithIdentifier:@"textCell" forIndexPath:indexPath];10     }11     else12     {13         cell = [self.tableView dequeueReusableCellWithIdentifier:@"imageCell" forIndexPath:indexPath];14     }15     16     return cell;17 }

  

  4.根據(jù)微博內(nèi)容來(lái)動(dòng)態(tài)的調(diào)整cell的高度:

//根據(jù)博文的內(nèi)容調(diào)整cell的高度-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{    NSDictionary *dic = self.array[indexPath.row];    NSString *text = dic[@"text"];    //用字典設(shè)置字體的大小    NSDictionary * dic1 = @{NSFontAttributeName: [UIFont systemFontOfSize:14]};        CGRect frame = [text boundingRectWithSize:CGSizeMake(276, 1000) options:NSStringDrawingUsesLineFragmentOrigin attributes:dic1 context:nil];        CGFloat height = frame.size.height;            //不同類型的cell高度不同    if (dic[@"thumbnail_pic" ] == nil)    {        height = height + 59 + 25;    }    else    {        height = height + 59 + 25+ 105;    }    return height;}

  

  5.上面是添加的代碼,下面我們需要把獲取cell的方法進(jìn)行修改,如下:

 1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 2 { 3     NSDictionary *dic = self.array[indexPath.row]; 4      5     UITableViewCell *cell = [self selectCell:dic cellForRowAtIndexPath:indexPath]; 6      7     //把值給我們的cell,讓cell設(shè)置其自己的屬性 8     [cell setCellContent:dic]; 9        10     return cell;11 }

 

  上面的時(shí)核心代碼,加入后我們?cè)趤?lái)看一下我們請(qǐng)求的效果吧,是不是看著像那么一回事兒啦,今天的博客的內(nèi)容先到這吧,以后會(huì)繼續(xù)完善我們的圍脖的:

  如果有小伙伴感覺上面太簡(jiǎn)單的化,可以來(lái)的復(fù)雜的,如果微博是轉(zhuǎn)發(fā)的把轉(zhuǎn)發(fā)的微博顯示出來(lái),下面我們把轉(zhuǎn)發(fā)的帶圖片的和不帶圖片的博文顯示出來(lái),并在下面加上轉(zhuǎn)發(fā),評(píng)論和贊的按鈕。

    需求難點(diǎn):

      1.cell的高度根據(jù)本博文和轉(zhuǎn)發(fā)博文的多少而改變,就是在cell中有兩部分內(nèi)容的高度是變化的,需要用代碼來(lái)動(dòng)態(tài)控制其高度。先給自己發(fā)的博文設(shè)置一個(gè)垂直約束,下面轉(zhuǎn)發(fā)的博文只設(shè)置編輯約束,不設(shè)置高度約束。我們根據(jù)博文文字的多少來(lái)用代碼動(dòng)態(tài)的改變垂直約束,至于如何用代碼改變約束的值,請(qǐng)參照以前的博客IOS開發(fā)之絕對(duì)布局和相對(duì)布局(屏幕適配),在這就不做過(guò)多的論述,下面主要講如何給我們的cell添加多個(gè)按鈕,然后在點(diǎn)擊按鈕的時(shí)候我們知道是那個(gè)Cell的那個(gè)button被點(diǎn)擊了。

      (1)為了區(qū)分按鈕,我們需要給每個(gè)按鈕設(shè)置tag,然后在TableViewController中獲取Tag的值,我們就知道是那個(gè)按鈕被點(diǎn)擊了。

      (2)難點(diǎn)在于我們?nèi)绾闻袛啾稽c(diǎn)擊的按鈕位于那個(gè)cell上。這個(gè)得用block回調(diào)來(lái)解決問(wèn)題啦。

        a.在我們Cell的類中需要定義一個(gè)block塊的類型變量,用于在TableViewController中回調(diào)使用,在block回調(diào)時(shí),我們就可以把那個(gè)Cell以及Cell中被點(diǎn)擊的按鈕傳到TableViewController中啦,至于想深入的了解一下block回調(diào),請(qǐng)參考前面的博客Objective-C中的Block回調(diào)模式。下面是在Cell對(duì)應(yīng)的類中,聲明Block塊類型的代碼:

//創(chuàng)建cell的block塊把按鈕的tag傳到ViewController中typedef void (^CellBlock) (ReTextTableViewCell * cell, int buttonTag);

 

       b.在Cell中添加CellBlock類型的變量,用于接收回調(diào)

1 @property (strong, nonatomic) CellBlock block;

      

        c.添加設(shè)置block的setter方法,參數(shù)是要傳入的block塊

1 -(void)setTagButtonBlock:(CellBlock)cellBlock2 {3     self.block = cellBlock;4 }

 

      d.點(diǎn)擊不同的button是給傳入的block設(shè)置不同的值,也就是把Button的tag傳入到block中。添加的三個(gè)按鈕對(duì)應(yīng)著一個(gè)回調(diào)方法,代碼如下:

1 - (IBAction)tapComment:(id)sender {2     UIButton *button = sender;3     4     self.block(self, button.tag);5 }

 

     (3)在我們的TableView中實(shí)現(xiàn)Cell的回調(diào),給據(jù)回調(diào)參數(shù)Button.tag的值的不同,去執(zhí)行相應(yīng)的業(yè)務(wù)邏輯,回調(diào)的代碼如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    NSDictionary *dic = self.array[indexPath.row];        UITableViewCell *cell = [self selectCell:dic cellForRowAtIndexPath:indexPath];            //把值給我們的cell,讓cell設(shè)置其自己的屬性    [cell setCellContent:dic];        __weak __block NSDictionary *copy_dic = dic;    __weak __block SinaBlogTableViewController  *copy_self = self;        if ([cell isKindOfClass:[ReTextTableViewCell class]] || [cell isKindOfClass:[ReImageTableViewCell class]]) {        ReTextTableViewCell * cellTemp =( ReTextTableViewCell *) cell;        [cellTemp  setTagButtonBlock:^(ReTextTableViewCell *cell, int buttonTag) {                       switch (buttonTag) {                case 1:                {                    NSLog(@"轉(zhuǎn)發(fā)");                    NSString *str = @"https://api.weibo.com/2/statuses/repost.json";                                        NSDictionary *dic = @{@"access_token":@"你自己的令牌"                                          ,@"id":[NSString stringWithFormat:@"%@",copy_dic[@"id"]]};                    //用AFHTTPRequestOperationManager來(lái)組織我們的數(shù)據(jù),數(shù)據(jù)是存儲(chǔ)在字典中的                                        AFHTTPRequestOperation *op = [self.manager POST:str parameters:dic success:^(AFHTTPRequestOperation *operation, id responseObject) {                        NSLog(@"%@",responseObject);                    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {                        NSLog(@"%@",[error localizedDescription]);                    }];                                        //配置解析過(guò)程                   op.responseSerializer = [AFJSONResponseSerializer serializer];                                        //啟動(dòng)請(qǐng)求                    [op start];                                    }                    break;                                    case 2:                {                     NSLog(@"評(píng)論");                                        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];                                        id vc = [storyboard instantiateViewControllerWithIdentifier:@"Comments"];                                        [vc setValue:copy_dic forKey:@"userInfo"];                    [copy_self.navigationController pushViewController:vc animated:YES];                                    }                                       break;                                    case 3:                    NSLog(@"");                    break;                                    default:                    break;            }                                }];    }               return cell;}

 

    經(jīng)過(guò)上面的那些代碼的修飾,我們的新浪微博的效果如下,因?yàn)榱钆剖怯梦易约旱奈⒉┵~號(hào)申請(qǐng)的,所以顯示的東西和我新浪微博的主頁(yè)是一樣的:


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 宝鸡市| 鄱阳县| 阿鲁科尔沁旗| 广州市| 白朗县| 黄骅市| 介休市| 葫芦岛市| 且末县| 明溪县| 鄯善县| 鸡东县| 潜山县| 吉安县| 慈利县| 沾益县| 高尔夫| 城步| 龙口市| 黄梅县| 昌乐县| 手游| 衡南县| 德格县| 旅游| 太谷县| 宁陕县| 海晏县| 日土县| 黄山市| 威宁| 中牟县| 乐亭县| 古浪县| 香格里拉县| 邯郸市| 尖扎县| 名山县| 得荣县| 修武县| 翼城县|