Skip to content
This repository has been archived by the owner on Jan 29, 2024. It is now read-only.

Commit

Permalink
functions added for iOS
Browse files Browse the repository at this point in the history
  • Loading branch information
EinfachHans committed Jan 26, 2021
1 parent 7c625d8 commit 2847972
Show file tree
Hide file tree
Showing 3 changed files with 280 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/ios/ContactX.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class ContactX {
let labeledValues: [NSDictionary] = self.contact.emailAddresses.map { (ob: CNLabeledValue<NSString>) -> NSDictionary in
return [
"id": ob.identifier,
"type": CNLabeledValue<NSString>.localizedString(forLabel: ob.label ?? ""),
"type": ContactsX.mapLabelToSring(label: ob.label ?? ""),
"value": ob.value
]
}
Expand All @@ -25,7 +25,7 @@ class ContactX {
let labeledValues: [NSDictionary] = self.contact.phoneNumbers.map { (ob: CNLabeledValue<CNPhoneNumber>) -> NSDictionary in
return [
"id": ob.identifier,
"type": CNLabeledValue<CNPhoneNumber>.localizedString(forLabel: ob.label ?? ""),
"type": ContactsX.mapStringToLabel(string: ob.label ?? ""),
"value": ob.value.stringValue
]
}
Expand Down
218 changes: 218 additions & 0 deletions src/ios/ContactsX.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,198 @@ import ContactsUI
let result: CDVPluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: contactResult);
self.commandDelegate.send(result, callbackId: self._callbackId);
}

@objc(save:)
func saveOrModify(command: CDVInvokedUrlCommand) {
_callbackId = command.callbackId;

self.hasPermission { (granted) in
guard granted else {
self.returnError(error: ErrorCodes.PermissionDenied);
return;
}

let tmpContactOptions = command.argument(at: 0) as? NSDictionary;
if(tmpContactOptions == nil) {
self.returnError(error: ErrorCodes.WrongJsonObject, message: "You need to pass a contact object");
return;
}
let contactOptions = ContactXOptions.init(options: tmpContactOptions);

let retId: String?;
if(contactOptions.id == nil) {
retId = self.saveNewContact(contact: contactOptions);
} else {
retId = self.modifyContact(contact: contactOptions);
}

if(retId != nil) {
let contact = self.findById(id: retId!);
if(contact != nil) {
let result:CDVPluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: contact?.getJson() as! [String : Any]);
self.commandDelegate.send(result, callbackId: self._callbackId)
}
}
self.returnError(error: ErrorCodes.UnknownError);
}
}

func saveNewContact(contact: ContactXOptions) -> String? {
let newContact = CNMutableContact();
if(contact.firstName != nil) {
newContact.givenName = contact.firstName!;
}
if(contact.middleName != nil) {
newContact.middleName = contact.middleName!;
}
if(contact.familyName != nil) {
newContact.familyName = contact.familyName!;
}
if(contact.phoneNumbers != nil) {
newContact.phoneNumbers = contact.phoneNumbers!.map { (ob: ContactXValueTypeOptions) -> CNLabeledValue<CNPhoneNumber> in
return CNLabeledValue<CNPhoneNumber>(label: ContactsX.mapStringToLabel(string: ob.type), value: CNPhoneNumber(stringValue: ob.value));
};
}
if(contact.emails != nil) {
newContact.emailAddresses = contact.emails!.map { (ob: ContactXValueTypeOptions) -> CNLabeledValue<NSString> in
return CNLabeledValue<NSString>(label: ContactsX.mapStringToLabel(string: ob.type), value: ob.value as NSString);
};
}

let store = CNContactStore();
let saveRequest = CNSaveRequest();
saveRequest.add(newContact, toContainerWithIdentifier: nil);

do {
try store.execute(saveRequest);
if newContact.isKeyAvailable(CNContactIdentifierKey) {
return newContact.identifier;
}
return nil;
} catch {
return nil;
}
}

func modifyContact(contact: ContactXOptions) -> String? {
let existingContact = self.findById(id: contact.id!);
let editContact = existingContact!.contact.mutableCopy() as! CNMutableContact;

if(contact.firstName != nil) {
editContact.givenName = contact.firstName!;
}
if(contact.middleName != nil) {
editContact.middleName = contact.middleName!;
}
if(contact.familyName != nil) {
editContact.familyName = contact.familyName!;
}
if(contact.phoneNumbers != nil) {
if(contact.phoneNumbers?.count == 0) {
editContact.phoneNumbers = [];
} else {
var newNumbers: [CNLabeledValue<CNPhoneNumber>] = [];
outer: for newNumber in contact.phoneNumbers! {
for number in editContact.phoneNumbers {
if(newNumber.id != nil && number.identifier == newNumber.id!) {
newNumbers.append(number.settingLabel(ContactsX.mapStringToLabel(string: newNumber.type), value: CNPhoneNumber(stringValue: newNumber.value)));
continue outer;
}
}
newNumbers.append(CNLabeledValue(label: ContactsX.mapStringToLabel(string: newNumber.type), value: CNPhoneNumber(stringValue: newNumber.value)));
}
editContact.phoneNumbers = newNumbers;
}
}
if(contact.emails != nil) {
if(contact.emails!.count == 0) {
editContact.emailAddresses = [];
} else {
var newMails: [CNLabeledValue<NSString>] = [];
outer: for newMail in contact.emails! {
for mail in editContact.emailAddresses {
if(mail.identifier == newMail.id!) {
newMails.append(mail.settingLabel(ContactsX.mapStringToLabel(string: newMail.type), value: newMail.value as NSString));
continue outer;
}
}
newMails.append(CNLabeledValue(label: ContactsX.mapStringToLabel(string: newMail.type), value: newMail.value as NSString));
}
editContact.emailAddresses = newMails;
}
}

let store = CNContactStore();
let saveRequest = CNSaveRequest();
saveRequest.update(editContact);

do {
try store.execute(saveRequest);
if editContact.isKeyAvailable(CNContactIdentifierKey) {
return editContact.identifier;
}
return nil;
} catch {
return nil;
}
}

func findById(id: String) -> ContactX? {
let options = ContactsXOptions.init(options: [
"fields": [
"phoneNumbers": true,
"emails": true
]
]);
let keysToFetch = self.getKeysToFetch(options: options);
let predicate = CNContact.predicateForContacts(withIdentifiers: [id]);
let store = CNContactStore();
do {
let contacts = try store.unifiedContacts(matching: predicate, keysToFetch: keysToFetch as [NSString]);
if(contacts.count == 1) {
return ContactX(contact: contacts.first!, options: options);
}
return nil;
} catch {
return nil;
}
}

@objc(delete:)
func delete(command: CDVInvokedUrlCommand) {
_callbackId = command.callbackId;

self.hasPermission { (granted) in
guard granted else {
self.returnError(error: ErrorCodes.PermissionDenied);
return;
}

let id = command.argument(at: 0) as! String?;
if(id == nil) {
self.returnError(error: ErrorCodes.WrongJsonObject);
return;
}
let contact = self.findById(id: id!);
if(contact == nil) {
self.returnError(error: ErrorCodes.UnknownError);
return;
}

let store = CNContactStore();
let request = CNSaveRequest();
request.delete(contact!.contact.mutableCopy() as! CNMutableContact);

do {
try store.execute(request);

let result:CDVPluginResult = CDVPluginResult(status: CDVCommandStatus_OK);
self.commandDelegate.send(result, callbackId: self._callbackId)
} catch {
self.returnError(error: ErrorCodes.UnknownError)
}
}
}

@objc(hasPermission:)
func hasPermission(command: CDVInvokedUrlCommand) {
Expand Down Expand Up @@ -159,6 +351,32 @@ import ContactsUI
_callbackId = nil;
}
}

static func mapStringToLabel(string: String) -> String {
switch string {
case "home":
return CNLabelHome;
case "work":
return CNLabelWork;
case "mobile":
return CNLabelPhoneNumberMobile;
default:
return CNLabelOther;
}
}

static func mapLabelToSring(label: String) -> String {
switch label {
case CNLabelHome:
return "home";
case CNLabelWork:
return "work";
case CNLabelPhoneNumberMobile:
return "mobile";
default:
return "other";
}
}
}

enum ErrorCodes:NSNumber {
Expand Down
60 changes: 60 additions & 0 deletions src/ios/ContactsXOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,63 @@ class ContactsXOptions {
}

}

class ContactXOptions {
var id: String? = nil;
var firstName: String? = nil;
var middleName: String? = nil;
var familyName: String? = nil;
var phoneNumbers: [ContactXValueTypeOptions]? = nil;
var emails: [ContactXValueTypeOptions]? = nil;

init(options: NSDictionary?) {
if(options != nil) {
id = options?.value(forKey: "id") as? String;
firstName = options?.value(forKey: "firstName") as? String;
middleName = options?.value(forKey: "middleName") as? String;
familyName = options?.value(forKey: "familyName") as? String;
let phonenumberArray = options?.value(forKey: "phoneNumbers") as? [NSDictionary];
if(phonenumberArray != nil) {
phoneNumbers = self.parsePhoneNumbers(array: phonenumberArray!);
}
let emailsArray = options?.value(forKey: "emails") as? [NSDictionary];
if(emailsArray != nil) {
emails = self.parseEmails(array: emailsArray!);
}
}
}

private func parsePhoneNumbers(array: [NSDictionary]) -> [ContactXValueTypeOptions] {
var numbers: [ContactXValueTypeOptions] = [];
for numberObject in array {
let finalNumber = ContactXValueTypeOptions.init(options: numberObject);
if(finalNumber.type != "" && finalNumber.value != "") {
numbers.append(finalNumber);
}
}
return numbers;
}

private func parseEmails(array: [NSDictionary]) -> [ContactXValueTypeOptions] {
var mails: [ContactXValueTypeOptions] = [];
for mailObject in array {
let finalMail = ContactXValueTypeOptions.init(options: mailObject);
if(finalMail.type != "" && finalMail.value != "") {
mails.append(finalMail);
}
}
return mails;
}
}

class ContactXValueTypeOptions {
var id: String? = nil;
var type: String;
var value: String;

init(options: NSDictionary) {
id = options.value(forKey: "id") as? String;
type = options.value(forKey: "type") as? String ?? "";
value = options.value(forKey: "value") as? String ?? "";
}
}

0 comments on commit 2847972

Please sign in to comment.