Swift 致命错误:在运行时意外发现零
我的应用程序有问题。我正在使用Swift 致命错误:在运行时意外发现零,swift,Swift,我的应用程序有问题。我正在使用func importPhoneBookContact,并获得: 致命错误:在展开可选值时意外发现nil 当我在以下位置运行应用程序时: cnContacts.remove(at: cnContacts.index(of: contact)!) 如何向函数发送nil字符串 func importPhoneBookContact(){ let keysToFetch = [ CNContactGivenNameKey, // Formatte
func importPhoneBookContact
,并获得:
致命错误:在展开可选值时意外发现nil
当我在以下位置运行应用程序时:
cnContacts.remove(at: cnContacts.index(of: contact)!)
如何向函数发送nil字符串
func importPhoneBookContact(){
let keysToFetch = [
CNContactGivenNameKey, // Formatter.descriptorForRequiredKeys(for: .fullName),
CNContactPhoneNumbersKey,
CNContactImageDataAvailableKey,
CNContactThumbnailImageDataKey] as [CNKeyDescriptor]
let request = CNContactFetchRequest(keysToFetch: keysToFetch)
var cnContacts = [CNContact]()
var phoneNumbers = [String]()
let phoneNumberKit = PhoneNumberKit()
let store = CNContactStore()
do {
try store.enumerateContacts(with: request){ (contact, cursor) -> Void in
cnContacts.append(contact)
}
if cnContacts.count > 0 {
for contact in cnContacts {
if contact.phoneNumbers.count > 0 {
for phone in contact.phoneNumbers{
if PFUser.current() == nil {
return
}
var phoneNumber = phone.value.stringValue
phoneNumber = phoneNumber.components(separatedBy: .whitespaces).joined()
if (phoneNumber.count) > 3 {
if String(phoneNumber[..<phoneNumber.index(phoneNumber.startIndex, offsetBy: 2)]) == "00" {
phoneNumber = "+"+String(phoneNumber[phoneNumber.index(phoneNumber.startIndex, offsetBy: 2)...])
} else if String(phoneNumber[..<phoneNumber.index(phoneNumber.startIndex, offsetBy: 1)]) != "+" {
if let code = (PFUser.current() as! User).countryCode {
phoneNumber = "+"+String(describing: phoneNumberKit.countryCode(for: code)!)+phoneNumber
}
}
}
if phoneNumbers.contains(phoneNumber){
cnContacts.remove(at: cnContacts.index(of: contact)!)
} else{
phoneNumbers.append(phoneNumber)
}
}
}
}
AppDelegate.contacts = cnContacts
print("phone book contacts: ", AppDelegate.contacts.count)
}
} catch let error {
NSLog("Fetch contact error: \(error)")
AppDelegate.contactsImported = true
}
}
func importPhoneBookContact(){
让keystefetch=[
CNContactGivenNameKey,//Formatter.descriptorForRequiredKeys(用于:.fullName),
CNContactPhoneNumbersKey,
CNContactImageDataAvailableKey,
CNContactThumbnailImageDataKey]作为[CNKeyDescriptor]
let request=CNContactFetchRequest(keystefetch:keystefetch)
变量cnContacts=[cnContacts]()
var phoneNumbers=[String]()
设phoneNumberKit=phoneNumberKit()
let store=CNContactStore()
做{
尝试store.enumerateContacts(with:request){(contact,cursor)->Void in
cnContacts.append(contact)
}
如果cnContacts.count>0{
对于cnContacts中的联系人{
如果contact.phoneNumbers.count>0{
用于联系人中的电话。电话号码{
如果PFUser.current()==nil{
返回
}
var phoneNumber=phone.value.stringValue
phoneNumber=phoneNumber.components(分隔符:。空格)。joined()
如果(电话号码.计数)>3{
if字符串(phoneNumber[…如@John Montgomery已经指出的)在循环中从不改变数组。
因此,我建议不要在循环时删除对象,而是保留要删除的对象数组,并在最后删除它们。
下面是我的更新版本
func importPhoneBookContact(){
let keysToFetch = [
CNContactGivenNameKey, // Formatter.descriptorForRequiredKeys(for: .fullName),
CNContactPhoneNumbersKey,
CNContactImageDataAvailableKey,
CNContactThumbnailImageDataKey] as [CNKeyDescriptor]
let request = CNContactFetchRequest(keysToFetch: keysToFetch)
var cnContacts = [CNContact]()
var phoneNumbers = [String]()
let phoneNumberKit = PhoneNumberKit()
let store = CNContactStore()
var contactsToRemove = [CNContact]()
do {
try store.enumerateContacts(with: request){ (contact, cursor) -> Void in
cnContacts.append(contact)
}
for contact in cnContacts {
if contact.phoneNumbers.count > 0 {
for phone in contact.phoneNumbers{
if PFUser.current() == nil {
return
}
var phoneNumber = phone.value.stringValue
phoneNumber = phoneNumber.components(separatedBy: .whitespaces).joined()
if phoneNumber.count > 3 {
if phoneNumber.prefix(2) == "00" {
phoneNumber = "+"+String(phoneNumber[phoneNumber.index(phoneNumber.startIndex, offsetBy: 2)...])
} else if phoneNumber.prefix(1) != "+",
let user = PFUser.current(),
let code = user.countryCode,
let countryCode = phoneNumberKit.countryCode(for: code) {
phoneNumber = "+"+countryCode+phoneNumber
}
}
if phoneNumbers.contains(phoneNumber) {
contactsToRemove.append(contact)
} else {
phoneNumbers.append(phoneNumber)
}
}
}
}
cnContacts = cnContacts.filter({ contactsToRemove.contains($0) })
AppDelegate.contacts = cnContacts
print("phone book contacts: ", AppDelegate.contacts.count)
} catch let error {
NSLog("Fetch contact error: \(error)")
AppDelegate.contactsImported = true
}
}
不要使用!
。不要假设索引(of:)
会成功。此外,一般来说,在循环过程中对数组进行变异是个坏主意。奇怪的是,为什么要枚举构建自己数组的所有联系人,然后开始迭代联系人列表,检查电话号码,迭代每个联系人的电话号码,然后在所有这些之后,最后检查是否PFUser.current()==nil
?为什么不在这个导入函数中首先做这个检查呢?旁注:永远不要用.count>0
检查空数组,有一个isEmpty
属性。而且这两个检查都是多余的。如果数组为空,则将跳过for
循环。是的,这将解决崩溃问题太多:)