How can I open a url over IPv6 properly?

2019-07-29 23:13发布

问题:

I have written a function in my iOS and Android apps to open a url. I believe this code will be rejected by iTunes Connect for not connecting over IPv6.

This function also raises an error when I build it through Delphi:

An access violation occurred at error address 00000001017C4334. (When accessing address 000000000000000)

I am using Delphi 10.2.3 Tokyo with Indy 10.

How can I fix this error? My code is below:

Procedure OpenGoogleForm; 
Var
  ipversion : String; 
Begin 
  //  For 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; 

  //  open url 
  {$IFDEF ANDROID} 
  Intent := TJIntent.Create; 
  Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);

  Intent.setData(StrToJURI('https://docs.google.com/forms/xxxx')); 
  SharedActivity.startActivity(Intent); 
  {$ENDIF} 

  {$IFDEF IOS} 
  SharedApplication.openURL(StrToNSUrl('https://docs.google.com/forms/xxxx')); 
  {$ENDIF} 

End; 

回答1:

The error message is telling you that a nil pointer is being accessed, so you need to hunt that down.

But, there is no reason at all to perform a manual TCP check before opening a url. You are spawning an external app to open the url, so let that app handle connectivity errors as it needs. Especially since you proceed to open the url anyway if both Connect() calls fail. So just get rid of TIdTCPClient from your procedure altogether, it doesn't belong there. That is probably where your nil pointer is coming from.

procedure OpenGoogleForm; 
begin 
  {$IFDEF ANDROID} 
  Intent := TJIntent.Create; 
  Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
  Intent.setData(StrToJURI('https://docs.google.com/forms/xxxx')); 
  SharedActivity.startActivity(Intent); 
  {$ENDIF} 

  {$IFDEF IOS} 
  SharedApplication.openURL(StrToNSUrl('https://docs.google.com/forms/xxxx')); 
  {$ENDIF} 
end;