いつもお世話になっております。
iOSとAndroidでアプリにメールの送信機能を入れて開発をしています。
OpenSSLを使いGmailを通して送信する機能です。
通りすがりさんに教えていただいた以下のリンク先を参考に実装しました。
>Indy 10 を使って GMail を送受信するには? (Delphi 2009 以降)
https://ht-deko.com/tech040.html#tech076
おかげさまで、実機でも動作確認ができて、Android版は、Google playに公開までたどり着けました。
次にiOS版をApp storeに公開するために、審査を受けました。
すると、このメール送信の機能がIPv6に対応しておらず、エラーになるので、修正して下さい、とのこと。
>We discovered one or more bugs in your app when reviewed on iPad and iPhone running iOS 11.4.1 on Wi-Fi connected to an IPv6 network.
どのように修正していけばよいのでしょうか?
開発環境は以下の通りです。
PCはMacBook AirでMacOS10.12.6です。
Parallelsを通してWindows10につないでいます。
Delphi 10.2.3を使っています。
どうぞよろしくお願いいたします。
iOS9 以降で必要な IPv6 only Network への対応
https://qiita.com/shao1555/items/4433803419dfc72bf80b
iOSアプリのIPv6での動作試験用のネットワークを作る
https://community.embarcadero.com/blogs/entry/ios-appstore-ipv6
IPv6さん
ありがとうございます。
>iOS9 以降で必要な IPv6 only Network への対応
>https://qiita.com/shao1555/items/4433803419dfc72bf80b
「実際の対処方法」を確認しました。
1.まず検証環境の作るのですね。
有線LANケーブルが要るとのこと、帰りに買います。
2.アドレスファミリに依存しない実装
ここがダメで、審査が通らないのでしょうか?
今はきっとIPv4しか使えていないのですね。
>NSURLSession、CFNetworkレイヤーのAPIを使う。
このAPIが実装したもののどこに該当するのかから調べなくてはですね。
3.サービス名で接続するAPIを使う
少し調べましたが、何をしたらいいのかが分かりませんでした。
"delphi indy ios ipv6"をキーワードに検索すると色々出てきますね。
Delphi iOS IPv6 trouble. Please ensure that your app is compatible with IPv6 networks - Stack Overflow
https://stackoverflow.com/questions/43242485/delphi-ios-ipv6-trouble-please-ensure-that-your-app-is-compatible-with-ipv6-net
Delphi iOS IPv6 App Store Rejection - Stack Overflow
https://stackoverflow.com/questions/39114096/delphi-ios-ipv6-app-store-rejection
ホスト名からIPアドレスを解決するときにIPv6を優先して使い、うまくいかなければIPv4で、
そしてIPv6で解決できたらIPv6で通信、というコーディングが必要だと思われます。
>通りすがりさん
ありがとうございます。
リンク先を拝見しあした。
教えていただいたあのGmailを送信するコードにどうやって反映させるかが分からずに困っています。
検証環境が無いので、まずはリンク先を参考に思いつくだけコードを書いてみます。
このあたりあまり情報がないようですが、TIdSMTPのSocketプロパティにIPVersionというプロパティがあるので、
ホスト名(TIdSMTPのHostプロパティに設定するもの)を設定した後 IdSMTP.Connect; する前に
IdSMTP.Socket.IPVersion := Id_IPv6; として、IdSMTP.Connectでエラー(例外)が発生したら
IdSMTP.Socket.IPVersion := Id_IPv4; としてもう一度IdSMTP.Connectしてみる、みたいな
コーディングになるのではないでしょうか。
var
Connected: Boolean;
begin
IdSMTP.Host := 'ホスト名';
IdSMTP.Port := ポート名;
...
IdSMTP.Socket.IPVersion := Id_IPv6;
try
IdSMTP.Connect;
Connected := True;
except
Connected := False;
end;
if Connected = False then
begin
IdSMTP.Socket.IPVersion := Id_IPv6;
end;
こんな感じ?
1行抜けてました。
var
Connected: Boolean;
begin
IdSMTP.Host := 'ホスト名';
IdSMTP.Port := ポート名;
...
IdSMTP.Socket.IPVersion := Id_IPv6;
try
IdSMTP.Connect;
Connected := True;
except
Connected := False;
end;
if Connected = False then
begin
IdSMTP.Socket.IPVersion := Id_IPv6;
IdSMTP.Connect;
end;
おまけに間違えてるし…たびたびすいません。
var
Connected: Boolean;
begin
IdSMTP.Host := 'ホスト名';
IdSMTP.Port := ポート名;
...
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;
>通りすがりさん
自分流にやってみましたが、やはりよくわかりませんでした。
コードをありがとうございます。
教えていただいたコードを、「Indy 10 を使って GMail を送受信するには? (Delphi 2009 以降)」 に入れ込んでみました。
IPv4の環境では動きました。
検証環境を作るのがうまくいっておらずまだIPv6の環境で試せていない状況です。
取り急ぎお礼申し上げます。
念のためコードを載せておきます。
ユーザー名やパスワードは安全のために「xxxx」にしておきました。
このような形で良いのでしょうか?
// 以下、通りすがりさんのコードを入れ込んだメール送信機能
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;
>通りすがりさん
おかげさまで進みました。
android版は、IPv4もIPv6も繋がり、動きました。
iOS版は、IPv4では動きました。
IPv6には、実機(iPhone 6s plus)が上手く繋がりません。
androidは繋がるのにiPhoneで繋がらないのは、どういうことでしょう?
test−ipv6.comという接続性をチェックするサイトでは、iPhone 6s plusで以下のようなエラーメッセージが出ました。
ブラウザのアドオンとの干渉により、あなたのIPアドレスを検出できませんでした。
テスト結果によると、壊れた、もしくは正しくないIPv6設定になっており、webサイトがIPv6対応を行った際に問題が生じる恐れがあります。
他にもコメントがありましたので、改めて書き込みます。
こちらを参考にIPv6での動作試験用ネットワークを作りましたが、うまく行きません。
>iOSアプリのIPv6での動作試験用のネットワークを作る
>https://community.embarcadero.com/blogs/entry/ios-appstore-ipv6
iPhone 6s PlusでブラウザはSafariを使っています。
test−ipv6.comという接続性をチェックするサイトでは、Android SH-01Kは繋がっていたようです。
iPhone 6s plusで以下のようなエラーメッセージが出ました。
ブラウザのアドオンとの干渉により、あなたのIPアドレスを検出できませんでした。
テスト結果によると、壊れた、もしくは正しくないIPv6設定になっており、webサイトがIPv6対応を行った際に問題が生じる恐れがあります。
我々はあなたのシステムをテストできませんでした;ファイアウォール、もしくはブラウザフィルターがテストの動作を妨害しているようです。決定的に重要なテストが失敗しました。いかなるブラウザプラグイン、拡張、もしくはアドオン(例えば広告ブロックなど)を無効にして、このページを再読み込みしてください。それでも失敗するようであれば、支援を求める書き込みをコメントに残してください(英語のみ)。
開発環境は以下の通りです。
PCはMacBook AirでMacOS10.12.6です。
Parallelsを通してWindows10につないでいます。
Delphi 10.2.3を使っています。
どうぞよろしくお願いいたします。
想像ですけど、Macより先がIPv4ではないでしょうか?
https://qiita.com/kazinoue/items/e497db84d9b1c6327c50
IPv4もOKな状態だとIPv6の検証がしにくいので(IPv4で通信しようとしてしまう)、IPv6のみの環境作りが必要かと思います。
>IPv6さん
ご助言をありがとうございます。
たしかにmacより先(前)はIPv4です。
しかし有線LAN(IPv4)→Mac→wifi:IPv6→iPhone 6s plusという設定です。
Macの前の無線LANがIPv4というならおっしゃっていることにの影響がでるように思いますが、有線なので違うように思いますがいかがでしょうか。
リンク先の情報をありがとうございます。
難しそうですが読みといてみます。
>通りすがりさん
いつもお世話になっております。
書き込んでいただいたコードを追加して、上記のコードでAppleの審査を受けましたが、Rejectされました。
「アドレスsmtp.gmail.comの解決時にエラーが発生しました:(8)」とのエラーがIPv6環境で発生したとのことです。
このエラーは自分のIPv4環境でネットに繋いでいない時にも出ました。
アプリの機能として、このメールを送信する機能の後、グーグルフォームを開く機能が動くことになっています。
これもインターネットを通してやります。
https://www.gesource.jp/weblog/?p=6952
こちらのリンク先の以下のコードを使わせていただき実装しました。
加えて、IPv6に対応させるために、以下のリンク先のコードを加えて以下のように実装しました。
https://stackoverflow.com/questions/45215172/delphi-datasnap-connection-error-with-ipv6-ios
すると、IPv4環境ではメール送信まではできますが、その先のグーグルフォームに繋ぐ際のところで、以下のエラーが出てしまいます。
「エラー アドレス 00000001017C4334でアクセス違反が発生しました。(アドレス000000000000000へのアクセス時)」
ここからどのようにしていけば良いのでしょうか。
お忙しいところ恐縮ですがお知恵をお貸しいただけますとありがたいです。
// Googleフォームを開く
Procedure OpenGoogleForm;
Var ipversion : String;
Begin
// IPv6に対応させる
IdTCPClient1.IPVersion:=Id_IPv4; // <-- try IPv4 first
IdTCPClient1.Host:=MY_IP;
try
IdTCPClient1.Connect;
result:=true;
ipversion := 'IPv4'; // <-- will tell us what ip version to use
except
end;
if IdTCPClient1.Connected=false then
begin
try
IdTCPClient1.IPVersion:=Id_IPv6; // <-- now try IPv6
IdTCPClient1.Connect;
result:=true;
ipversion:='IPv6'; // <-- will tell us what ip version to use
except
end;
end;
// URLを開く
{$IFDEF ANDROID}
Intent := TJIntent.Create;
Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
Intent.setData(StrToJURI('https://docs.google.com/forms/d/e/1FAIpQLSfyNDVg4xjwdCT349wYB4W2f85tDry5m5ShGHFNdiUFinpcWQ/viewform?c=0&w=1'));
SharedActivity.startActivity(Intent);
{$ENDIF}
{$IFDEF IOS}
SharedApplication.openURL(StrToNSUrl('https://docs.google.com/forms/d/e/1FAIpQLSfyNDVg4xjwdCT349wYB4W2f85tDry5m5ShGHFNdiUFinpcWQ/viewform?c=0&w=1'));
{$ENDIF}
End;
>みなさま
マルチポストになるといけませんので、一旦こちらを閉じて、stackoverflowで質問をさせていただきます。
アドバイスを下さった通りすがりさん、IPv6さん、ありがとうございます。
続報がありましたら、こちらに書きこみます。
>みなさま
StackOverFlowにて助言を得られ、IPv6への接続についてはItunes Connectionの審査を通ったようです。
質問と回答のリンクを貼っておきます。
https://stackoverflow.com/questions/51640748/how-can-i-send-email-over-ipv6-properly
https://stackoverflow.com/questions/51643713/how-can-i-open-a-url-over-ipv6-properly
ツイート | ![]() |