CXCallObserver无法正常运行,并且在运行应用程序时多个应用程序崩溃(当包含联系人图像数据时)

时间:2017-04-22 13:13:11

标签: ios swift3 contacts callkit

我面临的两个主要问题首先是: 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")
        }
    }



}

当我拨打一个显示“拨号”的号码时工作正常,但当我切断呼叫时,它显示“已断开连接”,然后再次“拨号”状态。

  1. 另一个问题是,当我从设备中获取所有联系人信息时,当我没有获取imageData时它工作正常,但是当我提取联系人图像时,它第一次工作正常。然后,如果我再次运行它app变慢。接下来崩溃显示在展开值时发现nil。
  2. 我在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)
    
            })
    
    
    
        }
    

1 个答案:

答案 0 :(得分:0)

我用这个解决了这两个问题: 当我断开呼叫的时候,如果不幸的话,它会再次进入“拨号”选项,如果在“拨号”中大于0,则检查“秒”变量的值,然后使线程无效。

第二个问题: 我使用Dispatch.async.main后台线程并拍摄缩略图