我一直在尝试JSON-encode / -decode Swift的CNContact
对象的通用方式(我的意思是我想确定对象在运行时保存的属性,我不想很难编码其属性),但我没有设法这样做。我的问题是:有没有办法在Swift 4中实现这种行为,如果是的话,怎么办呢?
答案 0 :(得分:1)
不,CNContact
未根据official documentation进行更改,因此它不符合Codable
协议,后者只是Encodeable & Decodable
的类型。您可以看到当前符合Encodable和Decodable的类列表,并在此处查看CNContact
不在其中。
但是,您可以为CNContact
编写扩展名,使其符合上述协议。
以下是如何使用CNContact
中的JSONSerialization
框架对Swift3
对象进行编码的示例。请注意,这只是一个示例,因此我没有解析所有可能的字段,如果CNContact
对象中不存在某个值,则使用此实现,{{1也许。此外,解码器功能未完全实现,但如果您检查编码器的工作方式,则可以轻松实现。
JSON
键的名称也随着结构任意选择,所以你可以改变其中任何一个。
下面的代码是一个完整的,有效的游乐场文件,所以如果你愿意,你可以自己测试。
JSON
答案 1 :(得分:0)
尝试使用简单联系人选择。
func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
var name = ""
var email = ""
var mobile = ""
var address = ""
var companyname = ""
var jobtitle = ""
var organization = ""
var workaddress = ""
var worknumber = ""
var personalurl = ""
var companyurl = ""
var otherurl = ""
var othernumber = ""
var otheraddress = ""
var homeemail = ""
var workemail = ""
var otheremail = ""
var dataAll = NSMutableArray()
if contact != nil
{
dataAll = NSMutableArray()
if (contact?.isKeyAvailable(CNContactGivenNameKey))! {
let name2 = contact?.familyName
name = (contact?.givenName)! + " " + name2!
UserDefaults.standard.set(name, forKey: "name")
}
if (contact?.isKeyAvailable(CNContactOrganizationNameKey))!
{
companyname = (contact?.organizationName)!
//var dic : NSDictionary = [:]
if companyname != "" {
let dic : [String : AnyObject] = ["name":companyname as AnyObject,
"type":"companyname" as AnyObject,
"typeof":"companyname" as AnyObject]
dataAll.add(dic)
}
}
let designation = contact?.jobTitle
if (designation?.isEmpty)!
{
}
else
{
jobtitle = designation!
//let dic : [String : AnyObject] = ["designation":jobtitle as AnyObject]
let dic : [String : AnyObject] = ["name":jobtitle as AnyObject,
"type":"designation" as AnyObject,
"typeof":"designation" as AnyObject
]
dataAll.add(dic)
}
if (contact?.isKeyAvailable(CNContactPhoneNumbersKey))!{
if (contact?.phoneNumbers.count == 0)
{
}
else
{
for phoneNumber:CNLabeledValue in (contact?.phoneNumbers)! {
let number = phoneNumber.value
let number2 = number.stringValue
let lable :String = CNLabeledValue<NSString>.localizedString(forLabel: phoneNumber.label! )
let dic : [String : AnyObject] = ["name":number2 as AnyObject,
"type":lable as AnyObject,
"typeof":"phonenumber" as AnyObject]
dataAll.add(dic)
if number2 != ""
{
}
if lable == "home"
{
if number2 == ""
{
}
else
{
mobile = number.stringValue
let number2 = String(mobile.digitsOnly())!
}
}
if lable == "work"
{
if number2 == ""
{
}
else
{
worknumber = number.stringValue
}
}
if lable == "mobile"
{
if number2 == ""
{
}
else
{
othernumber = number.stringValue
}
}
}
}
}
if (contact?.isKeyAvailable(CNContactEmailAddressesKey))! {
if (contact?.emailAddresses.count == 0)
{
}
else
{
for emaiadd:CNLabeledValue in (contact?.emailAddresses)! {
let name2 = (emaiadd.value as String) as String
if name2 != ""
{
UserDefaults.standard.set(emaiadd.value as String, forKey: "mainemail")
}
let lable :String = CNLabeledValue<NSString>.localizedString(forLabel: emaiadd.label! )
// let dic : [String : AnyObject] = [lable:emaiadd.value as String as AnyObject]
let dic : [String : AnyObject] = ["name":name2 as AnyObject,
"type":lable as AnyObject,
"typeof":"email" as AnyObject]
dataAll.add(dic)
if lable == "home"
{
if name2 == ""
{
}
else
{
email = emaiadd.value as String
}
}
if lable == "work"
{
if name2 == ""
{
}
else
{
workemail = emaiadd.value as String
}
}
if lable == "other"
{
if name2 == ""
{
}
else
{
otheremail = emaiadd.value as String
}
}
}
}
}
if (contact?.isKeyAvailable(CNContactPostalAddressesKey))! {
for addres:CNLabeledValue in (contact?.postalAddresses)! {
let addre = addres.value
let addre2 = addre.street
let lable :String = CNLabeledValue<NSString>.localizedString(forLabel: addres.label! )
let dic : [String : AnyObject] = ["name":addre2 as AnyObject,
"type":lable as AnyObject,
"typeof":"address" as AnyObject]
dataAll.add(dic)
if lable == "home"
{
if addre2 == ""
{
}
else
{
address = addre.street
}
}
if lable == "work"
{
if addre2 == ""
{
}
else
{
workaddress = addre.street
}
}
if lable == "other"
{
if addre2 == ""
{
}
else
{
otheraddress = addre.street
}
}
print(lable + (addre.street))
}
}
if (contact?.isKeyAvailable(CNContactUrlAddressesKey))! {
for urladd:CNLabeledValue in (contact?.urlAddresses)! {
let url2 = (urladd.value as String) as String
let lable :String = CNLabeledValue<NSString>.localizedString(forLabel: urladd.label! )
let dic : [String : AnyObject] = ["name":url2 as AnyObject,
"type":lable as AnyObject,
"typeof":"url" as AnyObject]
dataAll.add(dic)
if lable == "home"
{
if url2 == ""
{
}
else
{
personalurl = urladd.value as String
}
}
if lable == "work"
{
if url2 == ""
{
}
else
{
companyurl = urladd.value as String
}
}
if lable == "other"
{
if url2 == ""
{
}
else
{
otherurl = urladd.value as String
}
}
}
}
if (contact?.isKeyAvailable(CNContactImageDataKey))! {
let image = contact?.imageData
let utf8str = image?.base64EncodedString()
}
dataArr = [["code": "Mobile", "title": othernumber],["code": "Work Number", "title": worknumber],["code": "OtherMobile", "title": number2],["code": "Email", "title": email],["code": "WorkEmail", "title": workemail],["code": "OtherEmail", "title": otheremail],["code": "Address", "title": address],["code": "Work Address", "title": workaddress],["code": "OtherAddress", "title": otheraddress],["code": "Company Name", "title": companyname],["code": "Designation", "title": jobtitle],["code": "Personal Website", "title": personalurl],["code": "Company Website", "title": companyurl],["code": "Other Website", "title": otherurl]]
}
}
在按钮操作中添加此代码
let contactPickerViewController = CNContactPickerViewController()
contactPickerViewController.delegate = self
present(contactPickerViewController, animated: true, completion: nil)