12/08/2018, 09:37

Lập trình iOS với iCloud

iCloud là một trong những tính năng được giới thiệu trong iOS5. Với người dùng thì iCloud là một tính năng đơn giản cho phép truy cập thông tin cá nhân từ tất cả các thiết bị không dây và tự động thông qua Apple ID. Với người dùng thì chúng ta có thể sử dụng iCloud API trong iOS SDK để tích hợp ...

iCloud là một trong những tính năng được giới thiệu trong iOS5. Với người dùng thì iCloud là một tính năng đơn giản cho phép truy cập thông tin cá nhân từ tất cả các thiết bị không dây và tự động thông qua Apple ID. Với người dùng thì chúng ta có thể sử dụng iCloud API trong iOS SDK để tích hợp dịch vụ iCloud trong ứng dụng.

iCloud là gì

Về cơ bản, iCloud là một dịch vụ giúp người dùng đồng bộ dữ liệu giữa các thiết bị. Mục đích chính là để cho phép người dùng dễ dàng ghi dữ liệu của họ và có thể truy cập vào dữ liệu trên các thiết bị iOS của họ. Apple không muốn người dùng phải suy nghĩ về các máy chủ và việc đồng bộ. Ý tưởng về việc đơn giản hoá đối với người dùng cũng đc áp dụng với các lập trình viên đó là khi bạn tích hợp iCloud vào ứng dụng của bạn thì bạn không cần phải biết làm thế nào để tương tác với các máy chủ đám mây hoặc upload dữ liệu lên iCloud. iOS sẽ xử lý hết các vấn đề đó còn các lập trình viên chỉ cần quan tâm tới các vấn đề liên quan đến nội dung như sự thay đổi về dữ liệu.

Kiểu lưu trữ

iCloud cung cấp 3 kiểu lưu trữ:

  • key-value cho các giá trị rời rạc, chẳng hạn như các tuỳ chọn, cài đặt, và trạng thái cho các ứng dụng đơn giản.
  • Document cho tập tin dựa trên người dùng có thể nhìn thấy như các văn bản, bản vẽ hay các trạng thái ứng dụng phức tạp.
  • CoreData cho các giải pháp cơ sở dữ liệu đa thiết bị cho nội dung cấu trúc. Nó được xây dựng dựa trên kiểu Document và sử dụng giống với các iCloudAPI

Kích hoạt iCloud

Để sử dụng iCloud, chúng ta cần tạo App ID với tính năng iCloud đã được khởi động. Đăng nhập vào iOS Provisioning Portao và chọn mục App IDs ở sidebar. Tạo một App ID mới bằng cách click vào nút new App ID. Ở màn hình tiếp theo điền các thông tin thích hợp sau đó click vào nút submit. Vào App ID mà chúng ta vừa lập và click vào configure để có thể kích hoạt dịch vụ iCloud.

Tạo một ứng dụng đơn giản tích hợp iCloud

Trong Xcode tạo một Project, lựa chọn template là Empty Application. Trong màn hình tiếp theo nhập tên của project trùng với tên mà mình đã tạo App ID.

Thiết lập cho việc lưu trữ bằng key-value

Entilements là một cặp khoá - trị yêu cầu khả năng cụ thể hoặc cho phép bảo mật cho ứng dụng của bạn. Khi hệ thống cấp quyền cho ứng dụng của bạn, ứng dụng của bạn được sử dụng lưu trữ dạng key-value của iCloud. Để sử dụng nó việc đầu tiên chúng ta cần khởi động entitlements ở Xcode, sau đó chọn nơi lữu trữ với identifier và nó sẽ tự động nhận dạng bundle identifier của ứng dụng.

Thiết kế giao diện người dùng

Việc này tương đối quen thuộc với các lập trình viên sử dụng StoryBoard. Vào file StoryBoard để tạo giao diện người dùng như hình vẽ sau

Screen Shot 2015-05-28 at 8.45.58 AM.png

Theo các trình tự sau: Kéo thả 1 Table View Controller và thả vào Navigation Controller. Thả một button trên phía bên phải của navigation bar và set identifier là Add. Khi đó nó sẽ tự động thay đổi kiểu button thành "+"button. Tiếp theo kéo thả 1 Table View Controller khác và nhúng vào Navigation Controller. Kéo thả 1 bar button vào navigation bar. Tên có thể là Cancel và một cái khác tên là Save. Sau đó chọn Table View và cài đặt nội dung cho Static Cell. Cuối cùng thêm một hàng vào Table View và thêm 1 Text Field.

Tạo lớp ViewController Tạo 2 lớp mới để liên kết với hai table view controller mà chúng ta vừa tạo. 1 lớp là AddNoteViewController và để nó kế thừa lớp UITableViewController. Liên kết với nó ở Storyboard bằng cách chọn TableViewController và chọn AddNoteViewController ở trường Custom Class như hình

Screen Shot 2015-05-28 at 9.00.54 AM.png

Làm tương tự với TableViewController còn lại với lớp NoteListViewController. Cuối cùng tạo 1 IBOutlet từ TextField vào AddNoteViewController và tạo hai action cho hai button Cancel và Save.Trong file AddNoteViewController.h sẽ có code như sau:

@interface AddNoteViewController : UITableViewController
- (IBAction)cancel:(id)sender;
- (IBAction)save:(id)sender;
@property (weak, nonatomic) IBOutlet UITextField *noteTextField;
@end

Tích hợp iCloud Chúng ta cần hiện thực các function của app mà đã được khởi tạo ở các bước trước:

  • lấy tất cả các note trên máy chủ về và show chúng trong TableView
  • Xoá 1 note trên máy chủ
  • thêm một note mới và lưu chúng trên máy chủ Lấy các note từ máy chủ Đầu tiên chúng ta cần hiện thực lớp NoteListViewController, đây chính là nơi chúng ta có thể lấy các note trên máy chủ về và hiển thị trên tableView. Mở file NoteListViewController.h và thêm thuộc tính là mảng các notes để có thể lưu trữ các note
@property (strong, nonatomic) NSMutableArray *notes;

Khởi tạo cho mảng ở file NoteListViewController.m

- (NSArray *)notes
{
    if (_notes) {
        return _notes;
    }
    _notes = [[[NSUbiquitousKeyValueStore defaultStore] arrayForKey:@"AVAILABLE_NOTES"] mutableCopy];
    if (!_notes) _notes = [NSMutableArray array];

    return _notes;
}

ở phần khởi tạo này thì sẽ lấy hết tất cả các note đang tồn tại từ iCloud bằng lớp NSUbiquitousKeyValueStore. Khoá “AVAILABLE_NOTE” là khoá để lưu trữ mảng các note trên máy chủ. Kiểu lưu trữ key-value của iCloud giống với kiểu lưu trữ user defaults ở phía local. Tiếp theo chúng ta cần viết phần thân hàm viewDidLoad:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.navigationItem.leftBarButtonItem = self.editButtonItem;

    NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(storeDidChange:)
                                                 name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification
                                               object:store];

    [[NSUbiquitousKeyValueStore defaultStore] synchronize];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(didAddNewNote:)
                                                 name:@"New Note"
                                               object:nil];
}

Ở đây chúng ta thực hiện thêm 1 Edit button vào navigation bar để người dùng có thể xoá note. Chúng ta cũng thêm một observer để điều khiển nên chúng ta có thể nhận thông báo khi dữ liệu trên máy chủ thay đổi. Bất kì thiết bị nào khi chạy ứng dụng có thể thay đổi dữ liệu nếu có tài khảon của người dùng. Khi một thay đổi bất kì xảy ra sẽ có một thông báo được gửi đi.Tiếp theo chúng ta hiện thực phương thức xử lý khi chúng ta nhận được thông báo.

#pragma mark - Observer New Note

- (void)didAddNewNote:(NSNotification *)notification
{
    NSDictionary *userInfo = [notification userInfo];
    NSString *noteStr = [userInfo valueForKey:@"Note"];
    [self.notes addObject:noteStr];

    [[NSUbiquitousKeyValueStore defaultStore] setArray:self.notes forKey:@"AVAILABLE_NOTES"];

    [self.tableView reloadData];
}

#pragma mark - Observer

- (void)storeDidChange:(NSNotification *)notification
{
    _notes = [[[NSUbiquitousKeyValueStore defaultStore] arrayForKey:@"AVAILABLE_NOTES"] mutableCopy];

    [self.tableView reloadData];
}

Phương thức didAddNote sẽ được gọi khi người dùng save một note mới. Đầu tiên chúng talaays note mới được tao ra và thêm nó vào mảng lưu trữ sau đó tải mảng lên cho iCloud. Cuối cùng chúng ta cần reload lại tableView để hiển thị các note mới mà mới được thực hiện. Phương thức storeDidChange sẽ được gọi khi dữ liệu được thay đổi trên máy chủ. Nói các khác khi dữ liệu được thay đổi bởi 1 thiết bị thì các thiết bị khác có cùng tài khoản đang chạy ứng dụng sẽ gọi phương thức này.

Hiển thị note trong tableView

như vậy chúng ta đã hoàn thành việc tích hợp iCloud. Phần hiển thị các note trong tableView chắc hẳn đã khá quen thuộc với các lập trình viên. Việc chúng ta đã lấy được các note trên iCloud xuống và giờ chúng ta chỉ cần thực hiện việc hiển thị ra trong tableView. Các note đã được lưu lại trong một mảng nên việc hiển thị sẽ được hiện thực trong NoteListViewController.m như sau:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.notes count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    NSString *note = [self.notes objectAtIndex:indexPath.row];
    [cell.textLabel setText:note];

    return cell;
}

Xoá 1 note từ iCloud

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [self.notes removeObjectAtIndex:indexPath.row];
        [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
        [[NSUbiquitousKeyValueStore defaultStore] setArray:self.notes forKey:@"AVAILABLE_NOTES"];
    }
}

Khi ngừoi dùng xoá một note từ tableView thì chúng ta sẽ xoá note được chọn trong mảng và note được chọn trong tableView. Cuối cùng chúng ta sẽ cập nhật lại các note trên iCloud.

Thêm note

Việc thêm note sẽ thực hiện ở AddNoteViewController và chúng ta sẽ hiện thực phần thân hàm hai action mà chúng ta đã khai báo trước đó cho 2 button Cancel và Save:

- (IBAction)cancel:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (IBAction)save:(id)sender {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"New Note" object:self userInfo:[NSDictionary dictionaryWithObject:self.noteTextField.text forKey:@"Note"]];
    [self dismissViewControllerAnimated:YES completion:nil];
}

Ở đây ở phương thức save thì nó sẽ gửi 1 thông báo là có 1 note mới được khởi tạo.

0