我正在iOS和Android应用程序中开发电子邮件发送功能。
该功能是使用OpenSSL通过Gmail发送电子邮件的功能。
我正在将Delphi 10.2.3 Tokyo和Indy 10一起使用。
我将iOS应用提交到iTunes Connect,但是他们拒绝了我的应用,因为此功能在IPv6中不起作用。
他们说
在连接到IPv6网络的Wi-Fi上运行iOS 11.4.1的iPad和iPhone上进行检查时,我们发现您的应用程序中存在一个或多个错误。
他们还向我发送了错误说的屏幕截图
解析地址smtp.gmail.com时发生错误:(8)
如何解决此错误以正确使用IPv6?我的代码如下:
Procedure MailSend;
Var
Connected: Boolean;
Begin
IdSMTP := TIdSMTP.Create(nil);
try
IdSMTP.Host := 'smtp.gmail.com';
IdSMTP.Port := 587;
IdSMTP.Username := 'xxxx@gmail.com'; // UserName
IdSMTP.Password := 'xxxx'; // Password
SSL := TIdSSLIOHandlerSocketOpenSSL.Create;
try
SSL.Host := IdSMTP.Host;
SSL.Port := IdSMTP.Port;
SSL.Destination := SSL.Host + ':' + IntToStr(SSL.Port);
IdSMTP.IOHandler := SSL;
IdSMTP.UseTLS := utUseExplicitTLS;
IdSMTP.Socket.IPVersion := Id_IPv6;
try
IdSMTP.Connect;
Connected := True;
except
Connected := False;
end;
If Connected = False then
Begin
IdSMTP.Socket.IPVersion := Id_IPv4;
IdSMTP.Connect;
End;
Msg := TIdMessage.Create(IdSMTP);
try
Msg.OnInitializeISO := IdMessage_InitializeISO;
Msg.ContentType := 'text/plain';
Msg.CharSet := 'UTF-8';
Msg.ContentTransferEncoding := 'BASE64'; // BASE64 (7bit)
//Msg.ContentTransferEncoding := '8bit'; // RAW(8bit)
Msg.From.Name := SsNoSt;
Msg.From.Address := 'xxxx@gmail.com';
Msg.Recipients.EMailAddresses := 'xxxx@gmail.com';
Msg.Subject := SsNoSt;
Msg.Body.Text := 'Unicode String (body)';
IdSMTP.Send(Msg);
finally
Msg.Free;
end;
IdSMTP.Disconnect;
finally
SSL.Free;
end;
finally
IdSMTP.Free;
End;
End;
答案 0 :(得分:4)
我发现您的SMTP代码有一些问题:
您需要设置IdSMTP.IPVersion
属性而不是IdSMTP.Socket.IPVersion
属性。 IPVersion
属性的默认值为Id_IPv4
(bug-不遵守ID_DEFAULT_IP_VERSION
单位中的IdGlobal
常数)。 Connect()
用Socket.IPVersion
属性值覆盖IPVersion
属性值,因此您实际上尝试使用Id_IPv4
进行两次连接,这将在仅IPv6的网络上失败(苹果需要支持应用程序。)
您没有从第二个Connect()
中捕获任何错误。这可能是苹果最终看到的错误。
您不应该手动设置SSL.Host
,SSL.Port
和SSL.Destination
属性。让Connect()
帮您解决这个问题。
尝试以下方法:
// this accessor class is needed because TIdSMTP derives from TIdTCPClientCustom
// instead of TIdTCPClient. The IPVersion property is protected in
// TIdTCPClientCustom and not published by TIdSMTP or its ancestors.
//
// See https://github.com/IndySockets/Indy/issues/184 ...
//
type
TIdSMTPAccess = class(TIdSMTP)
end;
procedure MailSend;
var
IdSMTP: TIdSMTP;
Msg: TIdMessage;
begin
IdSMTP := TIdSMTP.Create(nil);
try
SSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdSMTP);
IdSMTP.IOHandler := SSL;
IdSMTP.Host := 'smtp.gmail.com';
IdSMTP.Port := 587;
IdSMTP.Username := 'xxxx@gmail.com';
IdSMTP.Password := 'xxxx';
IdSMTP.UseTLS := utUseExplicitTLS;
TIdSMTPAccess(IdSMTP).IPVersion := Id_IPv6;
try
IdSMTP.Connect;
except
TIdSMTPAccess(IdSMTP).IPVersion := Id_IPv4;
try
IdSMTP.Connect;
except
// unable to connect!
Exit;
end;
end;
try
Msg := TIdMessage.Create(nil);
try
Msg.OnInitializeISO := IdMessage_InitializeISO;
Msg.ContentType := 'text/plain';
Msg.CharSet := 'UTF-8';
Msg.ContentTransferEncoding := 'BASE64'; // BASE64 (7bit)
//Msg.ContentTransferEncoding := '8bit'; // RAW(8bit)
Msg.From.Name := SsNoSt;
Msg.From.Address := 'xxxx@gmail.com';
Msg.Recipients.EMailAddresses := 'xxxx@gmail.com';
Msg.Subject := SsNoSt;
Msg.Body.Text := 'Unicode String (body)';
IdSMTP.Send(Msg);
finally
Msg.Free;
end;
finally
IdSMTP.Disconnect;
end;
finally
IdSMTP.Free;
end;
end;
或者:
type
TIdSMTPAccess = class(TIdSMTP)
end;
procedure MailSend;
var
IdSMTP: TIdSMTP;
Msg: TIdMessage;
Connected: Boolean;
begin
IdSMTP := TIdSMTP.Create(nil);
try
SSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdSMTP);
IdSMTP.IOHandler := SSL;
IdSMTP.Host := 'smtp.gmail.com';
IdSMTP.Port := 587;
IdSMTP.Username := 'xxxx@gmail.com';
IdSMTP.Password := 'xxxx';
IdSMTP.UseTLS := utUseExplicitTLS;
Connected := False;
if GStack.SupportsIPv6 then
begin
TIdSMTPAccess(IdSMTP).IPVersion := Id_IPv6;
try
IdSMTP.Connect;
Connected := True;
except
end;
end;
if (not Connected) and GStack.SupportsIPv4 then
begin
TIdSMTPAccess(IdSMTP).IPVersion := Id_IPv4;
try
IdSMTP.Connect;
Connected := True;
except
end;
end;
if not Connected then
begin
// unable to connect!
Exit;
end;
try
Msg := TIdMessage.Create(nil);
try
Msg.OnInitializeISO := IdMessage_InitializeISO;
Msg.ContentType := 'text/plain';
Msg.CharSet := 'UTF-8';
Msg.ContentTransferEncoding := 'BASE64'; // BASE64 (7bit)
//Msg.ContentTransferEncoding := '8bit'; // RAW(8bit)
Msg.From.Name := SsNoSt;
Msg.From.Address := 'xxxx@gmail.com';
Msg.Recipients.EMailAddresses := 'xxxx@gmail.com';
Msg.Subject := SsNoSt;
Msg.Body.Text := 'Unicode String (body)';
IdSMTP.Send(Msg);
finally
Msg.Free;
end;
finally
IdSMTP.Disconnect;
end;
finally
IdSMTP.Free;
end;
end;