Skip to content
This repository has been archived by the owner on Apr 8, 2021. It is now read-only.

Commit

Permalink
Optimization and ios fix
Browse files Browse the repository at this point in the history
  • Loading branch information
enisn committed Aug 9, 2018
1 parent c9e3d31 commit b864fca
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 98 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Android.App;
using Android.App;
using Android.Content;
using Android.Database;
using Android.Provider;
using Plugin.ContactService.Shared;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Plugin.ContactService
{
Expand All @@ -14,16 +14,16 @@ namespace Plugin.ContactService
/// </summary>
public class ContactServiceImplementation : IContactService
{
public IList<Contact> GetContactList()
public IEnumerable<Contact> GetContactList(Func<Contact, bool> filter = null)
{
return GetContacts()
.ToList();
return GetContacts(filter);
//.ToList();
}


public Task<IList<Contact>> GetContactListAsync() { return Task.Run(() => GetContactList()); }
public Task<IEnumerable<Contact>> GetContactListAsync(Func<Contact, bool> filter = null) => Task.Run(() => GetContactList(filter));

private IEnumerable<Contact> GetContacts()
private IEnumerable<Contact> GetContacts(Func<Contact, bool> filter = null)
{
var uri = ContactsContract.Contacts.ContentUri;
//var ctx = Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity;
Expand All @@ -35,6 +35,9 @@ private IEnumerable<Contact> GetContacts()
{
var contact = CreateContact(cursor, ctx);

if (filter != null && !filter(contact))
continue;

if (!string.IsNullOrWhiteSpace(contact.Name))
yield return contact;
}
Expand All @@ -45,20 +48,18 @@ private static Contact CreateContact(ICursor cursor, Context ctx)
var contactId = GetString(cursor, ContactsContract.Contacts.InterfaceConsts.Id);
// var hasNumbers = GetString(cursor, ContactsContract.Contacts.InterfaceConsts.HasPhoneNumber) == "1";

var numbers = GetNumbers(ctx, contactId)
.ToList();
var emails = GetEmails(ctx, contactId)
.ToList();
var numbers = GetNumbers(ctx, contactId);
//.ToList();
var emails = GetEmails(ctx, contactId);
//.ToList();

var contact = new Contact
{
Name = GetString(cursor, ContactsContract.Contacts.InterfaceConsts.DisplayName),
PhotoUri = GetString(cursor, ContactsContract.Contacts.InterfaceConsts.PhotoUri),
PhotoUriThumbnail = GetString(cursor, ContactsContract.Contacts.InterfaceConsts.PhotoThumbnailUri),
Emails = emails,
Email = emails.LastOrDefault(),
Numbers = numbers,
Number = numbers.LastOrDefault()
};

return contact;
Expand All @@ -72,7 +73,7 @@ private static IEnumerable<string> GetNumbers(Context ctx, string contactId)
ContactsContract.CommonDataKinds.Phone.ContentUri,
null,
ContactsContract.CommonDataKinds.Phone.InterfaceConsts.ContactId + " = ?",
new[] {contactId},
new[] { contactId },
null
);

Expand All @@ -87,7 +88,7 @@ private static IEnumerable<string> GetEmails(Context ctx, string contactId)
ContactsContract.CommonDataKinds.Email.ContentUri,
null,
ContactsContract.CommonDataKinds.Email.InterfaceConsts.ContactId + " = ?",
new[] {contactId},
new[] { contactId },
null);

return ReadCursorItems(cursor, key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ namespace Plugin.ContactService
/// </summary>
public class ContactServiceImplementation : IContactService
{
public IList<Contact> GetContactList()
public IEnumerable<Contact> GetContactList(Func<Contact, bool> filter = null)
{
throw new NotImplementedException();
}

public Task<IList<Contact>> GetContactListAsync()
public Task<IEnumerable<Contact>> GetContactListAsync(Func<Contact, bool> filter = null)
{
throw new NotImplementedException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ namespace Plugin.ContactService
/// </summary>
public class ContactServiceImplementation : IContactService
{
public IList<Contact> GetContactList()
public IEnumerable<Contact> GetContactList(Func<Contact, bool> filter = null)
{
throw new NotImplementedException();
}

public Task<IList<Contact>> GetContactListAsync()
public Task<IEnumerable<Contact>> GetContactListAsync(Func<Contact, bool> filter = null)
{
throw new NotImplementedException();
}
Expand Down
122 changes: 61 additions & 61 deletions Plugin/ContactService/Platforms/iOS/ContactServiceImplementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;

namespace Plugin.ContactService
Expand All @@ -18,86 +17,87 @@ public class ContactServiceImplementation : IContactService
/// Gets contact in a background task
/// </summary>
/// <returns></returns>
public Task<IList<Contact>> GetContactListAsync()
{
return Task.Run<IList<Contact>>(() =>
{
return GetContactList();
});

}
public Task<IEnumerable<Contact>> GetContactListAsync(Func<Contact, bool> filter = null) => Task.Run(() => GetContactList(filter));

/// <summary>
/// Gets contact in main thread
/// !!!Not Recommended
/// </summary>
public IList<Contact> GetContactList()
public IEnumerable<Contact> GetContactList(Func<Contact, bool> filter = null)
{
try
//try
//{
var keysToFetch = new[] { CNContactKey.Identifier, CNContactKey.GivenName, CNContactKey.FamilyName, CNContactKey.EmailAddresses, CNContactKey.PhoneNumbers, CNContactKey.ImageDataAvailable, CNContactKey.ThumbnailImageData };
NSError error;
//var containerId = new CNContactStore().DefaultContainerIdentifier;
// using the container id of null to get all containers.
// If you want to get contacts for only a single container type, you can specify that here
var contactList = new List<CNContact>();
using (var store = new CNContactStore())
{
var keysToFetch = new[] { CNContactKey.Identifier, CNContactKey.GivenName, CNContactKey.FamilyName, CNContactKey.EmailAddresses, CNContactKey.PhoneNumbers, CNContactKey.ImageDataAvailable };
NSError error;
//var containerId = new CNContactStore().DefaultContainerIdentifier;
// using the container id of null to get all containers.
// If you want to get contacts for only a single container type, you can specify that here
var contactList = new List<CNContact>();
using (var store = new CNContactStore())
var allContainers = store.GetContainers(null, out error);
foreach (var container in allContainers)
{
var allContainers = store.GetContainers(null, out error);
foreach (var container in allContainers)
try
{
try
using (var predicate = CNContact.GetPredicateForContactsInContainer(container.Identifier))
{
using (var predicate = CNContact.GetPredicateForContactsInContainer(container.Identifier))
{
var containerResults = store.GetUnifiedContacts(predicate, keysToFetch, out error);
contactList.AddRange(containerResults);
}
var containerResults = store.GetUnifiedContacts(predicate, keysToFetch, out error);
contactList.AddRange(containerResults);
}
catch (Exception ex)
{
Debug.WriteLine("\n\n\n" + ex.ToString() + "\n\n\n");
}
catch (Exception ex)
{
Debug.WriteLine("\n\n\n" + ex.ToString() + "\n\n\n");

if (ex.GetType() != typeof(NullReferenceException))
Debug.WriteLine(ex.ToString());
continue;
}
if (ex.GetType() != typeof(NullReferenceException))
Debug.WriteLine(ex.ToString());
continue;
}
}
var contacts = new List<Contact>();
}
//var contacts = new List<Contact>();

foreach (var item in contactList)
{
if (item.GivenName == null) continue;
Contact _contact = new Contact();
_contact.Name = item.GivenName + " " + item.FamilyName;
foreach (var item in contactList)
{
if (item.GivenName == null) continue;
Contact _contact = new Contact();

if (item.PhoneNumbers != null)
{
foreach (var number in item.PhoneNumbers)
{
_contact.Number = number?.Value?.ToString();
_contact.Numbers.Add(number?.Value?.ToString());
}
}

if (filter != null && !filter(_contact))
continue;

if (item.EmailAddresses != null)
{
foreach (var email in item.EmailAddresses)
{
_contact.Email = email?.Value?.ToString();
_contact.Emails.Add(email?.Value?.ToString());
}
}
contacts.Add(_contact);
yield return _contact;
}

}

}
return contacts;
Contact CreateContact(CNContact contact)
{
return new Contact
{
Numbers = GetNumbers(contact),
Emails = GetEmails(contact),
Name = $"{contact.GivenName} {contact.FamilyName}",
//PhotoUri = //NOT IMPLEMENTED YET,
//PhotoUriThumbnail = //NOT IMPLEMENTED YET,

};
}

IEnumerable<string> GetNumbers(CNContact contact)
{
foreach (var number in contact.PhoneNumbers)
{
yield return number?.Value?.ToString();
}
catch (Exception ex)
}

IEnumerable<string> GetEmails(CNContact contact)
{
foreach (var email in contact.EmailAddresses)
{
Debug.WriteLine("\n\n\n" + ex.ToString() + "\n\n\n");
return new List<Contact>();
yield return email?.Value?.ToString();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ namespace Plugin.ContactService
/// </summary>
public class ContactServiceImplementation : IContactService
{
public IList<Contact> GetContactList()
public IEnumerable<Contact> GetContactList(Func<Contact, bool> filter = null)
{
throw new NotImplementedException();
}

public Task<IList<Contact>> GetContactListAsync()
public Task<IEnumerable<Contact>> GetContactListAsync(Func<Contact, bool> filter = null)
{
throw new NotImplementedException();
}
Expand Down
17 changes: 8 additions & 9 deletions Plugin/ContactService/Shared/Contact.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Generic;
using System.Linq;

namespace Plugin.ContactService.Shared
{
Expand All @@ -24,27 +23,27 @@ public class Contact
/// <summary>
/// Phone number of this contact
/// </summary>
public string Number { get; set; }
public string Number { get => Numbers.LastOrDefault(); }
/// <summary>
/// Email address of this contact
/// </summary>
public string Email { get; set; }
public string Email { get => Emails.LastOrDefault(); }
/// <summary>
/// If contact have multiple phone numbers
/// </summary>
public List<string> Numbers { get; set; }
public IEnumerable<string> Numbers { get; set; }
/// <summary>
/// IF contact have multiple email addresses
/// </summary>
public List<string> Emails { get; set; }
public IEnumerable<string> Emails { get; set; }

/// <summary>
/// Default Constructor
/// </summary>
public Contact()
{
Numbers = new List<string>();
Emails = new List<string>();
//Numbers = new List<string>();
//Emails = new List<string>();
}
/// <summary>
/// Displays contact name
Expand Down
4 changes: 2 additions & 2 deletions Plugin/ContactService/Shared/IContactService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ public interface IContactService
/// Gets contact in an awaitable background task
/// </summary>
/// <returns></returns>
Task<IList<Contact>> GetContactListAsync();
Task<IEnumerable<Contact>> GetContactListAsync(Func<Contact,bool> filter = null);
/// <summary>
/// Gets contacts in main thread
/// !!!NOT RECOMMENDED
/// </summary>
/// <returns></returns>
IList<Contact> GetContactList();
IEnumerable<Contact> GetContactList(Func<Contact, bool> filter = null);
}
}
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Read Contacts Data on iOS and Android

<a href="https://www.nuget.org/packages/Xamarin.Forms.Contacts/">
<img src="https://img.shields.io/badge/Nuget-1.0.5-blue.svg">
<img src="https://img.shields.io/badge/Nuget-1.0.6-blue.svg">
</a>

Easy usage in Portable Project:
Expand All @@ -11,6 +11,26 @@ Easy usage in Portable Project:
var contacts = await Plugin.ContactService.CrossContactService.Current.GetContactListAsync();
```


You can generate ObservableCollection like that:


```csharp
var contacts = await Plugin.ContactService.CrossContactService.Current.GetContactListAsync();

ObservableCollection<Contact> = new ObservableCollection<Contact>(contacts);

```


You can use filter like that:


```csharp
var contacts = await Plugin.ContactService.CrossContactService.Current.GetContactListAsync(x=>x.Emails.Count > 0);
```


DO NOT FORGET ADD THIS PERMISSIONS:

# ANDROID
Expand Down
3 changes: 3 additions & 0 deletions Xamarin.Forms.Contacts.sln
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
VisualStudioVersion = 15.0.27130.2036
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugin", "Plugin", "{2CB4010C-8053-4948-8D11-E1AEFBBCD2AB}"
ProjectSection(SolutionItems) = preProject
README.md = README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sample", "Sample", "{FA6DC839-C434-41D4-995B-DC9367E51765}"
EndProject
Expand Down
Loading

0 comments on commit b864fca

Please sign in to comment.