Sinch SDK with VoIP, PushKit, CallKit - ios

I integrated Sinch sdk into my projects with VoIP, PushKit, CallKit. Everything is working fine. But when app is not running in device A and someone(Device B) is calling to it then sometimes in device A I am getting notification with text SIN_INCOMING_CALL . I don't know from where it is coming. But my problem is, I want to open default call screen of iOS device. Sometime it is being opened and sometimes it show notification with this text.
My Appdelegate has following code.
#interface AppDelegate() <SINClientDelegate, SINCallClientDelegate, SINManagedPushDelegate, SINCallDelegate>
#property (nonatomic, readwrite, strong) id<SINManagedPush> push;
#property (strong, nonatomic) id<SINClient> sinchClient;
#property (nonatomic, readwrite, strong) SINCallKitProvider *callKitProvider;
#end
#implementation AppDelegate
- (void)applicationWillEnterForeground:(UIApplication *)application
{
id<SINCall> call = [self.callKitProvider currentEstablishedCall];
if (call) {
//Show call view controller and pass call
}
}
#pragma mark - Remote Notification
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
if (notificationSettings.types != UIUserNotificationTypeNone) { [application registerForRemoteNotifications]; }
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSString *newToken = deviceToken.description;
newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
newToken = [newToken stringByReplacingOccurrencesOfString:#" " withString:#""];
[self.push application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
NSLog(#"My token is: %#", newToken);
//get previously initiated Sinch client
if (!self.sinchClient) { [self initSinchCallConfig]; }
id<SINClient> client = [self sinchClient];
[client registerPushNotificationData:deviceToken];
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(#"Failed to get token, error: %#", error);
[obj_SharedModel setUDID:#""]; //Statuc Device Id just for testing purpose from simulator.
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[self.push application:application didReceiveRemoteNotification:userInfo];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
completionHandler(UIBackgroundFetchResultNewData);
}
- (void)registerForPushNotifications
{
UIApplication *application = [UIApplication sharedApplication];
if (IS_OS_10_BELOW) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeAlert|UIUserNotificationTypeSound) categories:nil];
[application registerUserNotificationSettings:settings];
}
else {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){
if(!error){ dispatch_async(dispatch_get_main_queue(), ^{ [[UIApplication sharedApplication] registerForRemoteNotifications]; }); }
}];
}
//register for VoIP push
PKPushRegistry *voipRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
voipRegistry.delegate = self;
voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
self.push = [Sinch managedPushWithAPSEnvironment:SINAPSEnvironmentAutomatic];
self.push.delegate = self;
[self.push setDesiredPushTypeAutomatically];
[self.push registerUserNotificationSettings];
}
- (void)unRegisterForPushNotifications
{
[[UIApplication sharedApplication] unregisterForRemoteNotifications];
[self.sinchClient unregisterPushNotificationDeviceToken];
}
#pragma mark - IOS 10 UP - UNUserNotificationCenter
//Called when a notification is delivered to a foreground app.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
NSLog(#"User Info : %#",notification.request.content.userInfo);
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
//Called to let your app know which action was selected by the user for a given notification.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
completionHandler();
}
#pragma mark - VoIP remote Notifications
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type {
NSString *newToken = credentials.token.description;
newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
newToken = [newToken stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"VoIP Tokenp is: %#", newToken);
}
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
NSDictionary *dictPayload = payload.dictionaryPayload;
if ([dictPayload sin_isSinchPushPayload]) {
if (!self.sinchClient) { [self initSinchCallConfig]; }
[self.sinchClient relayRemotePushNotification:dictPayload];
/*
{"aps":{"alert":{"loc-key" : "SIN_INCOMING_CALL"}},"sin" :"ASDAS" }
*/
}
else {
}
}
- (void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(NSString *)type { }
#pragma mark - SINClient Method
- (void)initSinchCallConfig
{
// Instantiate a Sinch client object
if (!self.sinchClient && [stLoginUserName length]) {
self.sinchClient = [Sinch clientWithApplicationKey:#"dea827c1-1208-45a6-b510-5d1f277d9607" applicationSecret:#"AgxDpf/4X0OrLx1GXv6Quw==" environmentHost:#"sandbox.sinch.com" userId:stLoginUserName];
self.sinchClient.delegate = self;
self.sinchClient.callClient.delegate = self; //for incomming call
[self.sinchClient setSupportCalling:YES];
[self.sinchClient setSupportPushNotifications:YES];
[self.sinchClient setPushNotificationDisplayName:MSG_TITLE];
[self.sinchClient enableManagedPushNotifications];
[self.sinchClient start];
[self.sinchClient startListeningOnActiveConnection];
self.callKitProvider = [[SINCallKitProvider alloc] initWithClient:self.sinchClient];
}
}
#pragma mark - SINClient Delegate
- (void)clientDidStart:(id<SINClient>)client {
NSLog(#"Sinch client started successfully (version: %#)", [Sinch version]);
}
- (void)clientDidFail:(id<SINClient>)client error:(NSError *)error {
NSLog(#"Sinch client error: %#", [error localizedDescription]);
}
- (void)client:(id<SINClient>)client logMessage:(NSString *)message area:(NSString *)area severity:(SINLogSeverity)severity timestamp:(NSDate *)timestamp {
NSLog(#"%#", message);
}
#pragma mark - SINCallClient Delegate
- (void)client:(id<SINCallClient>)client didReceiveIncomingCall:(id<SINCall>)call {
NSLog(#"didReceiveIncomingCall");
CallViewController *callVC = [[CallViewController alloc] initWithNibName:#"CallViewController" bundle:nil];
callVC.call = call;
AppNavigationController *nav = [[AppNavigationController alloc] initWithRootViewController:callVC];
[self.navigationController presentViewController:nav animated:YES completion:nil];
if (call.details.applicationStateWhenReceived == UIApplicationStateActive) { }
else { [callVC btnAcceptCallAction]; }
}
- (void)client:(id<SINClient>)client willReceiveIncomingCall:(id<SINCall>)call {
[self.callKitProvider reportNewIncomingCall:call];
call.delegate = self;
}
#pragma mark - SINManagedPush Delegate
- (void)managedPush:(id<SINManagedPush>)unused didReceiveIncomingPushWithPayload:(NSDictionary *)payload forType:(NSString *)pushType {
if (!self.sinchClient) { [self initSinchCallConfig]; }
[self.sinchClient relayRemotePushNotification:payload];
}
- (void)call:(id<SINCall>)call shouldSendPushNotifications:(NSArray *) pushPairs {
NSLog(#"shouldSendPushNotifications");
}
#pragma mark - SINCall Delegate
- (void)callDidProgress:(id<SINCall>)call {
}
- (void)callDidEstablish:(id<SINCall>)call {
}
- (void)callDidEnd:(id<SINCall>)call { [[self callKitProvider] reportCallEnded:call]; }
#end

Related

After integrating OneSignal Cordova SDK my App delegate methods are not called for UNUserNotificationCenterDelegate

#import "AppDelegate.h"
#import <UserNotifications/UserNotifications.h>
#import "MainViewController.h"
#interface AppDelegate () <UNUserNotificationCenterDelegate>
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
self.viewController = [[MainViewController alloc] init];
[self registerForNotification];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification*)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
// This method are not getting called
completionHandler(UNNotificationPresentationOptionAlert|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(nonnull UNNotificationResponse* )response withCompletionHandler:(nonnull void (^)(void))completionHandler {
// This method are not getting called
NSDictionary *userInfo = response.notification.request.content.userInfo;
completionHandler();
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(#"DEVICE_TOKEN :: %#", deviceToken);
const unsigned *tokenBytes = [deviceToken bytes];
NSString *hexToken = [NSString stringWithFormat:#"%08x%08x%08x%08x%08x%08x%08x%08x",
ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
NSString *apnDeviceToken = hexToken;
NSLog(#"APN_DEVICE_TOKEN :: %#", apnDeviceToken);
}
-(void)registerForNotification
{
if(#available(iOS 10.0, *))
{
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error)
{
if(!error)
{
dispatch_async(dispatch_get_main_queue(), ^ {
[[UIApplication sharedApplication] registerForRemoteNotifications]; // required to get the app to do anything at all about push notifications
NSLog(#"Push registration success." );
});
}
else
{
NSLog(#"Push registration FAILED" );
NSLog(#"ERROR: %# - %#", error.localizedFailureReason, error.localizedDescription );
NSLog(#"SUGGESTIONS: %# - %#", error.localizedRecoveryOptions, error.localizedRecoverySuggestion );
}
}];
}
}
#end
The didReceiveNotificationResponse and willPresentNotification did not trigger. I'm not able to handle Other APNS notification which is not related to one signal Cordova plugin SDK notification.
Is there any way that my app delegate methods for UserNotifications delegate methods will trigger in Cordova ios when one signal plugin used?
I suspect that due to swizzling the app delegate methods by one signal callbacks are not triggered in the original Appdelegate file.
Please help on this if we have any other way to get my app delegate
UserNotifications delegate methods trigger.
As one signal uses the static frameworks in Cordova there is no way to change the code inside the plugin.
This is the one signal plugin for Cordova github https://github.com/OneSignal/OneSignal-Cordova-SDK

Issue subscribing to FCM topic using Xcode/Objective C

I have a problem which I've been unable to resolve. My knowledge of iOS/Xcode is limited, please forgive me.
I am trying to subscribe to an FCM topic for an iOS app using xcode/Objective C but when loading the App, it is not subscribing to the topic, in the debugger it doesn't even look like it is trying.
If I move the [[FIRMessaging messaging] subscribeToTopic:#"/topics/channel"];
line to just below
[FIRMessaging messaging].delegate = self;
[application registerForRemoteNotifications];
[FIRApp configure];
(and above return YES;) then at least I get this error message indicating that it is at least trying.
2018-01-04 04:00:18.723760+0000 App[1049:1251125] [Firebase/Messaging][I-FCM002010] Cannot subscribe to topic: /topics/channel with token: (null)
So following the suggestion here (and a number of other places), I have tried to move it out into didRegisterUserNotificationSettings but it doesn't seem to be doing anything at all and there is no trace of it in the debugger.
This is my full AppDelegate.m code
//
// AppDelegate.m
//
#import "AppDelegate.h"
#import <UserNotifications/UserNotifications.h>
#import <Firebase/Firebase.h>
#import <FirebaseMessaging/FirebaseMessaging.h>
#import <FirebaseInstanceID/FirebaseInstanceID.h>
#import <AFNetworking/AFNetworking.h>
#import Firebase;
#interface AppDelegate () <UNUserNotificationCenterDelegate, FIRMessagingDelegate>
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self setupNetworkReachability];
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error)
{
}];
[FIRMessaging messaging].delegate = self;
[application registerForRemoteNotifications];
[FIRApp configure];
//[[FIRMessaging messaging] subscribeToTopic:#"/topics/channel"];
return YES;
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UNNotificationSettings *)notificationSettings
{
[[FIRMessaging messaging] subscribeToTopic:#"/topics/channel"];
NSLog(#"Topic Registered");
}
- (void)applicationWillResignActive:(UIApplication *)application
{
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
}
- (void)applicationWillTerminate:(UIApplication *)application
{
}
#pragma mark - Public Methods
+ (AppDelegate *)sharedAppDelegate
{
return (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
- (void)setupNetworkReachability
{
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status)
{
if (status == AFNetworkReachabilityStatusReachableViaWiFi || status == AFNetworkReachabilityStatusReachableViaWWAN)
self.isNetworkAvailable = YES;
else
self.isNetworkAvailable = NO;
NSLog(#"Reachability: %#", AFStringFromNetworkReachabilityStatus(status));
}];
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
}
#pragma mark - FIRMessagingDelegate Methods
- (void)messaging:(nonnull FIRMessaging *)messaging didReceiveMessage:(nonnull FIRMessagingRemoteMessage *)remoteMessage
{
NSLog(#"%#", remoteMessage.appData);
}
- (void)applicationReceivedRemoteMessage:(nonnull FIRMessagingRemoteMessage *)remoteMessage
{
NSLog(#"%#", remoteMessage.appData);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
NSLog(#"%#", notification.request.content.userInfo);
completionHandler(UNNotificationPresentationOptionAlert + UNNotificationPresentationOptionSound);
}
#end
Would appreciate any help. Thank you.
Just to update, the App already receives message directly from FCM console, so that part works OK, it is just the topic subscription that is failing.
1: You should call [FIRApp configure]; before [FIRMessaging messaging].delegate = self;
2: As you post full code of your AppDelegate.m file. So it is missing the below method to update/send token to Firebase. You will receive a TOKEN with in this UIApplication's delegate method and you have to set it for Firebase (Just put this method in your AppDelegate.m file)
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
NSString *strDevicetoken = [[NSString alloc]initWithFormat:#"%#",[[[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]] stringByReplacingOccurrencesOfString:#" " withString:#""]];
NSLog(#"Device Token = %#",strDevicetoken);
[FIRMessaging messaging].APNSToken = deviceToken;
//NSString *fcmToken = [FIRMessaging messaging].FCMToken;
//NSLog(#"FCM registration token: %#", fcmToken);
}
Now you have successfully set APNS Token at Firebase and you can now subscribe to your desired topic at Firebase

Pushkit with Sinch VOIP not working with pushkit

I am trying to implement App-to-App calling with Sinch in my IOS app. I have implemented Pushkit in my iOS app with Sinch but the push notification is not working when the app is in background.
I have two questions.
Do I need another web service to send push notification to my app for incoming app separately or Sinch handles it itself.
If it does handle itself then what am I missing in my code.
#import "AppDelegate.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
[self handleLocalNotification:[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]];
self.push = [Sinch managedPushWithAPSEnvironment:SINAPSEnvironmentAutomatic];
self.push.delegate = self;
[self.push setDesiredPushTypeAutomatically];
[self.push registerUserNotificationSettings];
return YES;
}
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary *)options {
return [[GIDSignIn sharedInstance] handleURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [[GIDSignIn sharedInstance] handleURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
- (id<SINClient>)client {
return _sinchClient;
}
-(void)clientDidFail:(id<SINClient>)client error:(NSError *)error{
NSLog(#"fail");
}
-(void)clientDidStart:(id<SINClient>)client{
NSLog(#"Start");
[self voipRegistration];
}
- (void)client:(id<SINClient>)client
logMessage:(NSString *)message
area:(NSString *)area
severity:(SINLogSeverity)severity
timestamp:(NSDate *)timestamp {
// If you want all messages remove the if statement
if (severity == SINLogSeverityCritical) {
NSLog(#"%#", message);
}
}
- (void)initSinchClientWithUserId:(NSString *)userId {
if (!_sinchClient) {
_sinchClient = [Sinch clientWithApplicationKey:#"<my-key>"
applicationSecret:#"<my-secret>"
environmentHost:#"sandbox.sinch.com"
userId:userId];
_sinchClient.delegate = self;
[_sinchClient setSupportCalling:YES];
[_sinchClient startListeningOnActiveConnection];
[_sinchClient enableManagedPushNotifications];
[_sinchClient start];
}
}
- (void)handleLocalNotification:(UILocalNotification *)notification {
if (notification) {
id<SINNotificationResult> result = [self.sinchClient relayLocalNotification:notification];
if ([result isCall] && [[result callResult] isTimedOut]) {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Missed call"
message:[NSString stringWithFormat:#"Missed call from %#", [[result callResult] remoteUserId]]
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"OK", nil];
[alert show];
}
}
}
-(void)voipRegistration
{
PKPushRegistry* voipRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
voipRegistry.delegate = self;
voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}
-(void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type
{
[_sinchClient registerPushNotificationData:credentials.token];
}
-(void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(PKPushType)type{
NSLog(#"invalidated");
}
-(void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType: (NSString *)type
{
//notify
NSDictionary* dic = payload.dictionaryPayload;
NSString* sinchinfo = [dic objectForKey:#"sin"];
UILocalNotification* notif = [[UILocalNotification alloc] init];
notif.alertBody = #"incoming call";
[[UIApplication sharedApplication] presentLocalNotificationNow:notif];
if (sinchinfo == nil)
return;
dispatch_async(dispatch_get_main_queue(), ^{
[_sinchClient relayRemotePushNotificationPayload:sinchinfo];
});
}
If you integrated Pushkit and Sinch then push notification may can't catch on PushKit's delegate function - didReceiveIncomingPushWithPayload. But you can get push notification on SINManagedPushDelegate's function - didReceiveIncomingPushWithPayload.
Push notification is not coming but you can get incoming call event on there when app is in background. You can trigger local notification if app is in background to let user incoming call know.
Hope that would be helpful for you.

Is there a way to open urls received in a push notification without opening the app in ios 10?

I am trying to open a url that is passed in a push notification in ios 10.
So far I haven't found a way to open a the url without opening the app.
Is there a way to open urls received in a push notification without opening the app?
I have found a work-around to open the url (the work-around works for ios <10), but then again the app opens up first.
Update:
I've noticed that for the device (iOS 10.0)
The following mentohds get involked
application:didRegisterForRemoteNotificationsWithDeviceToken
userNotificationCenter:willPresentNotification:
userNotificationCenter:didReceiveNotificationResponse:
But -application:didReceiveRemoteNotification:fetchCompletionHandler: and -application:didReceiveRemoteNotification: aren't called.
I'm new to ios and this is how far I have gotten:
AppDelegate.h
#import <UIKit/UIKit.h>
#import <UserNotifications/UserNotifications.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>
#property (strong, nonatomic) UIWindow *window;
#end
AppDelegate.m
#import "AppDelegate.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10)
{
UNUserNotificationCenter * notificationCenter = [UNUserNotificationCenter currentNotificationCenter];
notificationCenter.delegate = self;
[notificationCenter requestAuthorizationWithOptions:UNAuthorizationOptionAlert|UNAuthorizationOptionBadge|UNAuthorizationOptionSound completionHandler:^(BOOL granted, NSError * error)
{
[[UIApplication sharedApplication] registerForRemoteNotifications];
if (error)
{
NSLog(#"Auth. error:%#",[error localizedDescription]);
}
}];
[notificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * settings) {
}];
}
else
{
UIUserNotificationType type = UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound;
UIUserNotificationSettings * settings = [UIUserNotificationSettings settingsForTypes:type categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
return YES;
}
...
#pragma mark Push Notification methods
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
NSLog(#"didReceiveRemoteNotification:");
NSString * message = [[userInfo valueForKey:#"aps"] valueForKey:#"alert"];
NSString * urlString = [[userInfo valueForKey:#"aps"] valueForKey:#"alert"];
NSLog(#"1 Received Push URL: %#", urlString);
NSURL * url = [NSURL URLWithString:urlString];
if(url!=nil)
{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10) {
// iOS 10 and above
[[UIApplication sharedApplication] openURL:url options:[NSDictionary dictionary] completionHandler:nil];
}
else
{
[[UIApplication sharedApplication] openURL:url]; // iOS <10
}
}
if (application.applicationState == UIApplicationStateInactive)
{
NSLog(#"Application inactive");
[[NSUserDefaults standardUserDefaults] setValue:message forKey:#"Push_Message"];
}
else if (application.applicationState == UIApplicationStateBackground)
{
NSLog(#"Application in background");
}
else
{
NSLog(#"Application active");
}
}
#pragma mark Notification Registration methods
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString* token = [[[[deviceToken description]
stringByReplacingOccurrencesOfString: #"<" withString: #""]
stringByReplacingOccurrencesOfString: #">" withString: #""]
stringByReplacingOccurrencesOfString: #" " withString: #""];
NSLog(#"didRegisterForRemoteNotificationsWithDeviceToken:\n%#",token);
}
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(#"Error:%#",[error localizedDescription]);
NSLog(#"Suggest:%#",[error localizedRecoverySuggestion]);
}
#pragma mark App Push notification methods
-(void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
NSLog(#"didRegisterUserNotificationSettings");
}
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(#"UserInfo: %#",userInfo);
NSString * messageString = [[userInfo valueForKey:#"aps"] valueForKey:#"alert"];
NSLog(#"Message:%#",messageString);
NSString * messageurl = [[userInfo valueForKey:#"aps"] valueForKey:#"alert"];
NSLog(#"2 Received Push URL: %#", messageurl);
NSURL * url = [NSURL URLWithString:messageurl];
if(url!=nil)
{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10) {
// iOS 10 and above
[[UIApplication sharedApplication] openURL:url options:[NSDictionary dictionary] completionHandler:nil];
}
else
{
[[UIApplication sharedApplication] openURL:url]; // iOS <10
}
}
[[NSNotificationCenter defaultCenter] postNotificationName:#"PushMessage" object:self userInfo:#{#"alertString":messageString}];
}
#pragma mark UNUserNotificationCenterDelegate methods
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
{
NSLog(#"didReceiveNotificationResponse");
//--URL click--//
//Kindly suggest what can be done here?
completionHandler(UNNotificationPresentationOptionAlert);
}
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
NSLog(#"willPresentNotification");
completionHandler(UNNotificationPresentationOptionAlert);
}
#end
Hopefully you can't control the behaviour of the push before launching the app. You get control over the push only after the app launched.

I can´t receive push notifications in background. iOS 10 - Obj c - Firebase

I'm trying to be notified in background, I followed the documentation Firebase and Apple but I can´t solve my problem.
Problem: When I send a notification from the console Firebase I receive notification perfectly foreground, but sending the same notification from Firebase and my application is in background I do not receive any data, however if I open the application, the application shows me notification, but never in background. And the funny thing is that the next day I receive all notifications in the background with the closed application.
Device: iPhone 6 - v10.0.1
EDIT: My payload:
When I send a notification in Firebase, I receive this payload, I selected high priority in Firebase but I don´t receive any priority in the payload.
My code:
#define SYSTEM_VERSION_GRATERTHAN_OR_EQUALTO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self registerForRemoteNotifications];
[FIRApp configure];
[self connectToFcm];
return YES;
}
- (void)registerForRemoteNotifications {
if(SYSTEM_VERSION_GRATERTHAN_OR_EQUALTO(#"10.0")){
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){
if(!error){
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}];
NSLog(#"Version >= 10");
}
else {
NSLog(#"version < 10");
// Code for old versions
}
}
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog(#"MODO 1: User Info: %#",notification.request.content.userInfo);
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
//Called to let your app know which action was selected by the user for a given notification.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{
NSLog(#"MODO 2: User Info: %#",response.notification.request.content.userInfo);
completionHandler();
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
NSLog(#"My token is: %#", deviceToken);
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error {
NSLog(#"Failed to get token, error: %#", error);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
for (NSString *key in userInfo) {
NSLog(#"key value: %#", key);
if ([key isEqualToString:#"notification"]) {
NSString *body = [[userInfo valueForKeyPath:key] objectForKey:#"body"];
NSLog(#"message content: %#", body);
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:5];
notification.repeatInterval = NSDayCalendarUnit;
notification.alertBody = body;
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.soundName = UILocalNotificationDefaultSoundName;
notification.applicationIconBadgeNumber = 0;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
}
NSLog(#"Message ID: %#", userInfo[#"gcm.message_id"]);
if( [UIApplication sharedApplication].applicationState == UIApplicationStateInactive )
{
NSLog( #"INACTIVE" );
completionHandler( UIBackgroundFetchResultNewData );
}
else if( [UIApplication sharedApplication].applicationState == UIApplicationStateBackground )
{
NSLog( #"BACKGROUND" );
completionHandler( UIBackgroundFetchResultNewData );
}
else
{
NSLog( #"FOREGROUND" );
completionHandler( UIBackgroundFetchResultNewData );
}
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(#"enter in background");
}
- (void)connectToFcm {
[[FIRMessaging messaging] connectWithCompletion:^(NSError * _Nullable error) {
if (error != nil) {
NSLog(#"Unable to connect to FCM. %#", error);
} else {
NSLog(#"Connected to FCM.");
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"registeredToFCM"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}];
}

Resources