I've an array it contains Ids of the message. By passing those ids to a method i can able to fetch messages/emails from google server by using Batch request. It works fine for hundreds of ids passing but the problem is when there is thousands of Ids it was taking more time to fetch messsages. So to avoid this i've decided to execute task in concuurently. google client library which i've integrated is https://github.com/google/google-api-objectivec-client-for-rest/wiki . For messagesGet.query refrence is http://cocoadocs.org/docsets/GoogleAPIClientForREST/1.2.0/Classes/GTLRGmailQuery_UsersMessagesGet.html . For batch request reference https://developers.google.com/gmail/api/guides/batch .
var messageIDes = [AnyObject]() //143b3e9751e6b3fd,141c2194fb6e4d6d...thousands if Ids
func fetchingMessagesWithIDs()
{
let batchQuery = GTLRBatchQuery()
for eachID in messageIDes{
let query = GTLRGmailQuery_UsersMessagesGet.query(withUserId: "me", identifier: eachID as! String)
query.fields = "id,labelIds, payload(headers, parts )"
batchQuery.addQuery(query)
}
service.executeQuery(batchQuery) { (ticket:GTLRServiceTicket, object:Any?, error:Error?) in
if error == nil{
print("Object is \(String(describing: object))") //Contains Full mail Body
}
}
}
The above process takes time to avoid that i'm deviding array into subarrays of size 100 and passing.
extension Array {
func divideBy(by size: Int) -> [[Element]] {
return stride(from: 0, to: self.count, by: size).map {
Array(self[$0..<Swift.min($0 + size, self.count)])
}
}
} Then Using dispatchQueue Concurrent perform i want to fetch messages but not satisfied with result.
var msgIDBatches = [[String]]()
func DividingMsgIdsandPassing(){
self.msgIDBatches = self.messageIDes.divideBy(by: 100) as! [[String]] //array inside subarray of size 100 elements.
DispatchQueue.concurrentPerform(iterations: msgIDBatches.count) { (index) in
for subArray in msgIDBatches{
let batchQuery = GTLRBatchQuery()
for messageID in subArray {
let query = GTLRGmailQuery_UsersMessagesGet.query(withUserId: "me", identifier: messageID as! String)
query.fields = "id,labelIds, payload(headers, parts )"
batchQuery.addQuery(query)
}
service.executeQuery(batchQuery) { (ticket:GTLRServiceTicket, object:Any?, error:Error?) in
if error == nil{
print("Object is \(String(describing: object))") //Contains Full mail Body
}
}
}
}
}
Am i following correct approach for concurrency. Any other fetching logic will be great help. In this answer somebody told one thread for ids fetch and 4 threads for messages fetch. how can i achieve it using 4 threads.
As for above code, does the result duplicated? If so, I think the problem is in the logic:
Since you have tell the dispatch queue to iterate 'msgIDBatches.count' times, then in your inner code, you should retrieve the 'subArray' directly by subscript with 'index' only once: