ตอนที่ 11 : การทำ Refine Mobile Services queries with paging บน iOS / iPhone |
ตอนที่ 11 : การทำ Refine Mobile Services queries with paging บน iOS / iPhone การทำ Refine queries paging เป็นรูปแบบการเขียน Query เพื่อสร้างเงื่อนไขการแสดงข้อมูล Data จาก Mobile Services (คล้าย ๆ กับการเขียน Query เช่น Where , Top , Limit , Order By) โดยเราสามารถทำได้ทั้งระดับ Script ที่อยู่บน Mobile Services หรือจะเขียนเงื่อนไขภายใต้คำสั่ง Where() ที่อยู่บนคำสั่งของ iOS ก็ได้เช่นเดียวกัน และรูปแบบการใช้งานคำสั่ง Script ก็สามารถเข้าใจได้ง่าย ๆ เช่น
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"complete == 'false' "];
MSQuery * query = [self.table queryWithPredicate:predicate];
query.fetchOffset = 0;
query.fetchLimit = 3;
จาก Code จะเหมือนกับ
SELECT TOP 3 * FROM table_name WHERE complete = 'false'
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"complete == 'false' "];
MSQuery * query = [self.table queryWithPredicate:predicate];
query.fetchOffset = 3;
query.fetchLimit = 3;
จากตัวอย่างจะเป็นการเลือก complete = false และ ไม่เอา 3 รายการแรก แต่เอาแค่ 3 รายการถัดไปที่พบ
Example ตัวอย่างการเขียน Refine queries แบบง่าย ๆ บน iOS
ตอนนี้เรามี Mobile Services อยู่ 1 รายการ ที่ได้สร้างไว้ก่อนหน้านี้
ชื่อตารางว่า MyMember มีข้อมุลอยู่ 4 รายการ
รายการข้อมูลในตาราง MyMember
กลับมายัง Project ของ iOS บน Xcode
สำหรับพื้นฐานการสร้าง Project และการสร้าง Table รวมทั้งการติดต่อระหว่าง iOS กับ Mobile Services บน Windows Azure แนะนำให้อ่านบทความในตอนที่ 5
ตอนที่ 5: iOS / iPhone สร้างตาราง Table บน Mobile Services และการ Insert ข้อมูล
โครงสร้างไฟล์
เราจะแสดงผลข้อมูลบน TableView
ตัวอย่างการเขียนเงื่อนไขเพื่อแสดงข้อมูล
- (void)refreshDataOnSuccess:(QSCompletionBlock)completion
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"status = '0' or status = '1' "];
MSQuery * query = [self.table queryWithPredicate:predicate];
query.fetchOffset = 0;
query.fetchLimit = 3;
[query readWithCompletion:^(NSArray *results, NSInteger totalCount, NSError *error) {
[self logErrorIfNotNil:error];
if (!error)
{
// Log total count.
NSLog(@"Total item count: %@",[NSString stringWithFormat:@"%zd", (ssize_t) totalCount]);
}
items = [results mutableCopy];
// Let the caller know that we finished
completion();
}];
}
Screenshot
สำหรับการเขียนและใช้งาน Scripts อยากให้ลองเข้าไปศึกษาในบทความนี้ครับ
ในไฟล์ ViewController.h และ ViewController.m เขียน Code ดังนี้
ViewController.h
//
// ViewController.h
// myAppMobileService
//
// Created by Weerachai on 5/12/56 BE.
// Copyright (c) 2556 Weerachai. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
{
IBOutlet UITableView *myTable;
}
@end
ViewController.m
//
// ViewController.m
// myAppMobileService
//
// Created by Weerachai on 5/12/56 BE.
// Copyright (c) 2556 Weerachai. All rights reserved.
//
#import <WindowsAzureMobileServices/WindowsAzureMobileServices.h>
#import "MyMemberService.h"
#import "ViewController.h"
@interface ViewController ()
// Private properties
@property (strong, nonatomic) MyMemberService *memberService;
@end
@implementation ViewController
@synthesize memberService;
- (void)viewDidLoad
{
[super viewDidLoad];
// Start Service
self.memberService = [MyMemberService defaultService];
[self.memberService refreshDataOnSuccess:^
{
[myTable reloadData];
}];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle : UITableViewCellStyleSubtitle
reuseIdentifier : CellIdentifier] autorelease];
}
NSDictionary *item = [self.memberService.items objectAtIndex:indexPath.row];
NSString *col1 =[NSString stringWithFormat:@"id = %@ name = %@",
[item objectForKey:@"id"],
[item objectForKey:@"name"]];
cell.textLabel.text = col1;
NSString *col2 =[NSString stringWithFormat:@"email = %@ status = %@",
[item objectForKey:@"email"],
[item objectForKey:@"status"]];
cell.detailTextLabel.text= col2;
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Always a single section
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of items in the todoService items array
return [self.memberService.items count];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc {
[myTable release];
[super dealloc];
}
@end
อันนี้ Code ในไฟล์ MyMemberService.h และ MyMemberService.m
MyMemberService.h
//
// MyMemberService.h
// myAppMobileService
//
// Created by Weerachai on 7/21/56 BE.
// Copyright (c) 2556 Weerachai. All rights reserved.
//
#import <WindowsAzureMobileServices/WindowsAzureMobileServices.h>
#import <Foundation/Foundation.h>
typedef void (^QSCompletionBlock) ();
typedef void (^QSBusyUpdateBlock) (BOOL busy);
@interface MyMemberService : NSObject
@property (nonatomic, strong) NSArray *items;
@property (nonatomic, strong) MSClient *client;
@property (nonatomic, copy) QSBusyUpdateBlock busyUpdate;
+ (MyMemberService *)defaultService;
- (void)refreshDataOnSuccess:(QSCompletionBlock)completion;
- (void)handleRequest:(NSURLRequest *)request
next:(MSFilterNextBlock)next
response:(MSFilterResponseBlock)response;
@end
MyMemberService.m
//
// MyMemberService.m
// myAppMobileService
//
// Created by Weerachai on 7/21/56 BE.
// Copyright (c) 2556 Weerachai. All rights reserved.
//
#import "MyMemberService.h"
#import <WindowsAzureMobileServices/WindowsAzureMobileServices.h>
@interface MyMemberService() <MSFilter>
@property (nonatomic, strong) MSTable *table;
@property (nonatomic) NSInteger busyCount;
@end
@implementation MyMemberService
@synthesize items;
+ (MyMemberService *)defaultService
{
// Create a singleton instance of MyMemberService
static MyMemberService* service;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
service = [[MyMemberService alloc] init];
});
return service;
}
-(MyMemberService *)init
{
self = [super init];
if (self)
{
// Initialize the Mobile Service client with your URL and key
MSClient *client = [MSClient clientWithApplicationURLString:@"https://thaicreate.azure-mobile.net/"
applicationKey:@"uJPAhkAkcTBuTyCNxaOSnDKFzkoYqB49"];
// Add a Mobile Service filter to enable the busy indicator
self.client = [client clientWithFilter:self];
// Create an MSTable instance to allow us to work with the TodoItem table
self.table = [_client tableWithName:@"MyMember"];
self.items = [[NSMutableArray alloc] init];
self.busyCount = 0;
}
return self;
}
- (void)refreshDataOnSuccess:(QSCompletionBlock)completion
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"status = '0' or status = '1' "];
MSQuery * query = [self.table queryWithPredicate:predicate];
query.fetchOffset = 0;
query.fetchLimit = 3;
[query readWithCompletion:^(NSArray *results, NSInteger totalCount, NSError *error) {
[self logErrorIfNotNil:error];
if (!error)
{
// Log total count.
NSLog(@"Total item count: %@",[NSString stringWithFormat:@"%zd", (ssize_t) totalCount]);
}
items = [results mutableCopy];
// Let the caller know that we finished
completion();
}];
}
- (void)busy:(BOOL)busy
{
// assumes always executes on UI thread
if (busy)
{
if (self.busyCount == 0 && self.busyUpdate != nil)
{
self.busyUpdate(YES);
}
self.busyCount ++;
}
else
{
if (self.busyCount == 1 && self.busyUpdate != nil)
{
self.busyUpdate(FALSE);
}
self.busyCount--;
}
}
- (void)logErrorIfNotNil:(NSError *) error
{
if (error)
{
NSLog(@"ERROR %@", error);
}
}
- (void)handleRequest:(NSURLRequest *)request
next:(MSFilterNextBlock)next
response:(MSFilterResponseBlock)response
{
// A wrapped response block that decrements the busy counter
MSFilterResponseBlock wrappedResponse = ^(NSHTTPURLResponse *innerResponse, NSData *data, NSError *error)
{
[self busy:NO];
response(innerResponse, data, error);
};
// Increment the busy counter before sending the request
[self busy:YES];
next(request, wrappedResponse);
}
@end
สามารถทำการดาวน์โหลด Code ทั้งหมดได้จากท้ายบทความ
บทความถัดไปที่แนะนำให้อ่าน
บทความที่เกี่ยวข้อง
|