如何发送SKPSMTPMessage的电子邮件,它将在电子邮件客户端解析好?

时间:2014-05-18 10:57:27

标签: ios objective-c email ios7 smtp

我一直在尝试将SKPSMTPMessage用于我正在创建的iOS应用程序。该应用确实立即发送电子邮件,但似乎某些客户端的电子邮件视图存在一些问题。

我可以在Gmail上正确看到该电子邮件,但我无法正确使用Airmail,它显示为空电子邮件。

查看电子邮件的代码,对我来说似乎“好”,我不知道发生了什么。

以下是以电子邮件形式发送的代码。

Delivered-To: edited@gmail.com
Received: by 10.194.33.198 with SMTP id t6csp161338wji;
        Sun, 18 May 2014 01:58:13 -0700 (PDT)
X-Received: by 10.43.138.210 with SMTP id it18mr25804198icc.23.1400403493134;
        Sun, 18 May 2014 01:58:13 -0700 (PDT)
Return-Path: <bounces+256657-1972-edited=gmail.com@sendgrid.info>
Received: from o1.b99.sendgrid.net (o1.b99.sendgrid.net. [208.115.235.3])
        by mx.google.com with SMTP id au7si6505972igc.48.2014.05.18.01.58.12
        for <edited@gmail.com>;
        Sun, 18 May 2014 01:58:13 -0700 (PDT)
Received-SPF: pass (google.com: domain of bounces+256657-1972-edited=gmail.com@sendgrid.info designates 208.115.235.3 as permitted sender) client-ip=208.115.235.3;
Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of bounces+256657-1972-edited=gmail.com@sendgrid.info designates 208.115.235.3 as permitted sender) smtp.mail=bounces+256657-1972-edited=gmail.com@sendgrid.info;
       dkim=pass header.i=@sendgrid.me
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sendgrid.me; 
  h=from:to:content-type:mime-version:subject:x-feedback-id; 
  s=smtpapi; bh=1gap02jh/1VKT+wxEZZuQWStvy0=; b=HFYnzTR3lNEIlBOuiy
  SLwK1Px7Lluo/tVq7wdsIa1Wyv6pbkKx4/JnPxhw3xls4WPgmyrZ8xCvbFXXFWIx
  IvXoCkZJvpg1TNqwZkpry4mW1JfQ1PTUv27lDUZGANkX1Lok7IVxUyMPuK63gOgK
  0rjCAoTALabZWrY4qSP8aVlfc=
Received: by mf182.sendgrid.net with SMTP id mf182.18991.537876231
        Sun, 18 May 2014 08:58:11 +0000 (UTC)
Received: from localhost (host-87-242-224-202.ppp.onetel.net.uk [87.242.224.202])
  by ismtpd-026 (SG) with ESMTP id 1460e8d79b4.2412.7462b
  for <edited@gmail.com>; Sun, 18 May 2014 08:58:11 +0000 (GMT)
Date: Sun, 18 May 2014 09:58:11 +0100
Message-id: <1C33AFA6A19E4E8F8C9F6E631F64C8C0@smtp.sendgrid.net>
From:note@edited.com
To:edited@gmail.com
Content-Type: multipart/mixed; boundary="SKPSMTPMessage--Separator--Delimiter"
Mime-Version: 1.0
Subject:Message from Me
X-SG-EID: BJe7cohFb5FdMOzj4ylEqIH38EB2ynRmLXAsLFCZ07JGI1WXoEFGqBqvYj7/w5+f8v5gwaPbTNko4vDw1IArlAD8ChLhkRLEGh9r/jEpxrZ1qCoZXpVOneVRhNmnnBFhWydd9Rn5FzHyFx4lwLmNL28I0B8WM5OGXYGRlIrHdsw=
X-Feedback-ID: 256657:UMrjcMh3M2hIu7P3CZOEj4QTBRK+KuIuZrDj8e2//Mk=:UMrjcMh3M2hIu7P3CZOEj4QTBRK+KuIuZrDj8e2//Mk=:SG

--SKPSMTPMessage--Separator--Delimiter
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=UTF-8;
 format=flowed

This is a test
--SKPSMTPMessage--Separator--Delimiter


--SKPSMTPMessage--Separator--Delimiter--

真的不知道这个问题。我唯一能想到的是,在电子邮件的末尾添加了两个分隔符,但我无法找到何时发生这种情况。

This is the file负责发送部件并附加分隔符分隔符。

- (BOOL)sendParts
{
    NSMutableString *message = [[NSMutableString alloc] init];
    static NSString *separatorString = @"--SKPSMTPMessage--Separator--Delimiter\r\n";

    CFUUIDRef   uuidRef   = CFUUIDCreate(kCFAllocatorDefault);
    NSString    *uuid     = (NSString *)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, uuidRef));
    CFRelease(uuidRef);

    NSDate *now = [[NSDate alloc] init];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

    [dateFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss Z"];

    [message appendFormat:@"Date: %@\r\n", [dateFormatter stringFromDate:now]];
    [message appendFormat:@"Message-id: <%@@%@>\r\n", [(NSString *)uuid stringByReplacingOccurrencesOfString:@"-" withString:@""], self.relayHost];

    [message appendFormat:@"From:%@\r\n", fromEmail];


    if ((self.toEmail != nil) && (![self.toEmail isEqualToString:@""]))
    {
        [message appendFormat:@"To:%@\r\n", self.toEmail];
    }

    if ((self.ccEmail != nil) && (![self.ccEmail isEqualToString:@""]))
    {
        [message appendFormat:@"Cc:%@\r\n", self.ccEmail];
    }

    [message appendString:@"Content-Type: multipart/mixed; boundary=\"SKPSMTPMessage--Separator--Delimiter\"\r\n"];
    [message appendString:@"Mime-Version: 1.0\r\n"];
    [message appendFormat:@"Subject:%@\r\n\r\n",subject];
    [message appendString:separatorString];

    NSData *messageData = [message dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];

    NSLog(@"C: %s", [messageData bytes]);
    if (CFWriteStreamWriteFully((__bridge CFWriteStreamRef)outputStream, (const uint8_t *)[messageData bytes], [messageData length]) < 0)
    {
        return NO;
    }

    message = [[NSMutableString alloc] init];

    for (NSDictionary *part in parts)
    {
        // Checking it contains the actual part to avoid appending separators
        if ([part objectForKey:kSKPSMTPPartMessageKey]){
            if ([part objectForKey:kSKPSMTPPartContentDispositionKey])
            {
                [message appendFormat:@"Content-Disposition: %@\r\n", [part objectForKey:kSKPSMTPPartContentDispositionKey]];
            }
            [message appendFormat:@"Content-Transfer-Encoding: %@\r\n", [part objectForKey:kSKPSMTPPartContentTransferEncodingKey]];
            [message appendFormat:@"Content-Type: %@\r\n\r\n", [part objectForKey:kSKPSMTPPartContentTypeKey]];

            [message appendString:[part objectForKey:kSKPSMTPPartMessageKey]];
            [message appendString:@"\r\n"];

            [message appendString:separatorString];
        }
    }

    [message appendString:@"\r\n.\r\n"];

    NSLog(@"C: %@", message);
    if (CFWriteStreamWriteFully((__bridge CFWriteStreamRef)outputStream, (const uint8_t *)[message UTF8String], [message lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) < 0)
    {
        return NO;
    }
    [self startLongWatchdog];
    return YES;
}

当记录时(NSLog(@"C: %@", message);),那两个最后的分隔符不存在。

任何人都有任何暗示吗?

2 个答案:

答案 0 :(得分:0)

该库已经自动创建了一个包含以下内容的标头:

Content-Type: multipart/mixed; boundary=SKPSMTPMessage--Separator--Delimiter

该库还负责在您指定为消息部分的项目之间附加这些边界分隔符。

因此,只需创建一堆消息部分,如下所示:

let fileMessagePart1 :[String : String] = [
    kSKPSMTPPartContentTypeKey: "image/jpg;\r\n\tname=\"\(fileName)\"",
    kSKPSMTPPartContentDispositionKey: "attachment;\r\n\tfilename=\"\(fileName)\"",
    kSKPSMTPPartMessageKey: fileData.encodeBase64ForData(),
    kSKPSMTPPartContentTransferEncodingKey: "base64",
]

您可以将它们全部传递给库:

let emailMessage = SKPSMTPMessage()
// ...
emailMessage.parts = [fileMessagePart1, fileMessagePart2, fileMessagePart3]

此示例仅发送了三个图像部分,但是您还可以包括纯文本部分或任何其他类型的消息部分。

答案 1 :(得分:-1)

正如我想的那样,问题在于,根本不需要额外的分隔符,因此失败了。

所以,在sendParts方法上,我改变了这个:

[message appendString:@"Content-Type: multipart/mixed; boundary=\"SKPSMTPMessage--Separator--Delimiter\"\r\n"];
[message appendString:@"Mime-Version: 1.0\r\n"];
[message appendFormat:@"Subject:%@\r\n\r\n",subject];
[message appendString:separatorString];

对此:

[message appendString:@"Content-Type: multipart/mixed; boundary=\"SKPSMTPMessage--Separator--Delimiter\"\r\n"];
[message appendString:@"Mime-Version: 1.0\r\n"];
[message appendFormat:@"Subject:%@\r\n\r\n",subject];

基本上,删除[message appendString:separatorString];

然后,在循环中:

for (NSDictionary *part in parts)
{
    // Checking it contains the actual part to avoid appending separators
    if ([part objectForKey:kSKPSMTPPartMessageKey]){
        if ([part objectForKey:kSKPSMTPPartContentDispositionKey])
        {
            [message appendFormat:@"Content-Disposition: %@\r\n", [part objectForKey:kSKPSMTPPartContentDispositionKey]];
        }

        [message appendFormat:@"Content-Transfer-Encoding: %@\r\n", [part objectForKey:kSKPSMTPPartContentTransferEncodingKey]];
        [message appendFormat:@"Content-Type: %@\r\n\r\n", [part objectForKey:kSKPSMTPPartContentTypeKey]];

        [message appendString:[part objectForKey:kSKPSMTPPartMessageKey]];
        [message appendString:@"\r\n"];

        [message appendString:separatorString];
    }
}

我将separatorString移到了追加操作的顶部:

for (NSDictionary *part in parts)
{
    // Checking it contains the actual part to avoid appending separators
    if ([part objectForKey:kSKPSMTPPartMessageKey]){

        [message appendString:separatorString];

        if ([part objectForKey:kSKPSMTPPartContentDispositionKey])
        {
            [message appendFormat:@"Content-Disposition: %@\r\n", [part objectForKey:kSKPSMTPPartContentDispositionKey]];
        }

        [message appendFormat:@"Content-Transfer-Encoding: %@\r\n", [part objectForKey:kSKPSMTPPartContentTransferEncodingKey]];
        [message appendFormat:@"Content-Type: %@\r\n\r\n", [part objectForKey:kSKPSMTPPartContentTypeKey]];

        [message appendString:[part objectForKey:kSKPSMTPPartMessageKey]];
        [message appendString:@"\r\n"];
    }
}

这将解决问题!