JSON資料於TableView與Pull Refresh

我透過JSON的方式來取得資料,並且可以從網路上取得,並且當資料有變動的時候,透過Table View向下拉的方式來更新資料。我的JSON資料是透過php程式來撰寫。首先先來建置一個簡單的資料表。如下圖,在Table View的部分會呈現名字,當點選名字後會看到該名字的電話號碼。

php程式碼

1
2
3
4
5
6
7
8
<?php
include('db.php');
$query = mysql_query('SELECT * FROM user');
$json_data = array();
while($row = mysql_fetch_assoc($query)) {
$json_data[] = $row;
}
echo json_encode($json_data);

**Step 1.**建立Master Detail Application專案。

建立完成專案後先開始編輯MasterViewController.h。建立一個NSMutableArray型態的json_array物件。

MasterViewController.h
1
2
3
4
#import <UIKit/UIKit.h>
@interface MasterViewController : UITableViewController
@property (strong, nonatomic) NSMutableArray *json_array;
@end

**Step 2.**編輯MasterViewController.m

viewDidLoad方法內加入下面的程式碼

MasterViewController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@implementation MasterViewController
@synthesize json_array;
- (void)viewDidLoad
{
[super viewDidLoad];
//1
NSURL *url = [NSURL
URLWithString:@"http://XXX.XXX/json.php"];
//2
NSData *jsonData=[NSData dataWithContentsOfURL:url];
NSError *error = nil;

//3
json_array = [NSJSONSerialization JSONObjectWithData:jsonData options:
NSJSONReadingMutableContainers error:&error];
}
  1. 在上面的程式碼一開始定義一個NSURL類別的url變數,該變數很明顯的可以看到要連接的網頁網址!
  2. url網址的資料存放到NSData類別的jsonData變數中。
  3. 接著將取得到的結果放到json陣列中,當中可以看到options:NSJSONReadingMutableContainers這段,這意思是將jsonData取得的JSON資料轉為NSMutableDictionary,之後再取得名稱或電話時可以objecForKey的方式來取得。

接著修改Table View Cell的回傳個數

MasterViewController.m
1
2
3
4
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return json_array.count;
}

修改Cell顯示的文字,這邊需要透過objectForKey方法指定Key值為。

MasterViewController.m
1
2
3
4
5
6
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
cell.textLabel.text = [[json_array objectAtIndex:indexPath.row] objectForKey:@"u_name"];
return cell;
}

傳遞參數也需要修改一下。

MasterViewController.m
1
2
3
4
5
6
7
8
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
[[segue destinationViewController] setDetailItem:[json_array
objectAtIndex:indexPath.row]];
}
}

JSON的資料放入Table View中會如下圖所示(資料內容有新增修改過)。

接下來當我MySql有新增資料,或是刪除資料時,我想要同步更新到Table View中,所以我使用了PullToRefresh這個套件。網路上蠻多人都說EGOTableViewPullRefresh這套,但是它似乎不支援ARC,所以我就改用別的了。

這個套件使用上很簡單!首先下載好它的檔案Here,並加入專案內。

接著加入QuartzCore.framework

修改MasterViewController.h,程式碼如下:

MasterViewController.m
1
2
3
4
5
6
7
#import <UIKit/UIKit.h>
#import "PullToRefreshView.h" //1

@interface MasterViewController : UITableViewController<PullToRefreshViewDelegate> //2
@property (strong, nonatomic) NSMutableArray *json_array;
@property (strong, nonatomic) PullToRefreshView *pull; //3
@end

回到MasterViewController.mviewDidLoadPullToRefresh加入到Table View中。

MasterViewController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@implementation MasterViewController
@synthesize json_array, pull;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSURL *url = [NSURL
URLWithString:@"http://lighter.cp22.secserverpros.com/lighter127/JSON/json.php"];
NSData *jsonData=[NSData dataWithContentsOfURL:url];
NSError *error = nil;
json_array = [NSJSONSerialization JSONObjectWithData:jsonData options:
NSJSONReadingMutableContainers error:&error];

//pull refresh
pull = [[PullToRefreshView alloc] initWithScrollView:(UIScrollView *) self.tableView];
[pull setDelegate:self];
[self.tableView addSubview:pull];
}

Table View往下拉的時候會呼叫pullToRefreshViewShouldRefresh:方法。這裡我會呼叫另一個自定的方法reloadTableData,而在該方法內我重新再連一次json.php的網頁並更新json_array的內容,最後才呼叫tableViewreloadData

當資料更新結束後,呼叫finishedLoading方法,結束Pull Refresh的動作。

MasterViewController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#pragma mark - Table View Pull Refresh

- (void)pullToRefreshViewShouldRefresh:(PullToRefreshView *)view;
{
[self reloadTableData];
}

- (void)reloadTableData
{
NSURL *url = [NSURL
URLWithString:@"http://XXX.XXX/json.php"];
NSData *jsonData=[NSData dataWithContentsOfURL:url];
NSError *error = nil;
json_array = [NSJSONSerialization JSONObjectWithData:jsonData options:
NSJSONReadingMutableContainers error:&error];
[self.tableView reloadData];
[pull finishedLoading];
}

註:由於向下捲動Table View的速度比我截圖速度快….我就放棄了…

#參考資料

  1. PullToRefresh iOS 5 and ARC Tutorial
  2. PullToRefresh
  3. EGOTableViewPullRefresh