iOS 9: Giới thiệu Contacts Framework

52

Với iOS 9, Apple đã giới thiệu một framework mới đó là Contacts. Đây là framework cung cấp một phương pháp hướng đối tượng để làm việc với những thông tin contact của người dùng và thay thế framework Address Book dựa trên chức năng.

Trong bài hướng dẫn này, chúng ta sẽ sử dụng lại những chức năng cơ bản của ứng dụng Contacts trong iOS để bạn có thể tìm hiểu cách mà các API mới làm việc.

Bài viết này yêu cầu chạy trên Xcode 7+ trên OS X Yosemite hoặc mới hơn. Bạn có thể download starter project từ GitHub.

Điều đầu tiên, chúng ta sẽ sử dụng Contacts framework để truy cập vào contacts của người dùng và hiển thị chúng bằng tableView. Mở starter project lên và chọn file MasterViewController.swift.

Nếu bạn cuộn lên đầu file này, bạn sẽ thấy rằng tác giả đã import thêm Contact framework. Điều này cho phép chúng ta truy cập tới các class, protocol và constants được định nghĩa trong framework.

Trong class MasterViewController, thêm vào 2 hàm getContacts() và retrieveContactsWithStore(_:)  như bên dưới:

Hãy tìm hiểu từng bước trong đoạn code này. Chúng ta tạo một đối tượng CNContactStore và nó được dùng để giao tiếp trực tiếp tới Contacts system trong iOS. Sau đó chúng ta kiểm tra trạng thái xác thực của CNContactStore. Nếu nó là undetermined, chúng ta sẽ yêu cầu xác thực và sẽ nhận được contacts nếu thành công. Nếu ứng dụng đã xác thực rồi thì chúng ta sẽ ngay lập tức lấy được contact của người dùng.

Trong hàm retrieveContactsWithStore(_:), chúng ta sẽ bao lại đoạn code trong câu lệnh do-catch bởi vì 2 hàm trong này chúng ta sử dụng là những hàm throw.

Trong câu lệnh do, chúng ta lấy nhóm contact của thiết bị. Sử dụng class CNContact, chúng ta tạo một đối tượng NSPredicate mà phù hợp với tất cả contacts bên trong cái thành phần thứ nhất của groups mà chúng ta vừa nhận được.

Sau đó chúng ta sẽ tạo một mảng chứa một số keys không đổi. Những key này quan hệ trực tiếp với những thông tin trong ứng dụng của bạn đã truy cập. Với bất kỳ key nào bạn không chỉ rõ (ví dụ như phone number) ứng dụng của bạn sẽ không thể truy cập thông tin đó. Khi làm việc với Contacts framework, điều này được xem như một phần của contact cũng như là bạn không truy cập được tất cả thông tin của contact.

Sử dụng đối tượng store, chúng ta sẽ nhận được các contact phù hợp với biến predicate mà chúng ta đã tạo trước đó và với các keys đã xác định. Chúng ta sẽ gán kết quả vào mảng objects của viewcontroller để hiển thị trong tableView. Chúng ta bắt buộc phải reload tableView trong main thread. Điều này là quan trọng bởi vì việc lấy các contact được thực hiện trong background thread.

Có một vài điều lưu ý:

  • Class method descriptorForRequiredKeysForStyle(_:)  sử dụng trong CNContactFormatter là cách thuận tiện để dễ dàng thêm các key cần thiết cho việc xem tên của contact.
  • Biến predicate bạn tạo ra không phải cho một nhóm contact. Nó có thể là một trong những thứ đó, bao gồm việc tìm kiếm những cái tên phù hợp như ví dụ sau:

  • Trong Contacts framework, không có cách nào để ứng dụng của bạn trực tiếp truy cập tới mỗi contact riêng lẻ. Đó là lý do chúng ta sử dụng đoạn code trên để nhận nhóm contact đầu tiên thay vì nhận tất cả.
  • Khi lấy các contacts, chúng ta sử dụng hàm unifiedContactsMatchingPredicate(_:keysToFetch:). “unified” trong ngữ cảnh này là gì? Nếu một người dùng có nhiều contacts liên quan đến cùng một người, họ có thể liên kết chúng cùng nhau trong app Contacts. Khi app của bạn cố gắng truy cập vào contacts của người dùng, thay vì trả về nhiều đối tượng CNContact, Contacts framework thống nhất chúng lại với nhau thành một đối tượng để ứng dụng của bạn có thể hiển thị thông tin một cách chính xác và giải thích nó một cách dễ dàng.

Tiếp theo, chúng ta cần hiển thị thông tin contacts trong tableView. Trong class MasterViewController, thêm đoạn code sau vào hàm tableView(_:cellForRowAtIndexPath:):

Chúng ta sử dụng class CNContactFormatter để dễ dàng lấy về một giá trị String là tên của contact. Chúng ta cũng lấy được địa chỉ email đầu tiên của contact (đại diện là đối tượng CNLabeledValue). Một đối tượng CNLabeledValue đại diện cho bất kỳ thông tin  contact nào mà một phần thông tin theo context có thể cần. Những đối tượng này chỉ có một label và một giá trị. Trong ví dụ sau, những từ in đậm đại diện cho label của item, những từ in nghiêng đại diện cho giá trị của chúng:

  • Home address
  • Work phone
  • Personal email

Build và run app bằng simulator. Ở lần đầu tiên run app, bạn sẽ thấy một bảng alert như sau:

Click vào OK và bạn sẽ thấy một danh sách như bên dưới:

Giờ là lúc điền đầy đủ chi tiết của contact khi người dùng chọn từ tableView. Khi lấy được contacts, chúng ta chỉ lấy đủ những keys để truy cập một tên của contact và địa chỉ email. Đối với việc hiển thị chi tiết, chúng ta cũng muốn hiển thị địa chỉ của chúng cũng như ảnh đại diện. Để thực hiện điều này, chúng ta có thêm các keys phụ trong class MasterViewController khi nhận contacts. Tuy nhiên, chúng ta sẽ lấy lại cùng một contact với keys mà chúng ta cần bằng cách sử dụng identifier của contact.

Mở file DetailViewController.swift và thêm những đoạn code sau vào trong hàm configureView() :