I'm trying to receive voip(and regular) push notification work on my app for sinch calls.
The code its already receiving calls when the app is in foreground.
And background with local nofitications
And the certificate for push is working sending pushes with pusher app in mac, i follow the tutorials and dont know what i'm missing
My code:
class AppDelegate: UIResponder, UIApplicationDelegate, SINCallClientDelegate, SINCallDelegate, SINMessageClientDelegate, SINClientDelegate, SINManagedPushDelegate {
var msgClient:SINMessageClient!
var window: UIWindow?
var applicationKey:String!
var applicationSecret:String!
var environmentHost:String!
var voipClient:SINClient!
var push:SINManagedPush!
func requestUserNotificationPermission() {
if UIApplication.sharedApplication().respondsToSelector("registerUserNotificationSettings:") {
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()
}
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
self.push.application(application, didReceiveRemoteNotification: userInfo)
}
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
self.handleLocalNotification(notification)
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
self.push.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
}
func startSinch() {
if self.voipClient == nil {
self.push.registerUserNotificationSettings()
let userID = "partner-4" //fixed for tests
self.voipClient = Sinch.clientWithApplicationKey(applicationKey, applicationSecret:applicationSecret,environmentHost:environmentHost,userId: userID)
self.voipClient.delegate = self;
//commented to test push but is working
//self.voipClient.setSupportActiveConnectionInBackground(true)
self.voipClient.enableManagedPushNotifications()
self.voipClient.setSupportCalling(true)
self.voipClient.setSupportMessaging(true);
self.voipClient.start()
self.voipClient.startListeningOnActiveConnection()
self.msgClient = self.voipClient.messageClient()
self.msgClient.delegate = self
}
}
func managedPush(managedPush: SINManagedPush!, didReceiveIncomingPushWithPayload payload: [NSObject : AnyObject]!, forType pushType: String!) {
self.handleRemoteNotification(payload)
}
func handleRemoteNotification(userInfo: NSDictionary){
if (self.voipClient == nil) {
self.startSinch()
}
self.voipClient.relayRemotePushNotification(userInfo as [NSObject : AnyObject])
}
func client(client: SINCallClient!, localNotificationForIncomingCall call: SINCall!) -> SINLocalNotification! {
let notification = SINLocalNotification()
notification.alertAction = "test"
notification.alertBody = "test"
notification.soundName = "notification-sound.caf"
return notification
}
func relayLocalNotification(notification: UILocalNotification) -> SINNotificationResult{
return self.voipClient.relayLocalNotification(notification)
}
Related
I'm using iOS version 9 and swift as well. I Can receive a call while the app is is active but when the app is closed or in the background, I have an issue, It only gets a notification, not a full ringtone (I'm using SinchService) but it's not working. I've added the VoIP certificate and it's valid
code
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
sinch?.push().application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
sinch?.push().application(application, didReceiveRemoteNotification: userInfo)
}
func startManager() {
let config = SinchService.config(withApplicationKey: VoiceManager.SinchKey, applicationSecret: VoiceManager.SinchSecret, environmentHost: VoiceManager.SinchHost).pushNotifications(with: SINAPSEnvironment.development)
let sinch = SinchService.service(with: config)
sinch?.delegate = self
sinch?.callClient().delegate = self
let push = Sinch.managedPush(with: SINAPSEnvironment.development)
push?.delegate = self
push?.setDesiredPushTypeAutomatically()
let appDelegate: AppDelegate = (UIApplication.shared.delegate as! AppDelegate)
appDelegate.sinch = sinch
appDelegate.push = push
}
// MARK: - SINCallClientDelegate
func client(_ client: SINCallClient!, didReceiveIncomingCall call: SINCall!) {
//show calling view
let controller = UIViewController.currentViewController()
VoiceCallingViewController.show(call: call, viewController: controller)
}
func client(_ client: SINCallClient!, localNotificationForIncomingCall call: SINCall!) -> SINLocalNotification! {
let notification = SINLocalNotification()
notification.alertAction! = LanguageManager.localizedString(key: "answer")
notification.alertBody = "\(LanguageManager.localizedString(key: "incomming-call")) \(call.remoteUserId)"
return notification
}
you are not setting any sound in you localnotification method. add sound to notification
I'm making this sweet app that requires Push notifications.
However when trying to grab the Push token not all required functions seem to get executed.
The user does get presented with this Alert:
When the user hits OK I step through my code and see that not everything gets executed:
override func viewDidLoad(){
let tapper = UITapGestureRecognizer(target: view, action:#selector(UIView.endEditing))
tapper.cancelsTouchesInView = false
view.addGestureRecognizer(tapper)
print("gets called")
registerForPushNotifications(UIApplication.sharedApplication())
}
func registerForPushNotifications(application: UIApplication) {
print("gets called")
let notificationSettings = UIUserNotificationSettings(
forTypes: [.Badge, .Sound, .Alert], categories: nil)
application.registerUserNotificationSettings(notificationSettings)
}
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
print("doesn't get called")
if notificationSettings.types != .None {
application.registerForRemoteNotifications()
}
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
print("doesn't get called")
let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
var apnsTokenString = ""
for i in 0..<deviceToken.length {
apnsTokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
}
Constant.pushToken = apnsTokenString
print("Device Token:", Constant.pushToken)
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
debugPrint("Error Registering Remote Notification")
}
In my console the following gets printed:
gets called
gets called
Meaning that not all required functions get called. What am I doing wrong?
Assuming all of the code you posted in your question is in your view controller class, the problem is that you need to put the UIApplicationDelegate methods in your actual app delegate class, not the view controller class. Simply move those methods to the proper class and they will work.
Just use this code
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
print("gets called")
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let characterSet: NSCharacterSet = NSCharacterSet(charactersInString: "<>")
let deviceTokenString: String = (deviceToken.description as NSString)
.stringByTrimmingCharactersInSet(characterSet)
.stringByReplacingOccurrencesOfString( " ", withString: "") as String
print(deviceTokenString)
}
I am trying to test my app and I noticed that handleActionWithIdentifier: forLocalNotification does not fire. While the app is in the foreground, this delegate method should fire after the user clicks on the action. I have read other posts about this, but most of them refer to the completionHandler() at the bottom of the method. I cannot seem to find a solution. If I put my app in the background, didReceiveLocalNotification does fire correctly. I am truly stumped. Here is my code...
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let notificationActionOk = UIMutableUserNotificationAction()
notificationActionOk.identifier = "ALARM_IDENTIFIER"
notificationActionOk.title = "Ok"
notificationActionOk.destructive = false
notificationActionOk.authenticationRequired = false
notificationActionOk.activationMode = UIUserNotificationActivationMode.Background
let notificationCategory = UIMutableUserNotificationCategory()
notificationCategory.identifier = "ALARM_CATEGORY"
notificationCategory.setActions([notificationActionOk], forContext: UIUserNotificationActionContext.Default)
notificationCategory.setActions([notificationActionOk], forContext: UIUserNotificationActionContext.Minimal)
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Sound], categories: [notificationCategory])
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
return true
}
func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) {
print("Handle action \(identifier)")
completionHandler()
//I cannot get this method to fire.
}
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
print("Received local notification")
//This method fires correctly
}
}
I am tired of doing this. Let me tell you whats happening. I am using iOS 9.0 & Xcode 7.3.1.
Situation 1 :
I have registered for local notification settings in didFinishLaunchingWithOptions like this.
let settings = UIUserNotificationSettings(forTypes: [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound] , categories: nil)
application.registerUserNotificationSettings(settings)
I have several controllers in my project, user will be pressing one button in one of these and I will be scheduling a notification by calling a function in App Delegate. The function is given below.
func activatingUserLocalNotification(timeIntervalSinceNow : NSDate?, alertBody : String, userInfo : [NSObject : AnyObject], region : CLRegion?)
{
let localNotification = UILocalNotification()
localNotification.fireDate = timeIntervalSinceNow
localNotification.timeZone = NSTimeZone.defaultTimeZone()
localNotification.alertBody = alertBody
localNotification.region = region
localNotification.regionTriggersOnce = false
localNotification.soundName = UILocalNotificationDefaultSoundName
localNotification.userInfo = userInfo
localNotification.applicationIconBadgeNumber = UIApplication.sharedApplication().applicationIconBadgeNumber + 1
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
Now I have set a notification by pressing on a button, which called this above function it successfully scheduled the notification.
I have set breakpoints in all these methods.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
// Break Point
return true
}
func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, withResponseInfo responseInfo: [NSObject : AnyObject], completionHandler: () -> Void) {
// Break Point
}
func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) {
// Break Point
}
func application(application: UIApplication, didReceivelocalNotification notification: UILocalNotification)
{
// Break Point
}
And waited for sometime while the app is in Foreground, Waited some more time. Nothing happened. I thought the app would fire up the notification and one of the method would get called, so that I could present the notification inside the app. But nothing happened.
Situation 2 :
Now I have tried the same, now I minimised the app [ App is in Background state ] by going to an another app and using it for sometime. Now the notification fired up properly, just like I have told you I have set breakpoints in almost all methods but none of them called when I clicked on the notification. But it called applicationWillEnterForeground, What am gonna do with this method without the launchOptions.
It's been two days I am fighting with this, Don't have any idea about whats happening.
Push Notifications Works Fine Though [ Inside & Outside the App ].
Let me know your thoughts? Please.
How I call this function activatingUserLocalNotification from a controller.
func setLocalNotificationForDistance(id : String, name : String, location : CLLocationCoordinate2D, radius : Double)
{
let alertBody = "Hello \(name)"
let dict : [NSObject : AnyObject] = ["aps" : ["alert" : alertBody], “id” : id]
let region = CLCircularRegion(center: location, radius: radius, identifier: id)
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.activatingUserLocalNotification(nil, alertBody: alertBody, userInfo: dict, region: region)
}
App Delegate
//
// AppDelegate.swift
//
//
import UIKit
import FBSDKCoreKit
import SVProgressHUD
import Alamofire
import GoogleMaps
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
//MARK: Local Variables
var window: UIWindow?
static let UpdateRootNotification = "UpdateRootNotification"
static let ShowMainUINotification = "ShowMainUINotification"
//MARK: Application Life Cycle
// Did Finish Launching
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
let settings = UIUserNotificationSettings(forTypes: [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound] , categories: nil)
application.registerUserNotificationSettings(settings)
return true
}
// Foreground
func applicationWillEnterForeground(application: UIApplication) {
}
// Did Become Active
func applicationDidBecomeActive(application: UIApplication) {
FBSDKAppEvents.activateApp()
application.applicationIconBadgeNumber = 0 // clear badge icon
}
// Did Enter Background
func applicationDidEnterBackground(application: UIApplication) {
}
// Opened Via Shortcut
func application(application: UIApplication, performActionForShortcutItem
shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
}
// Continue User Activity
func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity,
restorationHandler: ([AnyObject]?) -> Void) -> Bool {
return true
}
//MARK: Local Notification
func activatingUserLocalNotification(timeIntervalSinceNow : NSDate?, alertBody : String, userInfo : [NSObject : AnyObject], region : CLRegion?)
{
let localNotification = UILocalNotification()
localNotification.fireDate = timeIntervalSinceNow
localNotification.timeZone = NSTimeZone.defaultTimeZone()
localNotification.alertBody = alertBody
localNotification.region = region
localNotification.regionTriggersOnce = false
localNotification.soundName = UILocalNotificationDefaultSoundName
localNotification.userInfo = userInfo
localNotification.applicationIconBadgeNumber = UIApplication.sharedApplication().applicationIconBadgeNumber + 1
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, withResponseInfo responseInfo: [NSObject : AnyObject], completionHandler: () -> Void) {
}
func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) {
}
func application(application: UIApplication, didReceivelocalNotification notification: UILocalNotification)
{
application.applicationIconBadgeNumber = 0
UIApplication.sharedApplication().presentLocalNotificationNow(notification)
}
// MARK: Push Notification
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
if API.sharedInstance.isLoggedIn() {
NSUserDefaults.standardUserDefaults().setObject(deviceToken, forKey: "push_token")
NSUserDefaults.standardUserDefaults().synchronize()
API.sharedInstance.registerDeviceToken(deviceToken)
}
}
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
application.registerForRemoteNotifications()
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
EventTracker.trackEventWithCategory("APN", action: "Registraion", label: "Failed")
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
APNSManager.sharedInstance.handlePushNotification(userInfo)
}
//MARK: Open URL
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, openURL:url,sourceApplication:sourceApplication,annotation:annotation)
}
}
This is a bit funny, but change:
func application(application: UIApplication, didReceivelocalNotification notification: UILocalNotification)
To:
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification)
Note the capital L. From docs:
Also: expect this delegate method to be called only when your app is active. No notification should be visible in that situation as your app is active. You can handle it by using didReceiveLocalNotification delegate method.
I'm using push notifications on my app, and i didn't find a way to display only once notifications that have same content.
Is that possible ?
My code :
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UIAlertViewDelegate, GGLInstanceIDDelegate, GCMReceiverDelegate {
var window: UIWindow?
var gcmSenderID: String?
var registrationOptions = [String: AnyObject]()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
var configureError:NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError)")
gcmSenderID = GGLContext.sharedInstance().configuration.gcmSenderID
UIApplication.sharedApplication().registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: [category]))
UIApplication.sharedApplication().registerForRemoteNotifications()
let gcmConfig = GCMConfig.defaultConfig()
gcmConfig.receiverDelegate = self
GCMService.sharedInstance().startWithConfig(gcmConfig)
return true
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let instanceIDConfig = GGLInstanceIDConfig.defaultConfig()
instanceIDConfig.delegate = self
GGLInstanceID.sharedInstance().startWithConfig(instanceIDConfig)
registrationOptions = [kGGLInstanceIDRegisterAPNSOption:deviceToken,
kGGLInstanceIDAPNSServerTypeSandboxOption:true]
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
print(error.localizedDescription)
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
GCMService.sharedInstance().appDidReceiveMessage(userInfo)
}
func applicationDidEnterBackground(application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
GCMService.sharedInstance().disconnect()
}
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
GCMService.sharedInstance().connectWithHandler({(error:NSError?) -> Void in
if let error = error {
print("Could not connect to GCM: \(error.localizedDescription)")
} else {
print("Connected to GCM")
}
})
}
func onTokenRefresh() {
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID, scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
}
func registrationHandler(registrationToken: String!, error: NSError!) {
if(registrationToken != nil) {
print(registrationToken)
}else{
print("Registration to GCM failed with error: \(error.localizedDescription)")
}
}
}
I'm using Google Cloud Messaging for push notification into my app
Thank's in advance