I’ve an app that was written in UIKit. It is too massive, and it could be a lot too time consuming at this level to transform it to SwiftUI.
I need to incorporate the brand new restricted contacts into this app. The way in which it is at present written every little thing works high-quality aside from exhibiting the restricted contacts within the contact picker.
I’ve downloaded and gone although the Apple tutorial app however I am having bother considering it by way of into UIKit. After a few hours I made a decision I need assistance.
I perceive I would like to drag the contact IDs of the contacts which are within the restricted contacts listing. Unsure how to do this or find out how to get it to show within the picker. Any assist could be significantly appreciated.
func requestAccess(completionHandler: @escaping (_ accessGranted: Bool) -> Void)
{
swap CNContactStore.authorizationStatus(for: .contacts)
{
case .approved:
completionHandler(true)
case .denied:
showSettingsAlert(completionHandler)
case .restricted, .notDetermined:
CNContactStore().requestAccess(for: .contacts) { granted, error in
if granted
{
completionHandler(true)
} else {
DispatchQueue.predominant.async { [weak self] in
self?.showSettingsAlert(completionHandler)
}
}
}
// iOS 18 solely
case .restricted:
completionHandler(true)
@unknown default: break
}
}
// A textual content subject that shows the title of the chosen contact
@IBAction func contact_Fld_Tapped(_ sender: TextField_Designable)
{
sender.resignFirstResponder()
// The contact ID that's saved to the Db
getTheCurrentContactID()
let theAlert = UIAlertController(title: Ok.Titles.chooseAContact, message: nil, preferredStyle: .actionSheet)
// Create a brand new contact
let addContact = UIAlertAction(title: Ok.Titles.newContact, model: .default) { [weak self] _ in
self?.requestAccess { _ in
let openContact = CNContact()
let vc = CNContactViewController(forNewContact: openContact)
vc.delegate = self // this delegate CNContactViewControllerDelegate
DispatchQueue.predominant.async {
self?.current(UINavigationController(rootViewController: vc), animated: true)
}
}
}
// Choose contact from contact listing
let getContact = UIAlertAction(title: Ok.Titles.fromContacts, model: .default) { [weak self] _ in
self?.requestAccess { _ in
self?.contactPicker.delegate = self
DispatchQueue.predominant.async {
self?.current(self!.contactPicker, animated: true)
}
}
}
// Edit the present contact
let editBtn = UIAlertAction(title: Ok.Titles.editContact, model: .default) { [weak self] _ in
self?.requestAccess { _ in
let retailer = CNContactStore()
var vc = CNContactViewController()
do {
let descriptor = CNContactViewController.descriptorForRequiredKeys()
let editContact = attempt retailer.unifiedContact(withIdentifier: self!.oldContactID, keysToFetch: [descriptor])
vc = CNContactViewController(for: editContact)
} catch {
print("Getting contact to edit failed: (self!.VC_String) (error)")
}
vc.delegate = self // delegate for CNContactViewControllerDelegate
self?.navigationController?.isNavigationBarHidden = false
self?.navigationController?.navigationItem.hidesBackButton = false
self?.navigationController?.pushViewController(vc, animated: true)
}
}
let cancel = UIAlertAction(title: Ok.Titles.cancel, model: .cancel) { _ in }
if oldContactID.isEmpty
{
editBtn.isEnabled = false
}
theAlert.addAction(getContact) // Choose from contacts
theAlert.addAction(addContact) // Create new contact
theAlert.addAction(editBtn) // Edit this contact
theAlert.addAction(cancel)
let popOver = theAlert.popoverPresentationController
popOver?.sourceView = sender
popOver?.sourceRect = sender.bounds
popOver?.permittedArrowDirections = .any
current(theAlert,animated: true)
}
func requestAccess(completionHandler: @escaping (_ accessGranted: Bool) -> Void)
{
swap CNContactStore.authorizationStatus(for: .contacts)
{
case .approved:
completionHandler(true)
case .denied:
showSettingsAlert(completionHandler)
case .restricted, .notDetermined:
CNContactStore().requestAccess(for: .contacts) { granted, error in
if granted
{
completionHandler(true)
} else {
DispatchQueue.predominant.async { [weak self] in
self?.showSettingsAlert(completionHandler)
}
}
}
// iOS 18 solely
case .restricted:
completionHandler(true)
@unknown default: break
}
}
// MARK: - Contact Picker Delegate
extension AddEdit_Quote_VC: CNContactPickerDelegate
{
func contactPickerDidCancel(_ picker: CNContactPickerViewController)
{
}
func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty)
{
}
func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact)
{
selectedContactID = contact.identifier
let firm: String = contact.organizationName
let companyText = firm == "" ? Ok.Titles.noCompanyName : contact.organizationName
contactNameFld_Outlet.textual content = CNContactFormatter.string(from: contact, model: .fullName)!
companyFld_Outlet.textual content = companyText
save_Array[0] = Ok.AppFacing.true_App
setSaveBtn_AEQuote()
}
}
// MARK: - Create Contact Delegate
// Modifying a contact
extension AddEdit_Quote_VC: CNContactViewControllerDelegate
{
func contactViewController(_ viewController: CNContactViewController, shouldPerformDefaultActionFor property: CNContactProperty) -> Bool
{
return false
}
func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?)
{
selectedContactID = contact?.identifier ?? ""
if selectedContactID != ""
{
let firm: String = contact?.organizationName ?? ""
let companyText = firm == "" ? Ok.Titles.noCompanyName : contact!.organizationName
contactNameFld_Outlet.textual content = CNContactFormatter.string(from: contact!, model: .fullName)
companyFld_Outlet.textual content = companyText
getTheCurrentContactID()
if selectedContactID != oldContactID
{
save_Array[0] = Ok.AppFacing.true_App
setSaveBtn_AEQuote()
}
}
dismiss(animated: true, completion: nil)
}
}