Как заставить CoreSpotlight предсказать, кто звонит
Я хочу, чтобы мое устройство прогнозировало, кто мне звонит, на основе индекса внимания людей. Я загрузил информацию о людях, чтобы выделить индекс, и система выдает информацию, когда я ищу, но не когда кто-то звонит. Код ниже делает все это, и я не могу понять, что не так
if people.count > 0 {
var peopleArray = [CSSearchableItem]()
var peopleGUIDs = [String]()
for person in people {
let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeText as String)
// Basic AttributeSet setup
attributeSet.title = person.nameForList
attributeSet.contentDescription = person.division?.title
// Add first phone number to AttributeSet
var phoneNumber: NSString?
let contacts = Array(person.contacts)
for contact in contacts {
if contact.type == "phone" {
phoneNumber = contact.value as NSString
break
}
}
if phoneNumber != nil {
if let preparedNumber = phoneNumber!.removingPercentEncoding {
attributeSet.phoneNumbers = [preparedNumber]
attributeSet.supportsPhoneCall = true
}
}
attributeSet.displayName = person.name
// Add photo number to AttributeSet
if let photoPath = person.photo {
let key = SDWebImageManager.shared().cacheKey(for: NSURL(string: photoPath) as URL!)
let image = SDImageCache.shared().imageFromDiskCache(forKey: key)
var data = Data()
if let image = image {
if let dataFromImage = UIImagePNGRepresentation(image) {
data = dataFromImage
}
} else {
data = dataFromImage
}
attributeSet.thumbnailData = data
}
peoplesGUIDs.append(person.id)
let item = CSSearchableItem(uniqueIdentifier: person.id, domainIdentifier: "com.it.companySpotlight", attributeSet: attributeSet)
peopleArray.append(item)
}
CSSearchableIndex.default().indexSearchableItems(peopleArray) { (error) in
DispatchQueue.main.async(execute: {
if let error = error {
print("Indexing error: \(error.localizedDescription)")
} else {
print("Search for people successfully indexed")
}
})
}
}
Кто-нибудь знает, как решить эту проблему?
1 ответ
Через некоторое время Paulw11 сказал, что мне нужно пользовательское расширение CallKit, поэтому есть решение:
- Добавьте новую цель в ваш проект "Расширение CallKIt"
- Создайте группы приложений, чтобы предоставить текстовый файл с номером телефона для вашего добавочного номера, потому что там невозможно использовать базы данных
- Убедитесь, что ваши контакты в порядке возрастания номеров для лучшей производительности
Записать контакты в файл
if #available(iOS 10.0, *) { let numbers = ["79175870629"] let labels = ["Stranger name"] // Replace it with your id let groupId = "group.YOUR.ID" let container = FileManager.default .containerURL(forSecurityApplicationGroupIdentifier: groupId) guard let fileUrl = FileManager.default .containerURL(forSecurityApplicationGroupIdentifier: groupId)? .appendingPathComponent("contacts") else { return } var string = "" for (number, label) in zip(numbers, labels) { string += "\(number),\(label)\n" } try? string.write(to: fileUrl, atomically: true, encoding: .utf8) CXCallDirectoryManager.sharedInstance.reloadExtension( withIdentifier: groupId) } else { // Fallback on earlier versions }
- Затем добавьте класс LineReader к вашему расширению из этого поста.
Этот метод будет вызываться при вызове reloadExtension
override func beginRequest(with context: CXCallDirectoryExtensionContext) { context.delegate = self if #available(iOSApplicationExtension 11.0, *) { if context.isIncremental { addOrRemoveIncrementalBlockingPhoneNumbers(to: context) addOrRemoveIncrementalIdentificationPhoneNumbers(to: context) } else { addAllBlockingPhoneNumbers(to: context) addAllIdentificationPhoneNumbers(to: context) } } else { addAllBlockingPhoneNumbers(to: context) addAllIdentificationPhoneNumbers(to: context) } context.completeRequest()
}
В моем случае я реализовал только addAllIdentificationPhoneNumbers и прочитал там контакты из файла. Вам нужно добавить логику ко всем другим методам, которые были сгенерированы по умолчанию
guard let fileUrl = FileManager.default .containerURL(forSecurityApplicationGroupIdentifier: "group.YOUR.ID")? .appendingPathComponent("contacts") else { return } guard let reader = CBLineReader(path: fileUrl.path) else { return } print("\(#function) \(fileUrl)") for line in reader { autoreleasepool { let line = line.trimmingCharacters(in: .whitespacesAndNewlines) var components = line.components(separatedBy: ",") guard let phone = Int64(components[0]) else { return } let name = components[1] context.addIdentificationEntry(withNextSequentialPhoneNumber: phone, label: name) print(#function + name) } }
Зайдите в Настройки -> Телефон -> Блокировка звонков и идентификация -> включите swift напротив вашего приложения
Протестируйте свое приложение:-) Надеюсь, оно кому-нибудь поможет