2. Sử dụng Framework Core Spotlight
Một tập hợp các APIs khác trong iOS 9 hỗ trợ user tìm kiếm nội dung trong app của bạn là Core Spotlight framework. Framework này có một kiểu thiết kế cơ sở dữ liệu và để cho bạn cung cấp nhiều thông tin hơn về nội dung mà bạn muốn nó có thể được tìm kiếm.
Trước khi bạn có thể sử dụng Core Spotlight framework, chúng ta cần kết nối project tới framework này. Trong Project Navigator, chọn project và mở tab Build Phases ở phía trên cùng. Tiếp theo, mở mục Link Binary With Libraries và click vào dấu +. Trong menu xuất hiện, tìm CoreSpotlight và kết nối project tới framework này. Lặp lại những bước này với MobileCoreServices framework.
Tiếp theo, để đảm bảo rằng kết quả tìm kiếm mà ứng dụng của chúng ta cung cấp là từ Core Spotlight, xóa app từ thiết bị thử nghiệm của bạn hoặc iOS Simulator và comment các dòng sau trong class DetailViewController:
1 2 3 |
activity.becomeCurrent() |
Cuối cùng, mở file MasterViewController.swift và thêm vào các dòng sau trước khi định nghĩa structure Show:
1 2 3 4 |
import CoreSpotlight import MobileCoreServices |
Tiếp theo, thêm các đoạn code sau vào viewDidLoad của class MasterViewController:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
var searchableItems: [CSSearchableItem] = [] for show in objects { let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeItem as String) attributeSet.title = show.name let dateFormatter = NSDateFormatter() dateFormatter.timeStyle = .ShortStyle attributeSet.contentDescription = show.genre + "
" + dateFormatter.stringFromDate(show.time) var keywords = show.name.componentsSeparatedByString(" ") keywords.append(show.genre) attributeSet.keywords = keywords let item = CSSearchableItem(uniqueIdentifier: show.name, domainIdentifier: "tv-shows", attributeSet: attributeSet) searchableItems.append(item) } CSSearchableIndex.defaultSearchableIndex().indexSearchableItems(searchableItems) { (error) -> Void in if error != nil { print(error?.localizedDescription) } else { // Items were indexed successfully } } |
Trước khi kiểm ta đoạn code này, hãy phân tích từng bước trong vòng lặp for.
- Tạo một đối tượng CSSearchableItemAttributeSet, truyền 1 item cho tham số content type. Nếu kết quả tìm kiếm liên kết tới một tấm hình, cho ví dụ, bạn sẽ truyền kUTTypeImage.
- Bạn gán cho thuộc tính title của attribute set với giá trị là name của show. Cũng giống như NSUserActivity, title này là cái sẽ được xuất hiện trên cùng của kết quả tìm kiếm.
- Tiếp theo, bạn khởi tạo một chuỗi mô tả và gán giá trị này cho thuộc tính contentDescription của attribute set. Chuỗi này sẽ được hiển thị phía dưới tiêu đề kết quả trong Spotlight.
- Bạn khởi tạo một mảng chứa các từ khoá kết quả tìm kiếm giống như bạn đã làm với NSUserActivity.
- Cuối cùng, bạn khởi tạo một CSSearchableItem với 1 unique item identifier, unique domain identifier để nhóm các items với nhau và 1 attribute set. Không như NSUserActivity, cái mà trả về user activity từ kết quả tìm kiếm, unique identifiers bạn sử dụng cho CSSearchableItem là những thông tin duy nhất mà bạn nhận từ hệ thống khi kết quả tìm kiếm của bạn được chọn từ user. Bạn cần sử dụng những identifiers này để khôi phục app của bạn về trạng thái chính xác nhất.
Mỗi lần bạn khởi tạo 1 CSSearchableItem cho các chương trình TV, bạn chỉ mục chúng sử dụng method indexSearchableItems(_:completionHandler:) trong đối tượng CSSearchableIndex mặc định.
Build và run app, tất cả những chương trình sẽ được ghi vào mục lục bởi Spotlight. Điều hướng tới khung search và tìm kiếm thử 1 chương trình nào đó.
Kết quả tìm kiếm từ Core Spotlight được xử lý bằng những phương pháp tương tự như NSUserActivity, nhưng tiến trình này hơi khác nhau. Khi 1 CSSearchableItem được chọn từ kết quả tìm kiếm, hệ thống sẽ tạo 1 đối tượng NSUserActivity cho bạn mà chứa unique identifier của item đã chọn.
Trong hàm application(_:continueUserActivity:restorationHandler:) của appdelegate, bạn có thể sử dụng cách sau để nhận thông tin bạn cần từ kết quả tìm kiếm từ Core Spotlight:
1 2 3 4 5 6 7 8 9 10 |
if userActivity.activityType == CSSearchableItemActionType { if let identifier = userActivity.userInfo?[CSSearchableItemActivityIdentifier] as? String { // Use identifier to display the correct content for this search result return true } } |
Một cách tốt khi chỉ mục nội dung từ app của bạn với Core Spotlight framework là xoá các items khi chúng không còn cần thiết. Class CSSearchableIndex cung cấp 3 methods để xoá các items được tìm kiếm:
- deleteAllSearchableItemsWithCompletionHandler(_:)
- deleteSearchableItemsWithDomainIdentifiers(_:completionHandler:)
- deleteSearchableItemsWithIdentifiers(_:completionHandler:)
Như một ví dụ, thêm đoạn code sau vào cuối hàm viewDidLoad của class MasterViewController:
1 2 3 4 5 6 7 8 9 10 |
CSSearchableIndex.defaultSearchableIndex().deleteSearchableItemsWithDomainIdentifiers(["tv-shows"]) { (error) -> Void in if error != nil { print(error?.localizedDescription) } else { // Items were deleted successfully } } |
Build và run app lần nữa. Khi bạn thử tìm bất kỳ 1 chương trình nào, không có kết quả trả về bởi vì chúng đã bị xoá từ mục lục.
3. Combining NSUserActivity và Core Spotlight
Một điều mới được thêm vào class NSUserActivity trong iOS 9 là thuộc tính contentAttributeSet. Thuộc tính này cho phép bạn gán 1 CSSearchableItemAttributeSet, cũng như cái mà bạn đã tạo trước đó. Attribute set này cho phép kết quả tìm kiếm của bạn đối với đối tượng NSUserActivity để hiển thị cùng 1 số chi tiết như kết quả tìm kiếm từ Core Spotlight.
Bắt đầu bằng cách thêm đoạn import sau ở trên cùng file DetailViewController.swift: