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 the Bundle Identifier is the same as the one you used when configuring the certificate in your Apple account:

1-xcode-update

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

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

3-xcode-update

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 <Backendless-Swift.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
// Add UserNotifications and register device for push notifications in AppDelegate.swift:
import UIKit
import UserNotifications
import Backendless

@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):

4-xcode-update

Activate the created service extension:

5-xcode-update

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:

target 'YOUR-PROJECT-NAME' do   
  use_frameworks!   
  pod 'BackendlessSwift'   
end   

target 'NotificationService' do  
  use_frameworks!   
  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:

// 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 <Backendless-Swift.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
// Add UserNotifications and register device for push notifications in AppDelegate.swift:
import UIKit
import UserNotifications
import Backendless

@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)")
   }
}

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.

6-xcode-update

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

7-xcode-update

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:

8-xcode-update

Adding entitlements for the NotificationService target:

9-xcode-update