一、建立項目
這個很簡單,就不多說了
二、實作 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
}
}