1
votes

I am using silent push notification in XMPP chat application. Using that I want to connect to XMPP server when app is not running or not in background mode. I am receiving silent push notification and I enable following flag of xmppStream for background connection.

xmppStream.enableBackgroundingOnSocket = YES;

But socketDidConnect method is not being still called when app is not running and can't able to connect to XMPP server.

The purpose of this is to send message received status to XMPP server. So guide me about this.

I don't want to use VoIP for this. So please provide me alternate solution for this.

1
I suggest you start considering VoIP, to my experience, that's the only solution. Because when the app is not running (or killed by user), there is no execution at all even if you received the notification. VoIP provide you the opportunity to wake up the app in the background and execute some code.dichen

1 Answers

2
votes

Follow the below steps. This is possible using VoIP and PushKit framework.

  1. Enable VoIP Service Certificate for your app. Check below image.

enter image description here

  1. Enable Voice over IP for your app. Check below image.

enter image description here

  1. Now add PushKit.framework

  2. In AppDelegate.h file import PushKit framework and add its delegate PKPushRegistryDelegate

  3. AppDelegate.m file do following.

    A) In didFinishLaunchingWithOptions method add below code.

    PKPushRegistry *voipRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
    voipRegistry.delegate = self;
    voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
    

    B) Add all delegate methods of PKPushRegistryDelegate

    - (void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(NSString *)type { NSLog(@"VoIP - did Invalidate Push Token for type - %@", type); }
    
    - (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
    NSLog(@"VoIP - got Push with payload: %@ and Type: %@", payload.dictionaryPayload, type);
    
    NSDictionary *dictAps = [payload.dictionaryPayload valueForKey:@"aps"];
    if ([dictAps valueForKey:@"content-available"] != nil) {
    NSLog(@"Silent VoIP");
    
    //Fetch payload info and create local notification and fire that local notification.
    UILocalNotification *voipNotification = [[UILocalNotification alloc] init];
    voipNotification.alertTitle = @"Silent VoIP";
    voipNotification.alertBody = [dictAps valueForKey:@"alert"];
    voipNotification.soundName = UILocalNotificationDefaultSoundName;
    [[UIApplication sharedApplication] presentLocalNotificationNow:voipNotification];
    
    //Call xmpp connection method here.
    if (xmppStream == nil) { [self setupStream]; }
    if ([xmppStream isDisconnected]) { [self connect]; }
    }
    }
    
    - (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type {
    NSLog(@"VoIP - device Token: %@", credentials.token);
    
    NSString *newToken = credentials.token.description;
    newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    newToken = [newToken stringByReplacingOccurrencesOfString:@" " withString:@""];
    
    NSLog(@"VoIP token is: %@", newToken);
    [obj_DataModel setVoIPToken:newToken]; //Store token in somewhere for further use.
    }
    
  4. I am passing following payload for this purpose from the server.

    {"aps":{"alert":"Testing...","badge":1,"sound":"default","content-available":1}}
    

I hope that this is helpful for you. If you have any query then ask me.