How to set up push notifications in Swift

IosSwiftApple Push-Notifications

Ios Problem Overview


I am trying to set up a push notification system for my application. I have a server and a developer license to set up the push notification service.

I am currently running my app in Swift. I would like to be able to send the notifications remotely from my server. How can I do this?

Ios Solutions


Solution 1 - Ios

Swift 2:

let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()

Solution 2 - Ios

While the answer is given well to handle push notification, still I believe to share integrated complete case at once to ease:

To Register Application for APNS, (Include the following code in didFinishLaunchingWithOptions method inside AppDelegate.swift)


IOS 9

var settings : UIUserNotificationSettings = UIUserNotificationSettings(forTypes:UIUserNotificationType.Alert|UIUserNotificationType.Sound, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()

After IOS 10

Introduced UserNotifications framework:

Import the UserNotifications framework and add the UNUserNotificationCenterDelegate in AppDelegate.swift


To Register Application for APNS

let center = UNUserNotificationCenter.current()
center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in

    // If granted comes true you can enabled features based on authorization.
    guard granted else { return }

    application.registerForRemoteNotifications()
}

This will call following delegate method

func application(application: UIApplication,didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
//send this device token to server
}

//Called if unable to register for APNS.
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {

println(error)

}

On Receiving notification following delegate will call:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {

    println("Recived: \(userInfo)")
   //Parsing userinfo:
   var temp : NSDictionary = userInfo
   if let info = userInfo["aps"] as? Dictionary<String, AnyObject> 
            {
                var alertMsg = info["alert"] as! String
                var alert: UIAlertView!
                alert = UIAlertView(title: "", message: alertMsg, delegate: nil, cancelButtonTitle: "OK")
                alert.show()
            }
}

To be identify the permission given we can use:

UNUserNotificationCenter.current().getNotificationSettings(){ (setttings) in

        switch setttings.soundSetting{
        case .enabled:
            print("enabled sound")

        case .disabled:
            print("not allowed notifications")

        case .notSupported:
            print("something went wrong here")
        }
    }

So the checklist of APNS:

  • Create AppId allowed with Push Notification
  • Create SSL certificate with valid certificate and app id
  • Create Provisioning profile with same certificate and make sure to add device in case of sandboxing(development provisioning)

Note: That will be good if Create Provisioning profile after SSL Certificate.

With Code:

  • Register app for push notification
  • Handle didRegisterForRemoteNotificationsWithDeviceToken method
  • Set targets> Capability> background modes> Remote Notification
  • Handle didReceiveRemoteNotification

Solution 3 - Ios

To register to receive push notifications via Apple Push Service you have to call a registerForRemoteNotifications() method of UIApplication.

If registration succeeds, the app calls your app delegate object’s application:didRegisterForRemoteNotificationsWithDeviceToken: method and passes it a device token.

You should pass this token along to the server you use to generate push notifications for the device. If registration fails, the app calls its app delegate’s application:didFailToRegisterForRemoteNotificationsWithError: method instead.

Have a look into Local and Push Notification Programming Guide.

Solution 4 - Ios

registerForRemoteNotification() has been removed from ios8.

So you should use UIUserNotification

CODE EXAMPLE:

var type = UIUserNotificationType.Badge | UIUserNotificationType.Alert | UIUserNotificationType.Sound;
var setting = UIUserNotificationSettings(forTypes: type, categories: nil);
UIApplication.sharedApplication().registerUserNotificationSettings(setting);
UIApplication.sharedApplication().registerForRemoteNotifications();

Hope this will help you.

Solution 5 - Ios

To support ios 8 and before, use this:

// Register for Push Notitications, if running iOS 8
if application.respondsToSelector("registerUserNotificationSettings:") {
  
  let types:UIUserNotificationType = (.Alert | .Badge | .Sound)
  let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: types, categories: nil)

  application.registerUserNotificationSettings(settings)
  application.registerForRemoteNotifications()
  
} else {      
  // Register for Push Notifications before iOS 8
  application.registerForRemoteNotificationTypes(.Alert | .Badge | .Sound)
}

Solution 6 - Ios

Swift 4

I think this is the correct way for setup in iOS 8 and above.

Turn on Push Notifications in the Capabilities tab enter image description here

Import UserNotifications

import UserNotifications

Modify didFinishLaunchingWithOptions

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
    
    if let notification = launchOptions?[.remoteNotification] as? [String: AnyObject] {
        
        // If your app wasn’t running and the user launches it by tapping the push notification, the push notification is passed to your app in the launchOptions
        
        let aps = notification["aps"] as! [String: AnyObject]
        UIApplication.shared.applicationIconBadgeNumber = 0
    }
    
    registerForPushNotifications()
    
    return true
}

> It’s extremely important to call registerUserNotificationSettings(_:) every time the app launches. This is because the user can, at any time, go into the Settings app and change the notification permissions. application(_:didRegisterUserNotificationSettings:) will always provide you with what permissions the user currently has allowed for your app.

Copy paste this AppDelegate extension

// Push Notificaion
extension AppDelegate {
func registerForPushNotifications() {
    if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) {
            [weak self] (granted, error) in
            print("Permission granted: \(granted)")
            
            guard granted else {
                print("Please enable \"Notifications\" from App Settings.")
                self?.showPermissionAlert()
                return
            }
            
            self?.getNotificationSettings()
        }
    } else {
        let settings = UIUserNotificationSettings(types: [.alert, .sound, .badge], categories: nil)
        UIApplication.shared.registerUserNotificationSettings(settings)
        UIApplication.shared.registerForRemoteNotifications()
    }
}

@available(iOS 10.0, *)
func getNotificationSettings() {
    
    UNUserNotificationCenter.current().getNotificationSettings { (settings) in
        print("Notification settings: \(settings)")
        guard settings.authorizationStatus == .authorized else { return }
        DispatchQueue.main.async {
            UIApplication.shared.registerForRemoteNotifications()
        }
    }
}

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    
    let tokenParts = deviceToken.map { data -> String in
        return String(format: "%02.2hhx", data)
    }
    
    let token = tokenParts.joined()
    print("Device Token: \(token)")
    //UserDefaults.standard.set(token, forKey: DEVICE_TOKEN)
}

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    print("Failed to register: \(error)")
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
    
    // If your app was running and in the foreground
    // Or
    // If your app was running or suspended in the background and the user brings it to the foreground by tapping the push notification
    
    print("didReceiveRemoteNotification /(userInfo)")
    
    guard let dict = userInfo["aps"]  as? [String: Any], let msg = dict ["alert"] as? String else {
        print("Notification Parsing Error")
        return
    }
}

func showPermissionAlert() {
    let alert = UIAlertController(title: "WARNING", message: "Please enable access to Notifications in the Settings app.", preferredStyle: .alert)
    
    let settingsAction = UIAlertAction(title: "Settings", style: .default) {[weak self] (alertAction) in
        self?.gotoAppSettings()
    }
    
    let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
    
    alert.addAction(settingsAction)
    alert.addAction(cancelAction)
    
    DispatchQueue.main.async {
        self.window?.rootViewController?.present(alert, animated: true, completion: nil)
    }
}

private func gotoAppSettings() {
    
    guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
        return
    }
    
    if UIApplication.shared.canOpenURL(settingsUrl) {
        UIApplication.shared.openURL(settingsUrl)
    }
}
}

Check out: Push Notifications Tutorial: Getting Started

Solution 7 - Ios

Thanks for the earlier answers. Xcode has made some changes and here's the SWIFT 2 code that passes XCode 7 code check and supports both iOS 7 and above:

    if #available(iOS 8.0, *) {
        let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
        UIApplication.sharedApplication().registerUserNotificationSettings(settings)
        UIApplication.sharedApplication().registerForRemoteNotifications()
    } else {
        let settings = UIRemoteNotificationType.Alert.union(UIRemoteNotificationType.Badge).union(UIRemoteNotificationType.Sound)
        UIApplication.sharedApplication().registerForRemoteNotificationTypes(settings)
    }

Solution 8 - Ios

Swift 4

Import the UserNotifications framework and add the UNUserNotificationCenterDelegate in AppDelegate

import UserNotifications

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate

To Register Application for APNS, (Include the following code in didFinishLaunchingWithOptions method inside AppDelegate.swift)

let center = UNUserNotificationCenter.current()
    center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
        // Enable or disable features based on authorization.
    }
    application.registerForRemoteNotifications()

This will call following delegate method

func application(_ application: UIApplication,didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    //send this device token to server
    
}

//Called if unable to register for APNS.
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    print(error)
}

On Receiving notification following delegate will call:

private func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
    
    print("Recived: \(userInfo)")
    //Parsing userinfo:

}

Solution 9 - Ios

Swift 3:

let center = UNUserNotificationCenter.current()
center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
        // Enable or disable features based on authorization.
    }
UIApplication.shared.registerForRemoteNotifications()

Make sure to import UserNotifications at the top of your view controller.

import UserNotifications

Solution 10 - Ios

You can send notification using the following code snippet:

let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
if(UIApplication.sharedApplication().currentUserNotificationSettings() == settings ){
//OK
}else{
//KO
}

Solution 11 - Ios

I use this code snip in AppDelegate.swift:

let pushType = UIUserNotificationType.alert.union(.badge).union(.sound)
let pushSettings = UIUserNotificationSettings(types: pushType
			, categories: nil)

application.registerUserNotificationSettings(pushSettings)
application.registerForRemoteNotifications()

Solution 12 - Ios

100% Working... You Can read onesignal document and setup properly https://documentation.onesignal.com/docs/ios-sdk-setup OneSignal below code import in AppDelegate

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    OneSignal.setLogLevel(.LL_VERBOSE, visualLevel: .LL_NONE)
    
    // OneSignal initialization
    let onesignalInitSettings = [kOSSettingsKeyAutoPrompt: false, kOSSettingsKeyInAppLaunchURL: false]
    
    OneSignal.initWithLaunchOptions(launchOptions,
                                    appId: "YOUR_ONE_SIGNAL_ID",
                                    handleNotificationAction: nil,
                                    settings: onesignalInitSettings)
    
    OneSignal.inFocusDisplayType = OSNotificationDisplayType.inAppAlert;
    // promptForPushNotifications will show the native iOS notification permission prompt.
    // We recommend removing the following code and instead using an In-App Message to prompt for notification permission (See step 8)
    OneSignal.promptForPushNotifications(userResponse: { accepted in
        print("User accepted notifications: \(accepted)")
    })

    return true
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBlakeHView Question on Stackoverflow
Solution 1 - IosAdam WaiteView Answer on Stackoverflow
Solution 2 - IosArvindView Answer on Stackoverflow
Solution 3 - IosRafa de KingView Answer on Stackoverflow
Solution 4 - IosDog SuView Answer on Stackoverflow
Solution 5 - IosGmeister4View Answer on Stackoverflow
Solution 6 - IosWarif Akhand RishiView Answer on Stackoverflow
Solution 7 - IosOliver ZhangView Answer on Stackoverflow
Solution 8 - IosjojoView Answer on Stackoverflow
Solution 9 - IosHenryView Answer on Stackoverflow
Solution 10 - IosGPYView Answer on Stackoverflow
Solution 11 - IosZYiOSView Answer on Stackoverflow
Solution 12 - IosKaran VakhariaView Answer on Stackoverflow