14

I need to push notifications to tens of thousands of iOS devices that my app installed. I'm trying to do it with PushSharp, but I'm missing some fundamental concepts here. At first I tried to actually run this in a Windows service, but couldn't get it work - getting null reference errors coming from _push.QueueNotification() call. Then I did exactly what the documented sample code did and it worked:

    PushService _push = new PushService();

    _push.Events.OnNotificationSendFailure += new ChannelEvents.NotificationSendFailureDelegate(Events_OnNotificationSendFailure);
    _push.Events.OnNotificationSent += new ChannelEvents.NotificationSentDelegate(Events_OnNotificationSent);

    var cert = File.ReadAllBytes(HttpContext.Current.Server.MapPath("..pathtokeyfile.p12"));

    _push.StartApplePushService(new ApplePushChannelSettings(false, cert, "certpwd"));

    AppleNotification notification = NotificationFactory.Apple()
                                                        .ForDeviceToken(deviceToken)
                                                        .WithAlert(message)
                                                        .WithSound("default")
                                                        .WithBadge(badge);
    _push.QueueNotification(notification);

    _push.StopAllServices(true);

Issue #1: This works perfectly and I see the notification pop up on the iPhone. However, since it's called a Push Service, I assumed it would behave like a service - meaning, I instantiate it and call _push.StartApplePushService() within a Windows service perhaps. And I thought to actually queue up my notifications, I could do this on the front-end (admin app, let's say):

        PushService push = new PushService();

        AppleNotification notification = NotificationFactory.Apple()
                                                            .ForDeviceToken(deviceToken)
                                                            .WithAlert(message)
                                                            .WithSound("default")
                                                            .WithBadge(badge);
        push.QueueNotification(notification);

Obviously (and like I already said), it didn't work - the last line kept throwing a null reference exception.

I'm having trouble finding any other kind of documentation that would show how to set this up in a service/client manner (and not just call everything at once). Is it possible or am I missing the point of how PushSharp should be utilized?

Issue #2: Also, I can't seem to find a way to target many device tokens at once, without looping through them and queuing up notifications one at a time. Is that the only way or am I missing something here as well?

Thanks in advance.

Kon
  • 25,664
  • 11
  • 56
  • 84

2 Answers2

4

@baramuse explained it all, if you wish to see a service "processor" you can browse through my solution on https://github.com/vmandic/DevUG-PushSharp where I've implemented the workflow you seek for, i.e. a win service, win processor or even a web api ad hoc processor using the same core processor.

Community
  • 1
  • 1
Vedran Mandić
  • 582
  • 5
  • 14
3

From what I've read and how I'm using it, the 'Service' keyword may have mislead you...

It is a service in a way that you configure it once and start it. From this point, it will wait for you to push new notifications inside its queue system and it will raise events as soon as something happens (delivery report, delivery error...). It is asynchronous and you can push (=queue) 10000 notifications and wait for the results to come back later using the event handlers.

But still it's a regular object instance you will have to create and access as a regular one. It doesn't expose any "outside listener" (http/tcp/ipc connection for example), you will have to build that.

In my project I created a small selfhosted webservice (relying on ServiceStack) that takes care about the configuration and instance lifetime while only exposing the SendNotification function.

And about the Issue #2, there indeed isn't any "batch queue" but as the queue function returns straight away (enqueue and push later) it's just a matter of a looping into your device tokens list...

public void QueueNotification(Notification notification)
{
    if (this.cancelTokenSource.IsCancellationRequested)
    {
        Events.RaiseChannelException(new ObjectDisposedException("Service", "Service has already been signaled to stop"), this.Platform, notification);
        return;
    }

    notification.EnqueuedTimestamp = DateTime.UtcNow;

    queuedNotifications.Enqueue(notification);
}
baramuse
  • 360
  • 2
  • 10