天天看點

IOS Swift 5.0 擷取通訊錄清單撥打電話

一、建立項目

這個很簡單,就不多說了

二、實作 UITableView 以及相關布局

也不複雜,不會的可以參考一下我的另一篇,都是最基礎的

三、添權重限

擷取通訊錄資料需要添加請求通路通訊錄的權限,第二個就是通路通訊錄權限,沒有權限當然就擷取不到了

四、代碼展示

TelController.swift

擷取通訊錄資料需要

import Contacts

繼承 ,UITableViewDataSource, UITableViewDelegate

TelModel 是自定義的一個 model ,下面也有代碼展示

import UIKit
import Contacts

class TelController: BaseController, UITableViewDataSource, UITableViewDelegate{
        
    //通訊錄資料集
    var telArray:Array  = [TelModel]()
    //清單
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        print(content ?? "tel-content-null")
        // Do any additional setup after loading the view.
        //1.擷取授權狀态
        let status = CNContactStore.authorizationStatus(for: .contacts)
        //2.判斷授權狀态,如果未授權,發起授權請求,如果已授權,就直接周遊通訊錄擷取資料
        if status == .notDetermined {
            let contactStore = CNContactStore()
            contactStore.requestAccess(for: .contacts, completionHandler: { (isRight: Bool, nil) in
                if isRight {
                    print("授權成功")
                    //周遊聯系人清單
                    self.getContatList()
                } else {
                    print("使用者未授權")
                }
            })
        }else{
            //周遊聯系人清單
            self.getContatList()
        }

    }
    //清單長度設定
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return telArray.count
    }
    //設定聯系人資料
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell:TelCell = tableView.dequeueReusableCell(withIdentifier: "TelCellId", for:indexPath) as! TelCell
        cell.telName.text = telArray[indexPath.row].name
        return cell
    }
    //點選聯系人-撥打電話去
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        //alerts2(contents: telArray[indexPath.row].tel ?? "電話為空!")
        callPhone(telArray[indexPath.row].tel ?? "電話為空!")
    }
    
    
    /*
     *調用時間:
     *作用:周遊通訊錄
     */
    private func getContatList() {
        //判斷是否有權讀取通訊錄
        let status = CNContactStore.authorizationStatus(for: .contacts)
        guard status == .authorized else {
            return
        }
        //1.建立通訊錄對象
        let store = CNContactStore()
        //2.定義要擷取的屬性鍵值
        let key = [CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey]
        //3.擷取請求對象
        let request = CNContactFetchRequest(keysToFetch: key as [CNKeyDescriptor])
        //4.周遊所有聯系人
        do {
            try store.enumerateContacts(with: request, usingBlock: { (contact: CNContact, stop: UnsafeMutablePointer<ObjCBool>) in
                //4.1擷取姓名
                let lastName = contact.familyName
                let firstName = contact.givenName
                let telModel:TelModel = TelModel()
                telModel.name = "\(lastName)\(firstName)"
                print("姓名:\(lastName)\(firstName)")
                //4.2擷取電話号碼
                let phoneNumbers = contact.phoneNumbers
                for phoneNumber in phoneNumbers {
                    print(phoneNumber.value.stringValue)
                    telModel.tel = phoneNumber.value.stringValue
                }
                self.telArray.append(telModel)
                //去掉聯系人姓名為空或者 電話為空的資料
                if(telModel.name == "" || telModel.tel == ""){
                    self.telArray.remove(at: self.telArray.count-1)
                }
                //在主線程中重新整理資料
                DispatchQueue.main.async(execute: {
                    self.tableView.reloadData()
                })
                                
//                //擷取姓名
//                let lastName = contact.familyName
//                let firstName = contact.givenName
//                print("姓名:\(lastName)\(firstName)")
//
//                //擷取昵稱
//                let nikeName = contact.nickname
//                print("昵稱:\(nikeName)")
//
//                //擷取公司(組織)
//                let organization = contact.organizationName
//                print("公司(組織):\(organization)")
//
//                //擷取職位
//                let jobTitle = contact.jobTitle
//                print("職位:\(jobTitle)")
//
//                //擷取部門
//                let department = contact.departmentName
//                print("部門:\(department)")
//
//                //擷取備注
//                let note = contact.note
//                print("備注:\(note)")
//
//                //擷取電話号碼
//                print("電話:")
//                for phone in contact.phoneNumbers {
//                    //獲得标簽名(轉為能看得懂的本地标簽名,比如work、home)
//                    let label = CNLabeledValue<NSString>.localizedString(forLabel: phone.label!)
//                    //擷取号碼
//                    let value = phone.value.stringValue
//                    print("\t\(label):\(value)")
//                }
//
//                //擷取Email
//                print("Email:")
//                for email in contact.emailAddresses {
//                    //獲得标簽名(轉為能看得懂的本地标簽名)
//                    let label = CNLabeledValue<NSString>.localizedString(forLabel: email.label!)
//                    //擷取值
//                    let value = email.value
//                    print("\t\(label):\(value)")
//                }
//
//                //擷取位址
//                print("位址:")
//                for address in contact.postalAddresses {
//                    //獲得标簽名(轉為能看得懂的本地标簽名)
//                    let label = CNLabeledValue<NSString>.localizedString(forLabel: address.label!)
//                    //擷取值
//                    let detail = address.value
//                    let contry = detail.value(forKey: CNPostalAddressCountryKey) ?? ""
//                    let state = detail.value(forKey: CNPostalAddressStateKey) ?? ""
//                    let city = detail.value(forKey: CNPostalAddressCityKey) ?? ""
//                    let street = detail.value(forKey: CNPostalAddressStreetKey) ?? ""
//                    let code = detail.value(forKey: CNPostalAddressPostalCodeKey) ?? ""
//                    let str = "國家:\(contry) 省:\(state) 城市:\(city) 街道:\(street) 郵編:\(code)"
//                    print("\t\(label):\(str)")
//                }
//
//                //擷取紀念日
//                print("紀念日:")
//                for date in contact.dates {
//                    //獲得标簽名(轉為能看得懂的本地标簽名)
//                    let label = CNLabeledValue<NSString>.localizedString(forLabel: date.label!)
//                    //擷取值
//                    let dateComponents = date.value as DateComponents
//                    let value = NSCalendar.current.date(from: dateComponents)
//                    let dateFormatter = DateFormatter()
//                    dateFormatter.dateFormat = "yyyy年MM月dd日 HH:mm:ss"
//                    print("\t\(label):\(dateFormatter.string(from: value!))")
//                }
//
//                //擷取即時通訊(IM)
//                print("即時通訊(IM):")
//                for im in contact.instantMessageAddresses {
//                    //獲得标簽名(轉為能看得懂的本地标簽名)
//                    let label = CNLabeledValue<NSString>.localizedString(forLabel: im.label!)
//                    //擷取值
//                    let detail = im.value
//                    let username = detail.value(forKey: CNInstantMessageAddressUsernameKey) ?? ""
//                    let service = detail.value(forKey: CNInstantMessageAddressServiceKey) ?? ""
//                    print("\t\(label):\(username) 服務:\(service)")
//                }
//
//                print("----------------")
            })
        } catch {
            print("讀取通訊錄出錯")
        }
    }
    
    /// 撥打電話
    func callPhone(_ phone: String) {
        if phone.isEmpty {
            print("電話号碼異常")
        } else {
            var tel = "tel://"+phone
            //去掉空格-不然有些電話号碼會使 URL 報 nil
            tel = tel.replacingOccurrences(of: " ", with: "", options: .literal, range: nil);
            print(tel)
            if let urls = URL(string: tel){
                //ios 10.0以上和一下調用不同的方法撥打電話-預設都會彈框詢問
                if #available(iOS 10.0, *) {
                    UIApplication.shared.open(urls, options: [:], completionHandler: {
                       (success) in
                        print("Open \(phone): \(success)")
                    })
                } else {
                    UIApplication.shared.openURL(urls)
                }
            }else{
                print("url 為空!")
            }
        }
    }
}
           

TelModel.swift

import UIKit

class TelModel: NSObject {
    //聯系人姓名
    var name:String?
    //聯系人電話
    var tel:String?
}
           

TelCell.swift

import UIKit

class TelCell: UITableViewCell {

    @IBOutlet weak var telName: UILabel!
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}