這個頁面要講述的是使用者的粉絲列表,下面是:
可以看到這個視圖明顯也是一個tableview,在每一個cell中包含的有三個部分的內容:粉絲頭像image,粉絲暱稱label,我和粉絲之間的相互關注情況button。
在這個頁面我們主要處理的內容有:① 粉絲列表資料的擷取 ②tableview視圖介面的組織(重點是:添加關注和取消追蹤)
(1)首先是擷取粉絲列表資料,這部分內容沒有什麼好說的,就是些JSON資料,然後解析。調用的API:https://api.weibo.com/2/friendships/followers.json。其中有一個點是需要注意的。我們注意到其中API請求的參數:
count |
false |
int |
單頁返回的記錄條數,預設為50,最大不超過200。 |
cursor |
false |
int |
返回結果的遊標,下一頁用傳回值裡的next_cursor,上一頁用previous_cursor,預設為0。 |
可以知道一次資料請求是以頁的方式返回的,每一頁返回count條數的粉絲記錄,這個和前面微博內容的返回的差不多的,都是以頁為單位返回,但是這裡有一個比較特殊的是,在這個API的資料請求中沒有page這個參數,而是用到了cursor這個參數,這個參數開始是0,以後每一次請求後擷取的資料中就有next_cursor這個傳回值,用它來為cursor賦值,就可以繼續擷取接下去的資料了,如果粉絲資料已經全部擷取到了,那麼這個值返回就又是0了。那麼我們在繼續載入的時候就可以添加一個判斷,判斷next_cursor是否為0,如果不為0,說明粉絲列表還沒有載入完畢,可以繼續請求載入;如果為0,則說明所有的粉絲資料都已經載入了,這時就不要繼續再載入了。
下面通過代碼看看吧!
- (void) loadFollersDataWithCursor:(int) cursor { dispatch_async(dispatch_get_global_queue(0, 0), ^{ dispatch_sync(dispatch_get_global_queue(0, 0), ^{ hud = [[MBProgressHUD alloc] init]; hud.dimBackground = YES; hud.labelText = @"正在載入資料..."; [hud show:YES]; [self.view addSubview:hud]; //同步GET請求粉絲資料 NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:[InfoForSina returnFollowersUrlStringWithCursor:cursor]]]; NSError *error; NSData *followersData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error]; //使用JSONKit解析資料 NSString *follwersString = [[NSString alloc] initWithData:followersData encoding:NSUTF8StringEncoding]; NSDictionary *followersDictionary = [follwersString objectFromJSONString]; NSArray *followersArray = [followersDictionary objectForKey:@"users"]; followersCount = [[followersDictionary objectForKey:@"total_number"] integerValue]; //粉絲總數 nextCursor = [[followersDictionary objectForKey:@"next_cursor"] integerValue]; //粉絲列表 for (NSDictionary *dictionary in followersArray) { User *followersUser = [[User alloc] init]; [followersUser initUserWithDictionary:dictionary]; [self.followersMutableArray addObject:followersUser]; } }); dispatch_sync(dispatch_get_main_queue(), ^{ [self.tableView reloadData]; [hud removeFromSuperview]; }); });}//處理tableview滑動到底了- (void) scrollViewDidScroll:(UIScrollView *)scrollView { CGPoint contentOffsetPoint = self.tableView.contentOffset; CGRect frame = self.tableView.frame; if (contentOffsetPoint.y == self.tableView.contentSize.height - frame.size.height) { if (nextCursor!=0) { [self loadFollersDataWithCursor:nextCursor]; } //全部載入完畢 else { MBProgressHUD *endHud = [[MBProgressHUD alloc] init]; endHud.mode = MBProgressHUDModeText; endHud.labelText = @"提示"; endHud.detailsLabelText = @"粉絲資料已全部載入!"; [self.tableView addSubview:endHud]; [endHud show:YES]; [endHud hide:YES afterDelay:0.5]; } }}
注意到其中的nextCursor這個參數,就是用來繼續載入的關鍵參數,在開始的時候
nextCursor = 0;
[self loadFollersDataWithCursor:nextCursor];
以後每一次載入資料的時候就用擷取到的新值為它重新賦值。
(2)tableview視圖介面的組織
這裡粉絲頭像和粉絲的暱稱的顯示就不多說了,很簡單的。代碼如下:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *CellIdentifier = @"FansCell"; FansCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; if (cell == nil) { cell = [[FansCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } //這裡的User類就是表示一個粉絲 User *aUser = [[User alloc] init]; aUser = [_followersMutableArray objectAtIndex:[indexPath row]]; cell.nameLabel.adjustsFontSizeToFitWidth = YES; cell.nameLabel.text = aUser.nameString; //設定按鍵文字 cell.fansButtonLabel.titleLabel.adjustsFontSizeToFitWidth = YES; if (aUser.following) { //表示我已經關注了該粉絲 [cell.fansButtonLabel setTitle:@"互相關注" forState:UIControlStateNormal]; } else { [cell.fansButtonLabel setTitle:@"+關注" forState:UIControlStateNormal]; } //設定頭像 __block NSData *imageData; dispatch_async(dispatch_get_global_queue(0, 0), ^{ dispatch_sync(dispatch_get_global_queue(0, 0), ^{ imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:aUser.profileImageURL]]; }); dispatch_sync(dispatch_get_main_queue(), ^{ UIImage *image = [[UIImage alloc] initWithData:imageData]; [cell.imageView setImage:image]; }); }); //頭像設定圓角 CALayer *l = [cell.imageView layer]; //擷取ImageView的層 [l setMasksToBounds:YES]; [l setCornerRadius:6.0]; //設定粉絲的id號,這裡只是為取消追蹤或者添加關注的請求參數用 cell.fansUIDString = aUser.IDString; return cell;}
說明:
1、裡面的頭像我設定成圓角,這時需要#import "QuartzCore/QuartzCore.h",其他都可以看懂的吧。
2、其中擷取頭像的方法是:
-(UIImage *) getImageFromURL:(NSString *)fileURL { UIImage * resultImage = [[UIImage alloc] init]; NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]]; resultImage = [UIImage imageWithData:data]; return resultImage;}
在這一部分的內容中要值得說明的是我添加的那個按鍵的處理。首先說一下我這個按鍵的作用:我們在擷取到的粉絲JSON資料中有:follow_me和following這兩個項,前者表示的是該粉絲是否關注我,顯然我的粉絲肯定是關注我的啦,所以一直返回是true;後者表示的是我是否關注這個粉絲,有關注返回true,否則就返回false。所以我們就可以在這裡面做點事情了。
如果我沒有關注這個粉絲即following是false的話,button的作用就是可以添加對這個粉絲的關注,button的label就是“+關注”。
如果我關注了這個粉絲即following是true的話,button的作用就是可以取消對這個粉絲的關注,button的label就是“取消追蹤”;
由於有這部分的處理,所以我定義了一個Fanscell類專門是用於處理cell這部分的內容。
下面著重講的是關注和取消追蹤粉絲的處理。
①、請求API及參數
添加關注的API:https://api.weibo.com/2/friendships/create.json
取消追蹤的API: https://api.weibo.com/2/friendships/destroy.json
二者調用時所需的參數除了access_token之外,還要粉絲的uid或者screen_name(二選一),注意前者是long long (int64)類型,後者是string類型,我選用的是uid這個參數。
②、Fanscell類
其中包括的有:
- (IBAction)fansButton:(id)sender;@property (weak, nonatomic) IBOutlet UIButton *fansButtonLabel;@property (weak, nonatomic) IBOutlet UILabel *nameLabel;@property (weak, nonatomic) IBOutlet UIImageView *headImageView;@property (strong, nonatomic) NSString *fansUIDString;//粉絲的UID
其中的fansButton方法是用來處理關注和取消追蹤粉絲的。
下面先給出處理的過程代碼再解說:
- (IBAction)fansButton:(id)sender { destroyFriendships = NO; creatFriendships = NO; if ([self.fansButtonLabel.titleLabel.text isEqualToString:@"互相關注"]) { destroyFriendships = YES; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"是否取消追蹤" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil]; [alert show]; } else if ([self.fansButtonLabel.titleLabel.text isEqualToString:@"+關注"]) { creatFriendships = YES; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"是否關注" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil]; [alert show]; }}- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { //取消追蹤 if (destroyFriendships && buttonIndex == 1) { MBProgressHUD *custuonHUD = [[MBProgressHUD alloc]init]; custuonHUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]]; custuonHUD.mode = MBProgressHUDModeCustomView; [self addSubview:custuonHUD]; NSURL *url = [NSURL URLWithString:FRIENDSHIPS_DESTROY]; ASIFormDataRequest *item = [[ASIFormDataRequest alloc] initWithURL:url]; [item setPostValue:[InfoForSina returnAccessTokenString] forKey:@"access_token"]; [item setPostValue:[NSString stringWithFormat:@"%lld",[_fansUIDString longLongValue]] forKey:@"uid"]; [item setCompletionBlock:^{ [self.fansButtonLabel setTitle:@"+關注" forState:UIControlStateNormal]; custuonHUD.labelText = @"取消追蹤成功!"; [custuonHUD show:YES]; [custuonHUD hide:YES afterDelay:2]; }]; [item setFailedBlock:^{ custuonHUD.labelText = @"取消追蹤失敗!"; [custuonHUD show:YES]; [custuonHUD hide:YES afterDelay:2]; }]; [item startAsynchronous]; } //添加關注 else if (creatFriendships && buttonIndex == 1) { //使用ASI這個類庫處理添加關注的資料請求 /* MBProgressHUD *custuonHUD = [[MBProgressHUD alloc]init]; custuonHUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]]; custuonHUD.mode = MBProgressHUDModeCustomView; [self addSubview:custuonHUD]; NSURL *url = [NSURL URLWithString:FRIENDSHIPS_CREAT]; ASIFormDataRequest *item = [[ASIFormDataRequest alloc] initWithURL:url]; [item setPostValue:[InfoForSina returnAccessTokenString] forKey:@"access_token"]; [item setPostValue:[NSString stringWithFormat:@"%lld",[_fansUIDString longLongValue]] forKey:@"uid"]; [item setCompletionBlock:^{ [self.fansButtonLabel setTitle:@"互相關注" forState:UIControlStateNormal]; custuonHUD.labelText = @"關注成功!"; [custuonHUD show:YES]; [custuonHUD hide:YES afterDelay:1]; }]; [item setFailedBlock:^{ custuonHUD.labelText = @"關註失敗!"; [custuonHUD show:YES]; [custuonHUD hide:YES afterDelay:1]; }]; [item startAsynchronous]; */ //不使用ASI這個類庫處理添加關注的資料請求 NSURL *url = [NSURL URLWithString:FRIENDSHIPS_CREAT]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5.0]; [request setHTTPMethod:@"POST"]; NSString *postString = [NSString stringWithFormat:@"access_token=%@&uid=%lld",[InfoForSina returnAccessTokenString],[_fansUIDString longLongValue]]; NSMutableData *postData = [[NSMutableData alloc] init]; [postData appendData:[postString dataUsingEncoding:NSUTF8StringEncoding]]; [request setHTTPBody:postData]; self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; }}#pragma mark - NSURLConnection delegate Methods-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ self.responseData = [[NSMutableData alloc] initWithLength:0];}-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ [self.responseData appendData:data];}-(void)connectionDidFinishLoading:(NSURLConnection *)theconnection{ MBProgressHUD *custuonHUD = [[MBProgressHUD alloc]init]; custuonHUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]]; custuonHUD.mode = MBProgressHUDModeCustomView; [self addSubview:custuonHUD]; NSError *error; NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:&error]; NSString *idString = [dict objectForKey:@"idstr"]; if(idString) { [self.fansButtonLabel setTitle:@"互相關注" forState:UIControlStateNormal]; custuonHUD.labelText = @"關注成功!"; [custuonHUD show:YES]; [custuonHUD hide:YES afterDelay:2.3]; } else { custuonHUD.labelText = @"關註失敗!"; [custuonHUD show:YES]; [custuonHUD hide:YES afterDelay:2.3]; } [self.connection cancel];}-(void)connection:(NSURLConnection *)theconnection didFailWithError:(NSError *)error{ MBProgressHUD *failedHud = [[MBProgressHUD alloc] init]; failedHud.mode = MBProgressHUDModeText; failedHud.labelText = @"提示"; failedHud.detailsLabelText = @"發表評論失敗!"; [failedHud show:YES]; [self addSubview:failedHud]; [failedHud hide:YES afterDelay:1.3]; [self.connection cancel];}
說明:
1、當按下這個button時會觸發一個UIAlertView,提示是否確定關注和取消追蹤。
2、確定要關注或者取消追蹤粉絲的處理在UIAlertView的delegate方法中處理。
3、關注和取消追蹤粉絲的資料請求方式是POST,我們可以用ASIHTTPRequest來非同步方式處理,也可以用不用這個類庫,用系統內建的方法非同步POST處理。代碼中有我使用了這這兩種方式。其中取消追蹤我是使用ASIHTTPRequest,而添加關注是使用系統內建的方法(當然注釋部分也給出了ASIHTTPRequest的使用代碼)。
注意,如果是使用系統內建的方式非同步POST處理,我還添加了兩個property:
@property (strong, nonatomic) NSURLConnection *connection;
@property (strong, nonatomic) NSMutableData *responseData;
通過代碼可以清楚的看到,前一種處理方式十分簡潔,後一種處理方式由於要實現delegate方法,所以感覺有點麻煩,二者孰好孰不好,自己感覺咯!
4、在資料請求結束我繼續使用MBProgressHUD這個類庫添加了一些提示框,表示關注是否成功或者取消追蹤是否成功。效果如下:
這個頁面的處理差不多就是這樣了!