CXCallObserver 无法正常工作,并且当 运行 多个应用程序(包括联系人图像数据时)时应用程序崩溃
CXCallObserver is not working properly and App getting crash when running the app more than one (when includes contacts image data)
我面临两个主要问题,第一个是:
1. 我正在尝试检测来电、去电、拨号,我正在使用此代码:
import UIKit
import CoreTelephony
import CallKit
class ViewController: UIViewController,CXCallObserverDelegate {
let callObserver = CXCallObserver()
var seconds = 0
var timer = Timer()
override func viewDidLoad() {
super.viewDidLoad()
callObserver.setDelegate(self, queue: nil)
}
override func viewWillAppear(_ animated: Bool) {
print("viewWillAppear \(seconds)")
}
fileprivate func runTimer(){
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.updateTimer), userInfo: nil, repeats: true)
}
func updateTimer() {
seconds += 1
print("Seconds \(seconds)")
}
@IBAction func callButton(_ sender: UIButton) {
if let url = URL(string: "tel://\(12345879)"){
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {
if call.hasEnded == true {
print("Disconnected")
seconds = 0
self.timer.invalidate()
}
if call.isOutgoing == true && call.hasConnected == false {
print("Dialing call")
self.runTimer()
}
if call.isOutgoing == false && call.hasConnected == false && call.hasEnded == false {
print("Incoming")
}
if call.hasConnected == true && call.hasEnded == false {
print("Connected")
}
}
}
当我拨打一个号码时它工作正常,它显示 "Dialling" 但是当我挂断电话时它显示 "Disconnected" 然后又显示 "Dialing" 状态。
- 另一个问题是,当我从设备中获取所有联系人信息时,当我不获取图像数据时它工作正常,但当我获取联系人图像时它第一次工作正常。然后如果我 运行 它再次应用变慢。然后接下来它崩溃显示在展开值时发现 nil。
我在 AppDelegate 中写了我的联系人数据获取功能。它在应用程序启动时调用。这是代码:
func fetchContactList(){
let loginInformation = LoginInformation()
var contactModelData: [ContactsModel] = []
var profileImage : UIImage?
let store = CNContactStore()
store.requestAccess(for: .contacts, completionHandler: {
granted, error in
guard granted else {
let alert = UIAlertController(title: "Can't access contact", message: "Please go to Settings -> MyApp to enable contact permission", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
return
}
let keysToFetch = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName),CNContactPhoneNumbersKey, CNContactEmailAddressesKey, CNContactPostalAddressesKey, CNContactImageDataKey, CNContactImageDataAvailableKey,CNContactThumbnailImageDataKey,CNContactThumbnailImageDataKey] as [Any]
let request = CNContactFetchRequest(keysToFetch: keysToFetch as! [CNKeyDescriptor])
var cnContacts = [CNContact]()
do {
try store.enumerateContacts(with: request){
(contact, cursor) -> Void in
cnContacts.append(contact)
}
} catch let error {
NSLog("Fetch contact error: \(error)")
}
for contact in cnContacts {
let fullName = CNContactFormatter.string(from: contact, style: .fullName) ?? "No Name"
var phoneNumberUnclean : String?
var labelofContact : String?
var phoneNumberClean: String?
for phoneNumber in contact.phoneNumbers {
if let number = phoneNumber.value as? CNPhoneNumber,
let label = phoneNumber.label {
let localizedLabel = CNLabeledValue<CNPhoneNumber>.localizedString(forLabel: label)
print("fullname \(fullName), localized \(localizedLabel), number \(number.stringValue)")
phoneNumberUnclean = number.stringValue
labelofContact = localizedLabel
}
}
if let imageData = contact.imageData {
profileImage = UIImage(data: imageData)
print("image \(String(describing: UIImage(data: imageData)))")
} else {
profileImage = UIImage(named: "user")
}
self.contactModelData.append(ContactsModel(contactName: fullName, contactNumber:phoneNumberUnclean!, contactLabel: labelofContact!, contactImage: profileImage!, contactNumberClean: phoneNumberUnclean!))
}
self.loginInformation.saveContactData(allContactData: self.contactModelData)
})
}
我已经用这个解决了这两个问题:
对于第一个,当我断开呼叫时,如果不幸的是它再次转到 "Dialling" 选项,我检查了 "seconds" 变量的值,如果它在 "Dialing" 中大于 0,则使线程无效。
第二个问题:
我使用了 Dispatch.async.main 后台线程并拍摄了缩略图
我面临两个主要问题,第一个是: 1. 我正在尝试检测来电、去电、拨号,我正在使用此代码:
import UIKit
import CoreTelephony
import CallKit
class ViewController: UIViewController,CXCallObserverDelegate {
let callObserver = CXCallObserver()
var seconds = 0
var timer = Timer()
override func viewDidLoad() {
super.viewDidLoad()
callObserver.setDelegate(self, queue: nil)
}
override func viewWillAppear(_ animated: Bool) {
print("viewWillAppear \(seconds)")
}
fileprivate func runTimer(){
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.updateTimer), userInfo: nil, repeats: true)
}
func updateTimer() {
seconds += 1
print("Seconds \(seconds)")
}
@IBAction func callButton(_ sender: UIButton) {
if let url = URL(string: "tel://\(12345879)"){
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {
if call.hasEnded == true {
print("Disconnected")
seconds = 0
self.timer.invalidate()
}
if call.isOutgoing == true && call.hasConnected == false {
print("Dialing call")
self.runTimer()
}
if call.isOutgoing == false && call.hasConnected == false && call.hasEnded == false {
print("Incoming")
}
if call.hasConnected == true && call.hasEnded == false {
print("Connected")
}
}
}
当我拨打一个号码时它工作正常,它显示 "Dialling" 但是当我挂断电话时它显示 "Disconnected" 然后又显示 "Dialing" 状态。
- 另一个问题是,当我从设备中获取所有联系人信息时,当我不获取图像数据时它工作正常,但当我获取联系人图像时它第一次工作正常。然后如果我 运行 它再次应用变慢。然后接下来它崩溃显示在展开值时发现 nil。
我在 AppDelegate 中写了我的联系人数据获取功能。它在应用程序启动时调用。这是代码:
func fetchContactList(){
let loginInformation = LoginInformation()
var contactModelData: [ContactsModel] = []
var profileImage : UIImage?
let store = CNContactStore()
store.requestAccess(for: .contacts, completionHandler: {
granted, error in
guard granted else {
let alert = UIAlertController(title: "Can't access contact", message: "Please go to Settings -> MyApp to enable contact permission", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
return
}
let keysToFetch = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName),CNContactPhoneNumbersKey, CNContactEmailAddressesKey, CNContactPostalAddressesKey, CNContactImageDataKey, CNContactImageDataAvailableKey,CNContactThumbnailImageDataKey,CNContactThumbnailImageDataKey] as [Any]
let request = CNContactFetchRequest(keysToFetch: keysToFetch as! [CNKeyDescriptor])
var cnContacts = [CNContact]()
do {
try store.enumerateContacts(with: request){
(contact, cursor) -> Void in
cnContacts.append(contact)
}
} catch let error {
NSLog("Fetch contact error: \(error)")
}
for contact in cnContacts {
let fullName = CNContactFormatter.string(from: contact, style: .fullName) ?? "No Name"
var phoneNumberUnclean : String?
var labelofContact : String?
var phoneNumberClean: String?
for phoneNumber in contact.phoneNumbers {
if let number = phoneNumber.value as? CNPhoneNumber,
let label = phoneNumber.label {
let localizedLabel = CNLabeledValue<CNPhoneNumber>.localizedString(forLabel: label)
print("fullname \(fullName), localized \(localizedLabel), number \(number.stringValue)")
phoneNumberUnclean = number.stringValue
labelofContact = localizedLabel
}
}
if let imageData = contact.imageData {
profileImage = UIImage(data: imageData)
print("image \(String(describing: UIImage(data: imageData)))")
} else {
profileImage = UIImage(named: "user")
}
self.contactModelData.append(ContactsModel(contactName: fullName, contactNumber:phoneNumberUnclean!, contactLabel: labelofContact!, contactImage: profileImage!, contactNumberClean: phoneNumberUnclean!))
}
self.loginInformation.saveContactData(allContactData: self.contactModelData)
})
}
我已经用这个解决了这两个问题: 对于第一个,当我断开呼叫时,如果不幸的是它再次转到 "Dialling" 选项,我检查了 "seconds" 变量的值,如果它在 "Dialing" 中大于 0,则使线程无效。
第二个问题: 我使用了 Dispatch.async.main 后台线程并拍摄了缩略图