ios swift

时间:2018-04-28 15:17:11

标签: ios swift grand-central-dispatch gmail-api google-api-objc-client

我有一个包含消息ID的数组。通过将这些ID传递给方法,我可以使用批量请求从谷歌服务器获取消息/电子邮件。它适用于数百个ID传递,但问题是当有数千个ID时,它需要更多时间来获取消息。所以为了避免这种情况,我决定以相应的方式执行任务。我集成的Google客户端库是https://github.com/google/google-api-objectivec-client-for-rest/wiki。对于messagesGet.query,引用是http://cocoadocs.org/docsets/GoogleAPIClientForREST/1.2.0/Classes/GTLRGmailQuery_UsersMessagesGet.html。对于批处理请求参考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
        }
    }
}

上述过程需要时间来避免我将数组分成大小为100且传递的子数组。

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)])
    }
}

} 然后使用dispatchQueue Concurrent执行我想获取消息但不满意结果。

    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
                }
            }
        }
    }
}

我是否遵循正确的并发方法。任何其他获取逻辑将是很大的帮助。在这个答案中,有人告诉一个线程获取ids fetch和4个线程来获取消息。我怎样才能使用4个线程实现它。

1 个答案:

答案 0 :(得分:0)

至于上面的代码,结果是否重复?如果是这样,我认为问题在于逻辑:

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
            }
        }
    }
}

由于您已告知调度队列迭代&#39; msgIDBatches.count&#39;时间,然后在你的内部代码中,你应该检索&#39; subArray&#39;直接用下标索引&#39;只有一次:

DispatchQueue.concurrentPerform(iterations: msgIDBatches.count) { (index) in
    let subArray = msgIDBatches[index]
    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
        }
    }
}