2014-01-13 50 views
9

我有一个iPad应用程序,允许用户使用Mailcore2访问他们的Gmail帐户。我认为我了解了Gmail的线程标识,消息标识和UID之间的区别,直到我仔细查看Mailcore2在执行消息获取操作时返回给我的内容。我希望有人能澄清我的困惑。通过Mailcore 2获取Gmail:线程ID与消息ID与UID

这是我觉得我从Gmail的文档知道:

1)线程ID组一起消息(有属于同一对话的一部分自己的消息ID和的UID)

2)UID是特定于一个消息,并且是唯一的仅向包含它

3)的消息ID是特定于一个消息,并且横跨一个帐户的所有文件夹独特的文件夹

我也做了以下假设:

1)线程有一个线程ID和消息的集合。线程没有消息ID或UID。

2)的消息具有的消息ID,UID和线程ID(即使它是在一个线程正在抓取消息由UID获取它们具有在被请求落入UID消息的唯一消息)

3) UID的范围。

4)属于同一线程的消息将具有不同的UID和消息ID,但具有相同的线程ID。

好的,假设上面的说法是正确的,我会认为在通过UID在Mailcore2中进行典型的邮件提取时,我会收到一个电子邮件数组,并从这些邮件中查看他们的线程ID,示例并重建客户端上的线程。 但是,我似乎回到线程而不是电子邮件。此外,我得到的每个线程都不一定包含其所有“子”消息。

因此,例如,如果我的收件箱中有两个线程,每个线程都包含五条消息,Mailcore会以MCOIMAPMessages的形式向我返回一个2个“电子邮件”数组。每个“电子邮件”都有一个线程ID,一个消息ID和一个UID。所以我不确定如何访问这两个线程中包含的电子邮件。我看到有一个引用数组...但检查这个对象没有显示任何有用的东西。当我记录每个线程的内容时,我只收到部分内容 - 比如说线程中的5条消息中的4条。不知道这是否是Mailcore或我的保存过程中的错误,因为我不完全理解这是如何工作的。

这里是我的代码来获取信息:

//创建提取操作获得第一(10)文件夹中的邮件(第一个fetch是通过序列号进行,后面的读取通过UID

uint64_t location = MAX([info messageCount] - DefaultPageSize + 1, 1); 
uint64_t size = serverMessageCount < DefaultPageSize ? serverMessageCount - 1 : DefaultPageSize - 1; 

MCOIndexSet *numbers = [MCOIndexSet indexSetWithRange:MCORangeMake(location, size)]; 

MCOIMAPMessagesRequestKind kind = MCOIMAPMessagesRequestKindUid | 
     MCOIMAPMessagesRequestKindFullHeaders | 
     MCOIMAPMessagesRequestKindFlags | 
     MCOIMAPMessagesRequestKindHeaders | 
     MCOIMAPMessagesRequestKindInternalDate; 

if ([capabilities containsIndex:MCOIMAPCapabilityGmail]) { 
     kind |= MCOIMAPMessagesRequestKindGmailLabels | MCOIMAPMessagesRequestKindGmailThreadID | MCOIMAPMessagesRequestKindGmailMessageID; 
     self.gmailCapability = YES; 
     } 

fetchLatestEmails ([self.imapSession fetchMessagesByNumberOperationWithFolder:folder.folderId requestKind:kind numbers:numbers]); 

//执行取

void (^fetchLatestEmails)(MCOIMAPFetchMessagesOperation *) = ^(MCOIMAPFetchMessagesOperation *fetchOperation) { 

    [fetchOperation start:^(NSError *error, NSArray *emails, MCOIndexSet *vanishedMessages) { 

    if (nil != error) { 
     failure(error); 
     NSLog(@"the fetch error is %@", error); 
     return; 
    } 

    [self.dataManager performBatchedChanges:^{ 
     if ([emails count] !=0) { 

     MCOIndexSet *savedThreadIds = [[MCOIndexSet alloc]init]; 

     for (MCOIMAPMessage *email in emails) { 

      //do stuff with emails 

      Thread *thread = [self.dataManager fetchOrInsertNewThreadForFolder:folder threadId:email.gmailThreadID ?: email.gmailMessageID ?: email.uid error:nil]; 

      if (nil != thread) { 

      [savedThreadIds addIndex:thread.threadId]; 

      [self.dataManager updateOrInsertNewEmailForThread:thread uid:email.uid messageId:email.gmailMessageID date:email.header.receivedDate subject:email.header.subject from:email.header.from.mailbox to:[email.header.to valueForKey:@"mailbox"] cc:[email.header.cc valueForKey:@"mailbox"] labels:labels flags:flags error:nil]; 

      } 

      if (nil != error) { 
      failure(error); 
      return; 
      } 

     } 

     [savedThreadIds enumerateIndexes:^(uint64_t threadId) { 
      [self.dataManager updateFlagsForThreadWithThreadId:threadId inFolder:folder]; 
     }]; 

     } 

     NSError *folderUpdateError; 
     [self.dataManager updateFolder:folder withMessageCount:serverMessageCount error:&folderUpdateError]; 

    } error:&error]; 

    if (nil == error) { 

     [self refreshFolder:folder success:^{ 
     success(); 
     }failure:^(NSError *error) { 

     }]; 

    } else { 
     failure(error); 
    } 
    }]; 
}; 

显然有什么不妥,在这里我的Gmail或Mailcore2的理解而言,如果任何人都可以指出我的误解我WOU我很感激。

回答

9

在打开Mailcore和一些研究的问题后,我发现我自己的问题的答案。

首先,我对UID,gmailMessageID和gmailThreadID的假设是正确的。令人困惑的是,我在网上查看了我的电子邮件帐户的Gmail对话视图,并期望我的Mailcore提取匹配它。这不会发生,因为会话视图正如名称所暗示的那样将对话的所有消息(即使是收件箱中收到的消息的答复)拼接在一起 - 通常,这些消息将在“已发送”或“全部邮件”中找到'文件夹。换句话说,从Mailcore获取的内容看起来不完整,仅仅是因为它正在获取收件箱中的ACTUALLY(或者从中获取消息的任何文件夹)。这不包括对传入消息的回复。为了包含此类消息(即重新创建Gmail的会话视图),我知道必须通过使用消息的gmailThreadID执行搜索操作来从“所有邮件”(或者我认为是“发送”邮件)中获取发送的消息利益。

在测试我的Mailcore读取操作时,将Web会话视图切换为“关闭”我的Gmail帐户,使测试更加清晰。

+0

告诉我一些想法,我想在单个邮件中获得所有邮件对话。现在,我正在将每个对话都分开放在不同的邮件中。 – iSara

+0

自从我做完这件事以来,我们已经有一段时间了,但是对于我的回忆,您将分开获取所有消息,然后在您的身边,您必须连接在一起,这些消息具有相同的threadID以重新创建对话。 – jac300

+0

感谢您的意见。你能给我示例代码吗?这对我会更好。 – iSara

0

找到答案 获取gmailThreadID我们需要添加MCOIMAPMessagesRequestKindGmailThreadID。在像下面的例子那样获取请求。

MCOIMAPMessagesRequestKind requestKind = (MCOIMAPMessagesRequestKind) 
    (MCOIMAPMessagesRequestKindHeaders | MCOIMAPMessagesRequestKindStructure | 
    MCOIMAPMessagesRequestKindInternalDate | MCOIMAPMessagesRequestKindHeaderSubject | 
    MCOIMAPMessagesRequestKindFlags | MCOIMAPMessagesRequestKindGmailThreadID);