Tìm hiểu App Search (Phần 2)

Ở phần 1: https://viblo.asia/p/tim-hieu-app-search-phan-1-maGK7zwb5j2 ta đã tìm hiểu làm thế nào để có thể search được thông tin trong app. Ở phần này ta sẽ thử thêm thông tin vào search results và thực hiện các action lên search results

Thêm thông tin vào search results

NSUserActivity có 1 property contentAttributeSet với type là CSSearchableItemAttributeSet, cho phép ta định nghĩa content với nhiều attributes. Ta có thể vào class CSSearchableItemAttributeSet để xem cách định nghĩa content cho phù hợp. Chẳng hạn như: title, contentDescription, thumbnailData, phoneNumbers, supportsPhoneCall, emailAddresses...

import MobileCoreServices

public var attributeSet: CSSearchableItemAttributeSet {
        let attributeSet = CSSearchableItemAttributeSet(
            itemContentType: kUTTypeContact as String)
        attributeSet.title = name
        attributeSet.contentDescription = "\(department), \(email)\n\(phone)"
        attributeSet.thumbnailData = UIImageJPEGRepresentation(thumb!, 0.9)
        attributeSet.supportsPhoneCall = true
        
        attributeSet.phoneNumbers = [phone]
        attributeSet.emailAddresses = [email]
        attributeSet.keywords = skills
        
        return attributeSet
    }

Khi khởi tạo CSSearchableItemAttributeSet, 1 param itemContentType để truyền vào là kUTTypeContact. Sau đó khai báo cho activity.

activity.contentAttributeSet = attributeSet

Build và search ta có kết quả như sau:

Mở 1 search result

Ý tưởng ở đây là khi ta search ra kết quả, sau đó khi click chọn kết quả app sẽ open và redirect đến đúng màn hình có thông tin kết quả search. Ở phần trước ta đã khai báo activityTypeuserInfo cho NSUserActivity. Nay ta cần check và parse các dữ kiện đó và thực hiện redirect đến screen tương ứng.

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Swift.Void) -> Bool {
        
        guard userActivity.activityType == Person.domainIdentifier,
            let ID = userActivity.userInfo?["id"] as? Int else {
                return false
        }
        
        if let nav = window?.rootViewController as? UINavigationController,
            let listVC = nav.viewControllers.first as? ViewController,
            let index = listVC.persons.index(where: { $0.id == ID }) {
            nav.popToRootViewController(animated: false)
            
            listVC.performSegue(withIdentifier: "showDetail", sender: listVC.persons[index])
            return true
        }
        
        return false
    }

Xóa các thông tin search

Ta chỉ cần thực hiện như sau

public static func destroyIndexing() {
        CSSearchableIndex
            .default()
            .deleteAllSearchableItems { error in
                if let error = error {
                    print("Error deleting searching items: \(error)")
                } else {
                    print("Person indexing deleted.")
                }
        }
    }
  1. Build và install app.
  2. Stop Xcode.
  3. Vào Settings \ AppSearchSample và set Indexing to Viewed Records.
  4. Mở app và select person để các person này được index.
  5. Trở lại home screen và mở Spotlight
  6. Search tên person mà ta đã select
  7. Vào Settings \ AppSearchSample và set Indexing to Disabled.
  8. Quit app.
  9. Reopen app.
  10. Mở home screen và activate Spotlight.
  11. Search lại tên person lúc nãy -> no results Ở trên ta đã thực hiện xóa tất cả search items. Nếu ta chỉ muốn xóa vài item cụ thể. Có 2 API support việc này:
  • deleteSearchableItemsWithDomainIdentifiers(:completionHandler:) xóa entire “groups” của indexes dựa vào domain identifiers.
  • deleteSearchableItemsWithIdentifiers(:completionHandler:) xóa item dựa vào unique idntifier của nó từ index. 1 search item sẽ có type là CSSearchableItem và có uniqueIdentifier.