ios - 将地址簿中的电话号码与 Firestore 匹配
问题描述
我正在尝试快速将来自 Firestore 的电话号码列表与用户的通讯录进行比较和匹配。这行得通,但速度很慢,尤其是来自 Firestore 的更多数字,我认为逻辑都是错误的,需要修复。
// Array of Strings containing all the phone numbers that are registered on the app are passed through the function.
func searchForContactUsingPhoneNumber(phoneNumberArray: [String]) -> [CNContact] {
var result: [CNContact] = []
let phoneNumberKit = PhoneNumberKit()
// go through all contacts in the address book for contact in self.contacts {
if !contact.phoneNumbers.isEmpty {
let parsedNumberArray = try? phoneNumberKit.parse(phoneNumberArray, withRegion: "GB", ignoreType: true)
for singleNumber in parsedNumberArray! {
let databaseNumber = singleNumber.nationalNumber
//go through every number of each contach
for phoneNumber in contact.phoneNumbers {
let fulMobNumVar = phoneNumber.value
let number = fulMobNumVar.value(forKey: "digits") as? String
let parsedNumber = try? phoneNumberKit.parse(number!, withRegion: "GB", ignoreType: true)
let contactNumber = parsedNumber?.nationalNumber
//compare phoneNumber of contact with given users phone number
if contactNumber == databaseNumber {
result.append(contact)
}
}
}
}
}
return result
}
编辑
有3个电话号码列表:
Firestore 中的一个列表,其中存储了在应用程序上注册的用户的每个电话号码。当任何新用户在应用程序上注册时,他们的电话号码就会添加到该列表中。将此列表与用户自己的电话通讯簿进行比较。
第二个列表是用户通讯录(联系人)。如果 firebase 中的电话号码与地址簿匹配,则该号码将添加到特定用户文档中 firebase 内的第三个列表中。
第三个列表是我尝试生成的特定于应用程序的列表,其中包含用户通讯录和所有电话号码的大列表之间的匹配项。
解决方案
这里的目标是在应用程序中创建一个电话号码列表,其中所有用户电话号码的主列表与存储在用户通讯录(联系人)中的电话号码之间存在匹配。
用一些示例数据更好地说明:
phone_master
docId_0
phone: "222-222-2222"
uid: "uid_2"
docId_1
phone: "333-333-3333"
uid: "uid_3"
在上面,我们收集了所有使用该应用程序的用户电话号码。每个文档都包含电话号码,然后是拥有它的用户的 uid。
users
uid_1
name: "Hank"
phone_numbers: (a collection)
docId_0:
phone: "222-222-2222"
uid: "uid_2"
在 users 集合中,用户 Hank 已经有一个电话号码存储在他们的应用程序 222-222-2222 中,这是 uid_2 的号码。
以下将扫描存储在 firebase 主列表中的所有号码,并将任何匹配项添加到应用程序中 Hank 的电话列表中。它还将在其他用户添加到应用程序以进行任何未来比赛时收听。
这里的问题是,一旦将数字添加到应用程序中,我们就不想再次添加它。
前两行是样本数据数组:
addressBookNumbers - the numbers that are stored in the users address book, not the app
appNumbers - these are the numbers that have already been added
我假设 OP 可以从 Firestore 读取地址簿编号和现有应用程序编号并将它们存储在一个数组中。
和代码:
func generateContactList() {
let addressBookNumbers = ["111-111-1111", "222-222-2222", "333-333-3333", "444-444-4444"]
let appNumbers = ["222-222-2222"]
let thisUser = "uid_1"
let allPhonesCollection = self.db.collection("phone_master")
allPhonesCollection.addSnapshotListener { querySnapshot, error in
guard let snapshot = querySnapshot else {
print("Error fetching snapshots: \(error!)")
return
}
snapshot.documentChanges.forEach { diff in
if (diff.type == .added) {
let phone = diff.document.get("phone") as? String ?? "No Phone"
//see if this number has already been added to the app
if appNumbers.contains(phone) {
return
}
//ignore the number if it's not in the addresssbook
if !addressBookNumbers.contains(phone) {
return
}
let contactsUid = diff.document.get("uid") as? String ?? "No uid"
//if we get here, we know the number from the master list is in
// this users address book, so add it to the app
let usersCollection = self.db.collection("users")
let thisUserDoc = usersCollection.document(thisUser)
let phoneCollection = thisUserDoc.collection("phone_numbers")
let data = ["number": phone,
"uid": contactsUid]
phoneCollection.document().setData(data)
}
if (diff.type == .modified) {
let docId = diff.document.documentID
print(docId)
}
if (diff.type == .removed) {
let docId = diff.document.documentID
print(docId)
}
}
}
}
代码运行后,汉克斯文档看起来像这样
users
uid_1
name: "Hank"
phone_numbers: (a collection)
docId_0:
phone: "222-222-2222"
uid: "uid_2"
docId_1:
phone: "333-333-3333"
uid: "uid_3"
推荐阅读
- apache-spark - 如何选择包含任何给定字符串的列作为 Pyspark 中列名的一部分
- typescript - 打字稿:将 typeof 与泛型一起使用
- python - 使用 Python Ray 进行并行处理时 CPU 未完全使用
- python-3.x - 将数组的每一行与列表中的系数相乘 - Python
- python - 将 pandas dtype 字符串表示形式转换为 dict
- react-native - 向服务器发送 http 请求时处理请求正文时出错
- python - while 循环没有使用正确的变量进行输出
- javascript - 无法将 css 过滤器应用于 JavaScript 中的上下文
- c# - 如何在模型中评估 x 轴值,知道鼠标的位置?
- mysql - 尽管有索引,但更新查询很慢