forked from mirrors/linphone-iphone
Add edit view for native contact
This commit is contained in:
parent
abd5461f54
commit
5d0ce2c8f3
9 changed files with 280 additions and 75 deletions
|
|
@ -50,6 +50,7 @@
|
|||
D7C3650A2AF001C300FE6142 /* EditContactFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C365092AF001C300FE6142 /* EditContactFragment.swift */; };
|
||||
D7C3650C2AF0084000FE6142 /* EditContactViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C3650B2AF0084000FE6142 /* EditContactViewModel.swift */; };
|
||||
D7C3650E2AF15BF200FE6142 /* PhotoPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C3650D2AF15BF200FE6142 /* PhotoPicker.swift */; };
|
||||
D7C48DF42AFA66F900D938CB /* EditContactController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C48DF32AFA66F900D938CB /* EditContactController.swift */; };
|
||||
D7D1698C2AE66FA500109A5C /* MagicSearchSingleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D1698B2AE66FA500109A5C /* MagicSearchSingleton.swift */; };
|
||||
D7D24D132AC1B4E800C6F35B /* NotoSans-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7D24D0D2AC1B4E800C6F35B /* NotoSans-Medium.ttf */; };
|
||||
D7D24D142AC1B4E800C6F35B /* NotoSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7D24D0E2AC1B4E800C6F35B /* NotoSans-Regular.ttf */; };
|
||||
|
|
@ -116,6 +117,7 @@
|
|||
D7C365092AF001C300FE6142 /* EditContactFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditContactFragment.swift; sourceTree = "<group>"; };
|
||||
D7C3650B2AF0084000FE6142 /* EditContactViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditContactViewModel.swift; sourceTree = "<group>"; };
|
||||
D7C3650D2AF15BF200FE6142 /* PhotoPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoPicker.swift; sourceTree = "<group>"; };
|
||||
D7C48DF32AFA66F900D938CB /* EditContactController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditContactController.swift; sourceTree = "<group>"; };
|
||||
D7D1698B2AE66FA500109A5C /* MagicSearchSingleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MagicSearchSingleton.swift; sourceTree = "<group>"; };
|
||||
D7D24D0D2AC1B4E800C6F35B /* NotoSans-Medium.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NotoSans-Medium.ttf"; sourceTree = "<group>"; };
|
||||
D7D24D0E2AC1B4E800C6F35B /* NotoSans-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NotoSans-Regular.ttf"; sourceTree = "<group>"; };
|
||||
|
|
@ -172,6 +174,7 @@
|
|||
D74C9D002ACB098C0021626A /* PermissionManager.swift */,
|
||||
D7D1698B2AE66FA500109A5C /* MagicSearchSingleton.swift */,
|
||||
D7C3650D2AF15BF200FE6142 /* PhotoPicker.swift */,
|
||||
D7C48DF32AFA66F900D938CB /* EditContactController.swift */,
|
||||
);
|
||||
path = Utils;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -568,6 +571,7 @@
|
|||
D72992392ADD7F68003AF125 /* HistoryContactFragment.swift in Sources */,
|
||||
D7B5066D2AEFA9B900CEB4E9 /* ContactInnerFragment.swift in Sources */,
|
||||
D7E6D04D2AEBD77600A57AAF /* CustomBottomSheet.swift in Sources */,
|
||||
D7C48DF42AFA66F900D938CB /* EditContactController.swift in Sources */,
|
||||
D74C9D012ACB098C0021626A /* PermissionManager.swift in Sources */,
|
||||
D7702EF22AC7205000557C00 /* WelcomeView.swift in Sources */,
|
||||
D71FCA7F2AE1397200D2E43E /* ContactsListViewModel.swift in Sources */,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
import linphonesw
|
||||
import Contacts
|
||||
import SwiftUI
|
||||
import ContactsUI
|
||||
|
||||
final class ContactsManager: ObservableObject {
|
||||
|
||||
|
|
@ -110,6 +111,7 @@ final class ContactsManager: ObservableObject {
|
|||
try store.enumerateContacts(with: request, usingBlock: { (contact, _) in
|
||||
DispatchQueue.main.sync {
|
||||
let newContact = Contact(
|
||||
identifier: contact.identifier,
|
||||
firstName: contact.givenName,
|
||||
lastName: contact.familyName,
|
||||
organizationName: contact.organizationName,
|
||||
|
|
@ -203,6 +205,8 @@ final class ContactsManager: ObservableObject {
|
|||
if friend != nil {
|
||||
friend!.edit()
|
||||
|
||||
friend!.nativeUri = contact.identifier
|
||||
|
||||
try friend!.setName(newValue: contact.firstName + " " + contact.lastName)
|
||||
|
||||
let friendvCard = friend!.vcard
|
||||
|
|
@ -284,6 +288,55 @@ final class ContactsManager: ObservableObject {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getCNContact(friend: Friend, completion: @escaping (CNContact?) -> Void) {
|
||||
DispatchQueue.global().async {
|
||||
let store = CNContactStore()
|
||||
store.requestAccess(for: .contacts) { (granted, error) in
|
||||
if let error = error {
|
||||
print("failed to request access", error)
|
||||
return
|
||||
}
|
||||
if granted {
|
||||
let keys = [CNContactEmailAddressesKey, CNContactPhoneNumbersKey,
|
||||
CNContactFamilyNameKey, CNContactGivenNameKey, CNContactNicknameKey,
|
||||
CNContactPostalAddressesKey, CNContactIdentifierKey,
|
||||
CNInstantMessageAddressUsernameKey, CNContactInstantMessageAddressesKey,
|
||||
CNContactImageDataKey, CNContactThumbnailImageDataKey, CNContactOrganizationNameKey]
|
||||
let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
|
||||
do {
|
||||
try store.enumerateContacts(with: request, usingBlock: { (contact, _) in
|
||||
if contact.identifier == friend.nativeUri {
|
||||
var contactFetched = contact
|
||||
if !contactFetched.areKeysAvailable([CNContactViewController.descriptorForRequiredKeys()]) {
|
||||
do {
|
||||
contactFetched = try store.unifiedContact(withIdentifier: contact.identifier, keysToFetch: [CNContactViewController.descriptorForRequiredKeys()])
|
||||
completion(contactFetched)
|
||||
}
|
||||
catch {
|
||||
completion(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
} catch let error {
|
||||
print("Failed to enumerate contact", error)
|
||||
}
|
||||
} else {
|
||||
print("access denied")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getFriend(contact: Contact) -> Friend? {
|
||||
if friendList != nil {
|
||||
let friend = friendList!.friends.first(where: {$0.nativeUri == contact.identifier})
|
||||
return friend
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PhoneNumber {
|
||||
|
|
@ -293,6 +346,7 @@ struct PhoneNumber {
|
|||
|
||||
struct Contact: Identifiable {
|
||||
var id = UUID()
|
||||
var identifier: String
|
||||
var firstName: String
|
||||
var lastName: String
|
||||
var organizationName: String
|
||||
|
|
|
|||
|
|
@ -208,6 +208,9 @@
|
|||
},
|
||||
"Edit contact" : {
|
||||
|
||||
},
|
||||
"Edit Contact" : {
|
||||
|
||||
},
|
||||
"Edit picture" : {
|
||||
|
||||
|
|
|
|||
|
|
@ -74,5 +74,10 @@ struct ContactFragment: View {
|
|||
}
|
||||
|
||||
#Preview {
|
||||
ContactFragment(contactViewModel: ContactViewModel(), editContactViewModel: EditContactViewModel(), isShowDeletePopup: .constant(false), isShowDismissPopup: .constant(false))
|
||||
ContactFragment(
|
||||
contactViewModel: ContactViewModel(),
|
||||
editContactViewModel: EditContactViewModel(),
|
||||
isShowDeletePopup: .constant(false),
|
||||
isShowDismissPopup: .constant(false)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
import SwiftUI
|
||||
import Contacts
|
||||
|
||||
struct ContactInnerFragment: View {
|
||||
|
||||
|
|
@ -30,6 +31,8 @@ struct ContactInnerFragment: View {
|
|||
@State private var orientation = UIDevice.current.orientation
|
||||
|
||||
@State private var informationIsOpen = true
|
||||
@State private var presentingEditContact = false
|
||||
@State private var cnContact: CNContact?
|
||||
|
||||
@Binding var isShowDeletePopup: Bool
|
||||
@Binding var showingSheet: Bool
|
||||
|
|
@ -44,8 +47,7 @@ struct ContactInnerFragment: View {
|
|||
.frame(height: 0)
|
||||
|
||||
HStack {
|
||||
if !(orientation == .landscapeLeft
|
||||
|| orientation == .landscapeRight
|
||||
if !(orientation == .landscapeLeft || orientation == .landscapeRight
|
||||
|| UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) {
|
||||
Image("caret-left")
|
||||
.renderingMode(.template)
|
||||
|
|
@ -61,21 +63,40 @@ struct ContactInnerFragment: View {
|
|||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
NavigationLink(destination: EditContactFragment(editContactViewModel: editContactViewModel, isShowEditContactFragment: .constant(false), isShowDismissPopup: $isShowDismissPopup)) {
|
||||
Image("pencil-simple")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.orangeMain500)
|
||||
.frame(width: 25, height: 25, alignment: .leading)
|
||||
.padding(.top, 2)
|
||||
}
|
||||
.simultaneousGesture(
|
||||
TapGesture().onEnded {
|
||||
editContactViewModel.selectedEditFriend = magicSearch.lastSearch[contactViewModel.indexDisplayedFriend!].friend
|
||||
editContactViewModel.resetValues()
|
||||
if contactViewModel.indexDisplayedFriend != nil
|
||||
&& magicSearch.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil
|
||||
&& magicSearch.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.nativeUri != nil && !magicSearch.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.nativeUri!.isEmpty {
|
||||
Button(action: {
|
||||
ContactsManager.shared.getCNContact(friend: magicSearch.lastSearch[contactViewModel.indexDisplayedFriend!].friend!) { result in
|
||||
cnContact = result
|
||||
if cnContact != nil {
|
||||
presentingEditContact.toggle()
|
||||
}
|
||||
}
|
||||
}, label: {
|
||||
Image("pencil-simple")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.orangeMain500)
|
||||
.frame(width: 25, height: 25, alignment: .leading)
|
||||
.padding(.top, 2)
|
||||
})
|
||||
} else {
|
||||
NavigationLink(destination: EditContactFragment(editContactViewModel: editContactViewModel, isShowEditContactFragment: .constant(false), isShowDismissPopup: $isShowDismissPopup)) {
|
||||
Image("pencil-simple")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.orangeMain500)
|
||||
.frame(width: 25, height: 25, alignment: .leading)
|
||||
.padding(.top, 2)
|
||||
}
|
||||
)
|
||||
.simultaneousGesture(
|
||||
TapGesture().onEnded {
|
||||
editContactViewModel.selectedEditFriend = magicSearch.lastSearch[contactViewModel.indexDisplayedFriend!].friend
|
||||
editContactViewModel.resetValues()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(height: 50)
|
||||
|
|
@ -143,7 +164,6 @@ struct ContactInnerFragment: View {
|
|||
Spacer()
|
||||
|
||||
Button(action: {
|
||||
|
||||
}, label: {
|
||||
VStack {
|
||||
HStack(alignment: .center) {
|
||||
|
|
@ -458,8 +478,7 @@ struct ContactInnerFragment: View {
|
|||
&& magicSearch.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.starred == true ? "heart-fill" : "heart")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(contactViewModel.indexDisplayedFriend != nil
|
||||
&& magicSearch.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil
|
||||
.foregroundStyle(contactViewModel.indexDisplayedFriend != nil && magicSearch.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil
|
||||
&& magicSearch.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.starred == true ? Color.redDanger500 : Color.grayMain2c500)
|
||||
.frame(width: 25, height: 25)
|
||||
Text(contactViewModel.indexDisplayedFriend != nil
|
||||
|
|
@ -600,6 +619,14 @@ struct ContactInnerFragment: View {
|
|||
.onRotate { newOrientation in
|
||||
orientation = newOrientation
|
||||
}
|
||||
.sheet(isPresented: $presentingEditContact) {
|
||||
NavigationView {
|
||||
AnyView(EditContactView(contact: $cnContact)
|
||||
.navigationBarTitle("Edit Contact")
|
||||
.navigationBarTitleDisplayMode(.inline))
|
||||
.edgesIgnoringSafeArea(.top)
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationViewStyle(.stack)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,64 +18,77 @@
|
|||
*/
|
||||
|
||||
import SwiftUI
|
||||
import linphonesw
|
||||
|
||||
struct ContactsInnerFragment: View {
|
||||
|
||||
@ObservedObject var magicSearch = MagicSearchSingleton.shared
|
||||
@ObservedObject var contactViewModel: ContactViewModel
|
||||
|
||||
@State private var isFavoriteOpen = true
|
||||
|
||||
@Binding var showingSheet: Bool
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
if !magicSearch.lastSearch.filter({ $0.friend?.starred == true }).isEmpty {
|
||||
HStack(alignment: .center) {
|
||||
Text("Favourites")
|
||||
.default_text_style_800(styleSize: 16)
|
||||
|
||||
Spacer()
|
||||
|
||||
Image(isFavoriteOpen ? "caret-up" : "caret-down")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.grayMain2c600)
|
||||
.frame(width: 25, height: 25, alignment: .leading)
|
||||
}
|
||||
.padding(.top, 30)
|
||||
.padding(.horizontal, 16)
|
||||
.background(.white)
|
||||
.onTapGesture {
|
||||
withAnimation {
|
||||
isFavoriteOpen.toggle()
|
||||
}
|
||||
}
|
||||
|
||||
if isFavoriteOpen {
|
||||
FavoriteContactsListFragment(
|
||||
contactViewModel: contactViewModel,
|
||||
favoriteContactsListViewModel: FavoriteContactsListViewModel(),
|
||||
showingSheet: $showingSheet)
|
||||
.zIndex(-1)
|
||||
.transition(.move(edge: .top))
|
||||
}
|
||||
|
||||
HStack(alignment: .center) {
|
||||
Text("All contacts")
|
||||
.default_text_style_800(styleSize: 16)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding(.top, 10)
|
||||
.padding(.horizontal, 16)
|
||||
}
|
||||
ContactsListFragment(contactViewModel: contactViewModel, contactsListViewModel: ContactsListViewModel(), showingSheet: $showingSheet)
|
||||
}
|
||||
.navigationBarHidden(true)
|
||||
}
|
||||
|
||||
@Environment(\.scenePhase) var scenePhase
|
||||
|
||||
@ObservedObject var magicSearch = MagicSearchSingleton.shared
|
||||
@ObservedObject var contactViewModel: ContactViewModel
|
||||
|
||||
@State private var isFavoriteOpen = true
|
||||
|
||||
@Binding var showingSheet: Bool
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
if !magicSearch.lastSearch.filter({ $0.friend?.starred == true }).isEmpty {
|
||||
HStack(alignment: .center) {
|
||||
Text("Favourites")
|
||||
.default_text_style_800(styleSize: 16)
|
||||
|
||||
Spacer()
|
||||
|
||||
Image(isFavoriteOpen ? "caret-up" : "caret-down")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.grayMain2c600)
|
||||
.frame(width: 25, height: 25, alignment: .leading)
|
||||
}
|
||||
.padding(.top, 30)
|
||||
.padding(.horizontal, 16)
|
||||
.background(.white)
|
||||
.onTapGesture {
|
||||
withAnimation {
|
||||
isFavoriteOpen.toggle()
|
||||
}
|
||||
}
|
||||
|
||||
if isFavoriteOpen {
|
||||
FavoriteContactsListFragment(
|
||||
contactViewModel: contactViewModel,
|
||||
favoriteContactsListViewModel: FavoriteContactsListViewModel(),
|
||||
showingSheet: $showingSheet)
|
||||
.zIndex(-1)
|
||||
.transition(.move(edge: .top))
|
||||
}
|
||||
|
||||
HStack(alignment: .center) {
|
||||
Text("All contacts")
|
||||
.default_text_style_800(styleSize: 16)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding(.top, 10)
|
||||
.padding(.horizontal, 16)
|
||||
}
|
||||
ContactsListFragment(contactViewModel: contactViewModel, contactsListViewModel: ContactsListViewModel(), showingSheet: $showingSheet)
|
||||
}
|
||||
.navigationBarHidden(true)
|
||||
.onChange(of: scenePhase) { newPhase in
|
||||
if newPhase == .active {
|
||||
ContactsManager.shared.fetchContacts()
|
||||
print("Active")
|
||||
} else if newPhase == .inactive {
|
||||
print("Inactive")
|
||||
} else if newPhase == .background {
|
||||
print("Background")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
ContactsInnerFragment(contactViewModel: ContactViewModel(), showingSheet: .constant(false))
|
||||
ContactsInnerFragment(contactViewModel: ContactViewModel(), showingSheet: .constant(false))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -472,6 +472,7 @@ struct EditContactFragment: View {
|
|||
|
||||
func addOrEditFriend() {
|
||||
let newContact = Contact(
|
||||
identifier: editContactViewModel.identifier,
|
||||
firstName: editContactViewModel.firstName,
|
||||
lastName: editContactViewModel.lastName,
|
||||
organizationName: editContactViewModel.company,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ class EditContactViewModel: ObservableObject {
|
|||
|
||||
@Published var selectedEditFriend: Friend?
|
||||
|
||||
@Published var identifier: String = ""
|
||||
@Published var firstName: String = ""
|
||||
@Published var lastName: String = ""
|
||||
@Published var sipAddresses: [String] = []
|
||||
|
|
@ -36,6 +37,7 @@ class EditContactViewModel: ObservableObject {
|
|||
}
|
||||
|
||||
func resetValues() {
|
||||
identifier = (selectedEditFriend == nil ? "" : selectedEditFriend!.nativeUri) ?? ""
|
||||
firstName = (selectedEditFriend == nil ? "" : selectedEditFriend!.vcard?.givenName) ?? ""
|
||||
lastName = (selectedEditFriend == nil ? "" : selectedEditFriend!.vcard?.familyName) ?? ""
|
||||
sipAddresses = []
|
||||
|
|
|
|||
96
Linphone/Utils/EditContactController.swift
Normal file
96
Linphone/Utils/EditContactController.swift
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2023 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-iphone
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import SwiftUI
|
||||
import ContactsUI
|
||||
import linphonesw
|
||||
|
||||
struct EditContactView: UIViewControllerRepresentable {
|
||||
|
||||
class Coordinator: NSObject, CNContactViewControllerDelegate, UINavigationControllerDelegate {
|
||||
func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
|
||||
if let cnc = contact {
|
||||
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
|
||||
self.parent.contact = cnc
|
||||
|
||||
let newContact = Contact(
|
||||
identifier: cnc.identifier,
|
||||
firstName: cnc.givenName,
|
||||
lastName: cnc.familyName,
|
||||
organizationName: cnc.organizationName,
|
||||
jobTitle: "",
|
||||
displayName: cnc.nickname,
|
||||
sipAddresses: cnc.instantMessageAddresses.map { $0.value.service == "SIP" ? $0.value.username : "" },
|
||||
phoneNumbers: cnc.phoneNumbers.map { PhoneNumber(numLabel: $0.label ?? "", num: $0.value.stringValue)},
|
||||
imageData: ""
|
||||
)
|
||||
|
||||
let imageThumbnail = UIImage(data: contact!.thumbnailImageData ?? Data())
|
||||
ContactsManager.shared.saveImage(
|
||||
image: imageThumbnail
|
||||
?? ContactsManager.shared.textToImage(
|
||||
firstName: cnc.givenName.isEmpty
|
||||
&& cnc.familyName.isEmpty
|
||||
&& cnc.phoneNumbers.first?.value.stringValue != nil
|
||||
? cnc.phoneNumbers.first!.value.stringValue
|
||||
: cnc.givenName, lastName: cnc.familyName),
|
||||
name: cnc.givenName + cnc.familyName + String(Int.random(in: 1...1000)) + ((imageThumbnail == nil) ? "-default" : ""),
|
||||
contact: newContact,
|
||||
linphoneFriend: false,
|
||||
existingFriend: ContactsManager.shared.getFriend(contact: newContact))
|
||||
|
||||
MagicSearchSingleton.shared.searchForContacts(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
|
||||
}
|
||||
}
|
||||
viewController.dismiss(animated: true, completion: {})
|
||||
}
|
||||
|
||||
func contactViewController(_ viewController: CNContactViewController, shouldPerformDefaultActionFor property: CNContactProperty) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
var parent: EditContactView
|
||||
|
||||
init(_ parent: EditContactView) {
|
||||
self.parent = parent
|
||||
}
|
||||
}
|
||||
|
||||
@Binding var contact: CNContact?
|
||||
|
||||
init(contact: Binding<CNContact?>) {
|
||||
self._contact = contact
|
||||
}
|
||||
|
||||
typealias UIViewControllerType = CNContactViewController
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
return Coordinator(self)
|
||||
}
|
||||
|
||||
func makeUIViewController(context: UIViewControllerRepresentableContext<EditContactView>) -> EditContactView.UIViewControllerType {
|
||||
let vcontact = contact != nil ? CNContactViewController(for: contact!) : CNContactViewController(forNewContact: CNContact())
|
||||
vcontact.isEditing = true
|
||||
vcontact.delegate = context.coordinator
|
||||
return vcontact
|
||||
}
|
||||
|
||||
func updateUIViewController(_ uiViewController: EditContactView.UIViewControllerType, context: UIViewControllerRepresentableContext<EditContactView>) {
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue