Sending Push Notifications to api.sandbox.push.apple.com fails

I am developing a new App that uses Push Notifications. I completed the development of the App itself and I can send Push Notifications from the CloudKit and receive it on my phone.

My problem is sending the Push Notifications from our service API to Apple. If I use the production address gateway.push.apple.com, I can send messages, but they don't work for my new App because it is in development and not yet released. If I use the sandbox address api.sandbox.push.apple.com, I get the following exception:

System.Net.Sockets.SocketException (10061): No connection could be made because the target machine actively refused it. [::ffff:17.188.143.98]:2195
   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
   at System.Net.Sockets.Socket.Connect(IPAddress[] addresses, Int32 port)
--- End of stack trace from previous location ---
   at System.Net.Sockets.Socket.Connect(IPAddress[] addresses, Int32 port)
   at System.Net.Sockets.Socket.Connect(String host, Int32 port)
   at System.Net.Sockets.TcpClient.Connect(String hostname, Int32 port)
   at System.Net.Sockets.TcpClient..ctor(String hostname, Int32 port)

The service API for sending Push Notifications was developed in C# .NET 8.0.

Constants:

    private readonly string _hostname = "api.sandbox.push.apple.com";
    private readonly int _port = 2195;

The code for sending a message.

public async Task Send(string? subtitle, string? title, string message, string deviceId)
{
	var payload =
	"{ \"aps\": { " +
			"\"alert\": { " +
				"\"title\": \"" + title + "\", " +
				"\"subtitle\": \"" + subtitle + "\", " +
				"\"body\": \"" + message + "\"" +
			"} " +
		"} " +
	"}";

	try
	{
		Debug.WriteLine($"apple api request: {payload}");

		using var client = new TcpClient(_hostname, _port);

		var sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate));

		var certificatesCollection = new X509Certificate2Collection(_certificate);

		await sslStream.AuthenticateAsClientAsync(_hostname, certificatesCollection, SslProtocols.Tls12 | SslProtocols.Tls13, true);

		var array = DataToBytes(deviceId, payload);
		sslStream.Write(array);
		sslStream.Flush();

		client.Close();
	}
	catch(Exception exception)
	{
		Debug.WriteLine(exception);
	}
}

The certificate that is used in this code was read beforehand:

var clientCertificate = new X509Certificate2(iOSApp.Certificate, iOSApp.CertificatePassword);

We are using a p12 certificate file with a private password.

Again, it works great for an App in Production but not at all for an App in Development. I made use that I use a new p12 developer certificate for the new App when I tested. I also tested with a p12 production certificate. I get the same error.

Any help is appreciated.

Answered by Engineer in 805705022

According to your code snippet, you are still using the legacy Binary Interface which was retired March 31st, 2021 (https://developer.apple.com/news/?id=c88acm2b).

This change requires you to migrate your push servers to use the HTTP/2 API. Any push servers still using the legacy interface will be unable to connect to APNs, resulting in Push Notifications not working.

More information about the HTTP/2 provider API can be found in these two WWDC sessions:

You can read more about the new APNs Provider API here: https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns/

If you have issues after migrating to the new interface, or have technical questions about the migration, we are happy to help troubleshoot your push requests once you have started using the HTTP/2 protocol. Please understand that we are unable to help with the specifics of your server side implementation. Unfortunately we also cannot make recommendations on which 3rd party resources to use to make this transition.

Existing production apps using the legacy protocol had been allowed to use it past the deadline to minimize disruptions, but there may come a time that your production app will also stop being able to receive notifications this way. There will be no more extensions or exceptions for your app once you start having problems. Moving to the new HTTP/2 protocol as explained above is your only option.


Argun Tekant /  DTS Engineer / Core Technologies

According to your code snippet, you are still using the legacy Binary Interface which was retired March 31st, 2021 (https://developer.apple.com/news/?id=c88acm2b).

This change requires you to migrate your push servers to use the HTTP/2 API. Any push servers still using the legacy interface will be unable to connect to APNs, resulting in Push Notifications not working.

More information about the HTTP/2 provider API can be found in these two WWDC sessions:

You can read more about the new APNs Provider API here: https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns/

If you have issues after migrating to the new interface, or have technical questions about the migration, we are happy to help troubleshoot your push requests once you have started using the HTTP/2 protocol. Please understand that we are unable to help with the specifics of your server side implementation. Unfortunately we also cannot make recommendations on which 3rd party resources to use to make this transition.

Existing production apps using the legacy protocol had been allowed to use it past the deadline to minimize disruptions, but there may come a time that your production app will also stop being able to receive notifications this way. There will be no more extensions or exceptions for your app once you start having problems. Moving to the new HTTP/2 protocol as explained above is your only option.


Argun Tekant /  DTS Engineer / Core Technologies

Sending Push Notifications to api.sandbox.push.apple.com fails
 
 
Q