Skip to content

Xcode Project Setup

Receiving push notifications in your iOS app requires making some changes in the project setup. The instructions below will walk you through the required setup.

Open a Terminal window and change the current directory to the project root.

  • If Podfile does not exist, run the following command: pod init
    Open the created Podfile and add a reference to the BackendlessSwift pod. The file should look as shown below:

    # Uncomment the next line to define a global platform for your project
    # platform :ios, '9.0'
    
    target 'YOUR-PROJECT-NAME' do
      # Comment the next line if you don't want to use dynamic frameworks
      use_frameworks!
    
      # Pods for PushNotificationsApp
      pod 'BackendlessSwift'
    end
    

  • If Podfile exists, make sure it references the BackendlessSwift pod as shown above.

Run the following command to install the pod(s):

pod install

Open .xcworkspace file to launch your project.

Make sure your application responds to your push notification certificate:

setup1

The next step is to add the User Notifications Framework to the project. Select Project > Target > Build Phases > Link Binary with Libraries:
setup2

Switch to the Capabilities section (Project > Target > Capabilities > Push Notifications) and enable Push Notifications:

setup3

Further configuration steps will vary between Objective-C and Swift, use the corresponding tab below:

Add UserNotifications in AppDelegate.h:

#import <UIKit/UIKit.h>
#import <UserNotifications/UserNotifications.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

Register device for push notifications in AppDelegate.m:

#import "AppDelegate.h"
#import <SwiftSDK/SwiftSDK.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // init Backendless
    [Backendless.shared initAppWithApplicationId:APPLICATION_ID apiKey:API_KEY];

    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionBadge + UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }];
    return YES;
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    [Backendless.shared.messaging registerDeviceWithDeviceToken:deviceToken responseHandler:^(NSString *registrationId) {
        NSLog(@"Device has been registered in Backendless");
    } errorHandler:^(Fault *fault) {
        NSLog(@"Error: %@", fault.message);
    }];
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"Device registration failed: %@", error.description);
}

@end

Create Notification Service Extension named "NotificationService" (File > New > Target > Notification Service Extension):

setup4

Activate the created service extension:

activate-notification-service-scheme

Open Podfile and modify it so that the Backendless pod is installed for the added notification service. Notice the sample Podfile below uses the NotificationService name, which is the same name shown in the Choose options for your new target window above:

# Uncomment the next line to define a global platform for your project  
# platform :ios, '9.0'  

target 'YOUR-PROJECT-NAME' do  
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks  
  use_frameworks!  

  # Pods for YOUR-PROJECT-NAME  
pod 'BackendlessSwift'  

end  

target 'NotificationService' do  
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks  
  use_frameworks!  

  # Pods for NotificationService  
pod 'BackendlessSwift'  

end

Close the Xcode project as you will need to re-run pod installation. Open a Terminal window and change the current directory to the project's root. Run the following command:

pod install

Reopen the Xcode project after the command above completes its execution.

Modify the NotificationService.m class so it looks as shown below:

#import "NotificationService.h"
#import <SwiftSDK/SwiftSDK.h>

@interface NotificationService ()

@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    [BackendlessPushHelper.shared processMutableContentWithRequest:request contentHandler:contentHandler];
}

- (void)serviceExtensionTimeWillExpire {
    self.contentHandler(self.bestAttemptContent);
}

@end

Open Info.plist, in both NotificationService and your target and make sure both of them contain App Transport Security Settings with the following configuration:

setup5

Since both the app and the notification service extension use the same storage, it is important to add an App Group (see the Apple Developer documentation for details about sharing data between service extension and the containing app). To create an app group navigate to Project > Target > Capabilities > App Groups. Select your app target and add an app group. The name of the group should contain BackendlessPushTemplatesand its name should be unique. E.g. it could be group.TeamID.BackendlessPushTemplates.

setup6

In addition to the app target, the group must also be added for the notification service extension:

setup7

After the group is added to your targets, it is necessary to add an entitlements file in the Copy Bundle Resources section on the Build Phases tab. It is important that this step is done for both app target as well as the NotificationService target. Note that the name of the entitelements file matches the name of the target:

setup8

Adding entitlements for the NotificationService target:

setup9

Add UserNotifications and register device for push notifications in AppDelegate.swift:

import UIKit
import UserNotifications
import SwiftSDK

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

   var window: UIWindow?

   func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
      // init Backendless
      Backendless.shared.initApp(applicationId: APPLICATION_ID, apiKey: API_KEY)

      let center = UNUserNotificationCenter.current()
      center.delegate = self
      center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
         UIApplication.shared.registerForRemoteNotifications()
      }
      return true
   }

   func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
      // register device in Backendless
      Backendless.shared.messaging.registerDevice(deviceToken: deviceToken, responseHandler: { registrationId in
         print("Device has been registered in Backendless")
      }, errorHandler: { fault in
         print("Error: \(fault.message ?? "")")
      })
   }

   func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
      print("Device registration failed: \(error.localizedDescription)")
   }
}

Create Notification Service Extension named "NotificationService" (File > New > Target > Notification Service Extension):

setup4

Activate the created service extension:

activate-notification-service-scheme

Open Podfile and modify it so that the Backendless pod is installed for the added notification service. Notice the sample Podfile below uses the NotificationService name, which is the same name shown in the Choose options for your new target window above:

# Uncomment the next line to define a global platform for your project  
# platform :ios, '9.0'  

target 'YOUR-PROJECT-NAME' do  
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks  
  use_frameworks!  

  # Pods for YOUR-PROJECT-NAME  
pod 'Backendless'  

end  

target 'NotificationService' do  
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks  
  use_frameworks!  

  # Pods for NotificationService  
pod 'Backendless'  

end

Open a Terminal window and change the current directory to the project's root. Run the following command:

pod install

Modify the NotificationService.swift class so it looks as shown below:

import UserNotifications
import SwiftSDK

class NotificationService: UNNotificationServiceExtension {

   var contentHandler: ((UNNotificationContent) -> Void)?
   var bestAttemptContent: UNMutableNotificationContent?

   override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
      BackendlessPushHelper.shared.processMutableContent(request: request, contentHandler: contentHandler)
   }

   override func serviceExtensionTimeWillExpire() {
      if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
         contentHandler(bestAttemptContent)
      }
   }
}

Open Info.plist, in both NotificationService and your target and make sure both of them contain App Transport Security Settings with the following configuration:

setup5

Since both the app and the notification service extension use the same storage, it is important to add an App Group (see the Apple Developer documentation for details about sharing data between service extension and the containing app). To create an app group navigate to Project > Target > Capabilities > App Groups. Select your app target and add an app group. The name of the group should contain BackendlessPushTemplatesand its name should be unique. E.g. it could be group.TeamID.BackendlessPushTemplates.

setup6

In addition to the app target, the group must also be added for the notification service extension:

setup7

After the group is added to your targets, it is necessary to add an entitlements file in the Copy Bundle Resources section on the Build Phases tab. It is important that this step is done for both app target as well as the NotificationService target. Note that the name of the entitelements file matches the name of the target:

setup8

Adding entitlements for the NotificationService target:

setup9