在iOS中使用GTLGmailMessage读取电子邮件

时间:2015-07-07 07:54:05

标签: ios xcode gmail gmail-api

我已按照以下步骤操作:https://developers.google.com/gmail/api/quickstart/ios我可以成功获取电子邮件列表,但我需要阅读每一个。

我就是这样做的:

- (void)fetchEmails {
    self.output.text = @"Getting emails...";
    NSString *newAPIStr = @"";
    newAPIStr = [NSString stringWithFormat:@"https://www.googleapis.com/gmail/v1/users/me/profile"];

    NSURL *url = [NSURL URLWithString:newAPIStr];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPMethod:@"GET"];

    GTMOAuth2Authentication *currentAuth= self.service.authorizer;
    GTMHTTPFetcher* myFetcher = [GTMHTTPFetcher fetcherWithRequest:request];
    [myFetcher setAuthorizer:currentAuth];
    [myFetcher beginFetchWithCompletionHandler:^(NSData *retrievedData, NSError *error) {
        if (error != nil)
        {
            // status code or network error
            NSLog(@"Ha ocurrido un error");
        }
        else {
            // succeeded
            NSDictionary* json = [NSJSONSerialization JSONObjectWithData:retrievedData options:kNilOptions error:&error];
            NSLog(@"json==>%@",json);
            userid=[json objectForKey:@"emailAddress"];

            GTLQueryGmail *query = [GTLQueryGmail queryForUsersMessagesList];
            [self.service executeQuery:query delegate:self didFinishSelector:@selector(displayResultMessageListWithTicket:finishedWithObject:error:)];

        }
    }];        
}

我必须打电话给"个人资料"因为我不知道获取用户ID的另一种方式,然后我会收到电子邮件列表。

- (void)displayResultMessageListWithTicket:(GTLServiceTicket *)ticket
                    finishedWithObject:(GTLGmailListMessagesResponse *)emailsResponse error:(NSError *)error 
{
    if (error == nil) 
    {
        NSMutableString *labelString = [[NSMutableString alloc] init];

        NSLog(@"emailsResponse =%@",emailsResponse);
        if (emailsResponse.messages.count > 0) 
        {
            [labelString appendString:@"Labels:\n"];
            NSMutableArray *gmailMessageIds = [[NSMutableArray alloc]  init];

            for (GTLGmailMessage *message in emailsResponse.messages)
            {
                NSString *mess = message.identifier;
                [gmailMessageIds addObject:mess];
            }

            GTLBatchQuery *batchQuery = [GTLBatchQuery batchQuery];

            [gmailMessageIds enumerateObjectsUsingBlock:^(NSString *messageId, NSUInteger idx, BOOL *stop) {
                GTLQueryGmail *query = [GTLQueryGmail queryForUsersMessagesGet];
                //query.userId = ;
                query.identifier = [NSString stringWithFormat:@"%llx", [messageId unsignedLongLongValue]];
                query.format = kGTLGmailFormatRaw;

                [batchQuery addQuery:query];
            }];


            [self.service executeQuery:batchQuery completionHandler:^(GTLServiceTicket *ticket, GTLBatchResult *result, NSError *error) {

                NSArray *gmailMessages = result.successes.allValues; // This is an array of GTLGmailMessage objects
                for (GTLGmailMessage *message in gmailMessages)
                {  
                    [labelString appendFormat:@"%@\n", message.JSONString];
                }
            }];

        } else {
            [labelString appendString:@"No emails found."];
        }
        self.output.text = labelString;
    } else {
        [self showAlert:@"Error" message:error.localizedDescription];
    }
}

我遇到的问题是gmailMessages包含100个没有内容的项目

GTLBatchResult 0x7ffc39d66a50 (successes:100 failures:0)

迭代它......每条消息都有0个键/值对

message GTLGmailMessage *   0 key/value pairs   0x00007ffc39d50700

还有另一种获取每封电子邮件的方式吗?我也尝试过:

GTLQueryGmail *query = [GTLQueryGmail queryForUsersMessages];
query.identifier = [NSString stringWithFormat:@"%llx", [messageId unsignedLongLongValue]];
query.format = kGTLGmailFormatRaw;
[self.service executeQuery:query delegate:self didFinishSelector:@selector(displayResultWithTicket:finishedWithObject:error:)];

但我认为我有同样的问题。

我还必须说我复制了GTLBatchQuery from this post,我必须将NSNumber *messageId更改为NSString *messageId

[gmailMessageIds enumerateObjectsUsingBlock:^(NSNumber *messageId, NSUInteger idx, BOOL *stop)

2 个答案:

答案 0 :(得分:3)

这段代码很快就行了。将逻辑传递给Objective C相对容易。

// MARK: - Construct a query and get a list of upcoming labels from the gmail API
    class func fetchEmails() {
        let appd = UIApplication.sharedApplication().delegate as! AppDelegate
        println("Getting Emails ")
        let query = GTLQueryGmail.queryForUsersMessagesList()
        appd.service.executeQuery(query,
            delegate: self,
            didFinishSelector: "displayResultWithTicket:finishedWithObject:error:"
        )
    }

    //get Emails {id:"15015408a4a88b4e" threadId:"15015408a4a88b4e"}
    class func displayResultWithTicket(ticket : GTLServiceTicket, finishedWithObject listMessageResponse : GTLGmailListMessagesResponse, error : NSError?) {
        let appd = UIApplication.sharedApplication().delegate as! AppDelegate
        if let error = error {
            //show your error
            return
        }

        for dictMessage in listMessageResponse.messages {
            var tmpDict2 = dictMessage as! GTLGmailMessage
            let ident = tmpDict2.identifier

            let query = GTLQueryGmail.queryForUsersMessagesGet()
            query.identifier = ident
//            query.format = "metadata" //default full
            appd.service.executeQuery(query,
                delegate: self,
                didFinishSelector: "displayResultWithTicketEachMessages:finishedWithObject:error:"
            )
        }
    }

    // Get each email
    class func displayResultWithTicketEachMessages(ticket : GTLServiceTicket, finishedWithObject eachMessageResponse : GTLGmailMessage, error : NSError?) {
        if let error = error {
            Utils.showAlert("Error 2", message: error.localizedDescription)
            return
        } else {
            logicForSaveMailInfo(eachMessageResponse)
        }
    }

class func logicForSaveMailInfo(eachMessageResponse: GTLGmailMessage) {
        var labelId = eachMessageResponse.labelIds[0] as! String
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        if labelId == "INBOX" {
            var mailInformationDict = NSMutableDictionary()
            mailInformationDict.setValue(eachMessageResponse.snippet as String, forKey: "snippet")
            mailInformationDict.setValue(eachMessageResponse.identifier as String, forKey: "gmailId")
            mailInformationDict.setValue(eachMessageResponse.internalDate, forKey: "internaldate")

            let payloadArray = eachMessageResponse.payload.headers as NSArray

            for obj in payloadArray {
                var payloadObj = obj as! GTLGmailMessagePartHeader
                if payloadObj.name == "Subject" {
                    mailInformationDict.setValue(payloadObj.value, forKey: "subject")
                }

                if payloadObj.name == "From" {
                    var fromStr = payloadObj.value
                    var index2 = fromStr.rangeOfString("<", options: .BackwardsSearch)?.startIndex
                    var substring2 = ""
                    if index2 != nil {
                        substring2 = fromStr.substringToIndex(index2!)
                    } else {
                        substring2 = fromStr as String
                    }

                    mailInformationDict.setValue(substring2, forKey: "from")
                }

                if payloadObj.name == "To" {
                    var fromStr = payloadObj.value
                    var index2 = fromStr.rangeOfString("<", options: .BackwardsSearch)?.startIndex
                    var substringTo = ""
                    if index2 != nil {
                        substringTo = fromStr.substringToIndex(index2!)
                    } else {
                        substringTo = fromStr as String
                    }

                    mailInformationDict.setValue(substringTo, forKey: "to")
                }
            }
            var parts = eachMessageResponse.payload.parts
            var decodedBody: NSString?
            if parts != nil {
                let body: AnyObject? = parts[0].valueForKey("body")
                if body!.valueForKey("data") != nil {
                    var base64DataString =  body!.valueForKey("data") as! String
                    base64DataString = base64DataString.stringByReplacingOccurrencesOfString("_", withString: "/", options: NSStringCompareOptions.LiteralSearch, range: nil)
                    base64DataString = base64DataString.stringByReplacingOccurrencesOfString("-", withString: "+", options: NSStringCompareOptions.LiteralSearch, range: nil)

                    let decodedData = NSData(base64EncodedString: base64DataString, options:NSDataBase64DecodingOptions(rawValue: 0))
                    decodedBody = NSString(data: decodedData!, encoding: NSUTF8StringEncoding)
                }

            }
        }
        //Create counter for know when finish
        if appDelegate.emailData.count == messageEmailsCounter {
            println("finish charge emails")
        }
    }

如果需要帮助,请告诉我。

答案 1 :(得分:2)

当你有这个时,

`GTLQueryGmail *query = [GTLQueryGmail queryForUsersMessagesGet];`

您还需要指定一些参数 比如

`query.format=@"full"; query.format= @"payload"`

您可以阅读有关此here

的更多信息