Question

I am using monotouch and mailkit library. I am retrieving emails from a pop3 mail account and present them on a tableview. I would like to create 3 sections on my tableview. Section1 “Today”, this where display the emails that i received today. Section2 “Yesterday”, this section where display the emails that i received yesterday. Section3 “Older Emails”, this section where display the emails that i have received 2 days before today. Is this possible? This is my code until now:

public class TableSource : UITableViewSource {
protected string[] tableItems;
protected string cellIdentifier = "TableCell";
public TableSource (string[] items)
{
    tableItems = items;
}
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
// do something when row is selected
}
public override int RowsInSection (UITableView tableview, int section)
{
   return tableItems.Length;
}
public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
// request a recycled cell to save memory
   UITableViewCell cell = tableView.DequeueReusableCell (cellIdentifier);   
if (cell == null)
   cell = new UITableViewCell (UITableViewCellStyle.Default, cellIdentifier);
 cell.TextLabel.Text = tableItems[indexPath.Row];
return cell;
}
}

// This is the loop where i load items to my array and assign as a datasource to my tableview
string[] mycell = new string[200];
for (int i = 0; i < count; i++) {
     var message = client.GetMessage (count, cancel.Token);
     string m = Convert.ToString (message.Date);
     DateTime mydate = Convert.ToDateTime (m);
     string s = mydate.ToString ("MMMM dd, yyyy H:mm") + " " + "Subject:" + Convert.ToString (message.Subject) + " " + "Sender" + Convert.ToString (message.From) ;
     mycell [i] = (Convert.ToString (s));
}
tblmytable = new UITableView (View.Bounds);
Add (tblmytable);
tblmytable.Source = new TableSource (mycell);   
//---------EDIT----------------------
//Email Object
public class EmailItem
{
public DateTime RecievedDate{ get; set; }
public string Subject{ get; set; }
public string Sender{ get; set; }
public EmailItem(DateTime recieveddate, string subject, string sender)
{
   RecievedDate=recieveddate;
   Subject=subject;
   Sender = sender;
 }
}
//Function for isolate the today emails
public  void TodayEmails(EmailItem[] emailarray, EmailItem[] myemailarray)
{
   DateTime curdate = DateTime.Today;
   for (int i = 0; i < emailarray.Length; i++) {
      if (emailarray [i].RecievedDate == curdate) {
          myemailarray [i] = emailarray [i];
    }
 }
}
Was it helpful?

Solution

First of all I suggest to rewrite the TodayEmails method:

public List<EmailItem> TodayEmails(List<EmailItem> emailArray)
{
    foreach(var emailItem in emailArray)
    {
       if(emailItem.RecievedDate.Date == DateTime.Today.Date)
       {
           yield return emailItem;
       }
    }
}

Then rewrite the contructor of table source:

private List<EmailItem> _emailItems;

public TableSource (List<EmailItem> emailItems)
{
    _emailItems= emailItems;
}

You should override NumberOfSections to set the num of sections

public override int NumberOfSections(UITableView tableView)
{
    return 3;
}

Then in method RowsInSection you should return the needed num of rows for each section, so:

public override int RowsInSection(UITableView tableview, int section)
{
    if(section == 0)
    {
        return TodayEmails(_emailItems).Count;  //I don't know where your TodayEmails located, so added just the name of it
    }
    else if(section == 1)
    {
        return YesterdayEmails(_emailItems).Count;  // The same as for TodayEmails
    }
    else
    {
        return OtherEmails(_emailItems).Count;  // The same as for TodayEmails
    }
}

And finally in GetCell method you should return the needed cell for the section:

public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
    UITableViewCell cell = tableView.DequeueReusableCell (cellIdentifier);   
    if (cell == null)
       cell = new UITableViewCell (UITableViewCellStyle.Default, cellIdentifier);

    if(indexPath.Section == 0)
    {
        cell.TextLabel.Text = TodayEmails(_emailItems)[indexPath.Row].Subject;
    }
    else if(indexPath.Section == 1)
    {
        cell.TextLabel.Text = YesterdayEmails(_emailItems)[indexPath.Row].Subject;
    }
    else
    {
        cell.TextLabel.Text = OtherEmails(_emailItems)[indexPath.Row].Subject;
    }

    return cell;
}

OTHER TIPS

I think the answer choper gave probably already answers your question and I think it's a pretty good answer (and probably deserves the accepted answer status).

What I would add, though, is that I don't think you want to be downloading these messages from the POP3 server and keeping them all in memory to populate your UITableView.

Instead, what I would suggest, is that you download the messages to disk and keep a database of the information you want to use for displaying in the UITableView (Subject, To, From, Date, maybe a bool to say whether or not the message has attachments, the location of the message saved on disk, maybe the first few lines of the message body if you want to do something like iOS's default mail app does) and then using the database to populate your UITableView.

The reason for this is that email messages can be quite large and you don't want to load a bunch of them into memory which simply won't scale to any significant number of messages.

Loading a screen full of records from a sqlite database is also probably going to be faster than loading and parsing that same number of messages (MimeKit is really fast, but probably not faster than sqlite is at loading a brief summary of the message).

Hope that helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top