2014-01-13 49 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);