0

I have been using Indy's TIdTCPClient component successfully for quite a while now to send push notifications to my mobile app users. Lately, due to new push notification requirements of Apple, this feature has stopped being functional for iOS users.

For the past three days, I've been trying to reconstruct this function by using the TIdHTTP component instead, following the new HTTP/2 format advised by Apple to send push notifications. Unfortunately, I've yet to come up with something operational.

Here's my failing code:

procedure TForm5.BtnPushClick(Sender: TObject);
var
  vHTTP: TIdHTTP;
  SslIOHandlerHTTP : TIdSSLIOHandlerSocketOpenSSL;
  RequestBody: TStream;
  ResponseBody, vCertFileName: string;  
  vJsonToSend : TStringStream;
begin
  try
    vCertFileName     := 'apns-dist.pem';
    vIdHTTP := TIdHTTP.Create(nil);
    SslIOHandlerHTTP := TIdSSLIOHandlerSocketOpenSSL.Create(vHTTP);
    SslIOHandlerHTTP.OnVerifyPeer  := SslIOHandlerHTTP1VerifyPeer;
    SslIOHandlerHTTP.OnGetPassword := SslIOHandlerHTTP1GetPassword;
    SslIOHandlerHTTP.SSLOptions.CertFile    := vCertFileName;
    SslIOHandlerHTTP.SSLOptions.KeyFile     := vCertFileName;
    SslIOHandlerHTTP.SSLOptions.Method      := sslvTLSv1_2;
    SslIOHandlerHTTP.SSLOptions.Mode        := sslmBoth;
    SslIOHandlerHTTP.SSLOptions.SSLVersions := [sslvTLSv1_2];
    SslIOHandlerHTTP.SSLOptions.VerifyMode := [sslvrfPeer];
    SslIOHandlerHTTP.SSLOptions.VerifyDepth := 2;
    //--
    vHTTP.Request.CustomHeaders.AddValue(':method', 'POST');
    vHTTP.Request.CustomHeaders.AddValue(':scheme', 'https');
    vHTTP.Request.CustomHeaders.AddValue(':path', '/3/device/111890052839d3ed4f596c94712329e20812464afe30ebd28487c4e65986c6f0');
    vHTTP.Request.CustomHeaders.AddValue('host', 'api.push.apple.com');
    vHTTP.Request.CustomHeaders.AddValue('apns-id', 'eabeae54-14a8-11e5-b60b-1697f925ec7b');
    vHTTP.Request.CustomHeaders.AddValue('apns-push-type', 'alert');
    vHTTP.Request.CustomHeaders.AddValue('apns-expiration', '0');
    vHTTP.Request.CustomHeaders.AddValue('apns-priority', '10');
    vHTTP.Request.CustomHeaders.AddValue('apns-topic', 'com.TS.JACK');
    //--
    vHTTP.IOHandler           := SslIOHandlerHTTP;
    vHTTP.Request.Accept      := 'application/json';
    vHTTP.Request.ContentType := 'application/json';
    vHTTP.HTTPOptions         := [hoForceEncodeParams];
    vHTTP.ProtocolVersion     := pv1_1;
    SslIOHandlerHTTP.PassThrough := true;

    vJsonToSend := TStringStream.Create('{ "aps" : { "alert" : "Hello" } }', TEncoding.UTF8);
    ResponseBody := vHTTP.Post('https://api.push.apple.com', vJsonToSend);
  except
    on E: Exception do
    begin
      Memo1.Lines.Add(IntToStr(vHTTP.ResponseCode)+':' + E.Message);
    end;
  end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Johny
  • 419
  • 4
  • 15
  • 2
    [Indy does not support HTTP/2](https://github.com/IndySockets/Indy/issues/163) – Olivier Sep 07 '21 at 15:40
  • You are probably better off using Delphi's Objective-C Bridge to access iOS native APIs or 3rd party APIs that wrap the APN communication for you. – Remy Lebeau Sep 07 '21 at 17:03
  • @RemyLebeau How about using Rad Server (EMS) to push notifications to IOS? – Johny Sep 08 '21 at 21:32
  • @Johny I wouldn't know, I've never worked with EMS before. I suppose [it is possible](https://docwiki.embarcadero.com/RADStudio/en/RAD_Server_Push_Notifications), but I think that is a different kind of push notification that is specific to RAD Server, not native to iOS, but I don't know for sure. – Remy Lebeau Sep 08 '21 at 23:07

0 Answers0