import Foundation import SwiftSignalKit import Postbox import TelegramCore import Contacts import Intents struct MatchingDeviceContact { let stableId: String let firstName: String let lastName: String let phoneNumbers: [String] } func matchingDeviceContacts(stableIds: [String]) -> Signal<[MatchingDeviceContact], NoError> { guard CNContactStore.authorizationStatus(for: .contacts) == .authorized else { return .single([]) } let store = CNContactStore() guard let contacts = try? store.unifiedContacts(matching: CNContact.predicateForContacts(withIdentifiers: stableIds), keysToFetch: [CNContactFormatter.descriptorForRequiredKeys(for: .fullName), CNContactPhoneNumbersKey as CNKeyDescriptor]) else { return .single([]) } return .single(contacts.map({ contact in let phoneNumbers = contact.phoneNumbers.compactMap({ number -> String? in if !number.value.stringValue.isEmpty { return number.value.stringValue } else { return nil } }) return MatchingDeviceContact(stableId: contact.identifier, firstName: contact.givenName, lastName: contact.familyName, phoneNumbers: phoneNumbers) })) } func matchingCloudContacts(postbox: Postbox, contacts: [MatchingDeviceContact]) -> Signal<[(String, TelegramUser)], NoError> { return postbox.transaction { transaction -> [(String, TelegramUser)] in var result: [(String, TelegramUser)] = [] outer: for peerId in transaction.getContactPeerIds() { if let peer = transaction.getPeer(peerId) as? TelegramUser, let phone = peer.phone { let formattedPhone = formatPhoneNumber(phone) for contact in contacts { for phoneNumber in contact.phoneNumbers { if formatPhoneNumber(phoneNumber) == formattedPhone { result.append((contact.stableId, peer)) continue outer } } } } } return result } } func personWithUser(stableId: String, user: TelegramUser) -> INPerson { var nameComponents = PersonNameComponents() nameComponents.givenName = user.firstName nameComponents.familyName = user.lastName return INPerson(personHandle: INPersonHandle(value: stableId, type: .unknown), nameComponents: nameComponents, displayName: user.debugDisplayTitle, image: nil, contactIdentifier: stableId, customIdentifier: "tg\(user.id.toInt64())") }