SDK

Troubleshooting

In this page you'll learn what are the most common mistakes when implementing the Notificare library for iOS.

Enabling debug logging

There are times when the default logging level is not sufficient to diagnose problems. You can enable debug logging by adding the following to the NotificareOptions.plist.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>DEBUG_LOGGING_ENABLED</key>
	<true/>
</dict>
</plist>

Managing application state

Important application data, such as current device information and push state, is stored in the standard UserDefaults. It's essential to avoid manually removing these properties, as doing so can have unintended side effects, essentially resetting your application to a partially fresh state. Instead, we recommended using the appropriate functions that align with your specific use-case, such as disableRemoteNotifications() or unlaunch().

Misplaced App Keys

When implementing Notificare, the library configuration file (located at NotificareServices.plist) must contain the Application ID, Application Key and the Application Secret. Because APNS will use the sandbox servers when building directly from Xcode in the device and production servers when you distribute over-the-air, we strongly recommend you to create two apps in Notificare, one for development and another for production. This will make it easier to switch between environments. Please read more about the configuration file here.

In this page you'll learn what are the most common mistakes when implementing the Notificare library for iOS.

Switching to Production

Always check if the correct NotificareServices.plist is being included in your app. Whenever you build your app directly from Xcode in a device you will be using APNS sandbox servers so the app keys must target a Notificare DEV application. If you archive your application for Ad Hoc, App Store or Enterprise distribution you should make sure the app keys target a Notificare PROD application. Failing to set this correctly will prevent Notificare from sending notifications to the correct device tokens, since you will be registering invalid device tokens in Notificare.

Expired Certificates

Functionality like APNS and Loyalty, require certificates that have an expiration date to function properly. Notificare keeps track of these certificate's expiry date will send you reminders by email and web push notifications to the dashboard. Without valid certificates, Notificare will not be able to send notifications or generate passes rendering useless this functionality. Make sure you renew and upload these certificates to Notificare in time to avoid that these features stop working.

SwiftUI

When using the new SwiftUI App Lifecycle, the AppDelegate is not accessible unless an interceptor is specified. Our library needs to be configured in the didFinishLaunchingWithOptions method.

In the main entrypoint of your app, add an UIApplicationDelegateAdaptor.

@main
struct SampleApp: App {
    // add the interceptor
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

Create the AppDelegate.swift file and configure the library.

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        // Configure Notificare.
        Notificare.shared.configure()

        // ...

        return true
    }
}

Notification Service Extension

Including the NotificareNotificationServiceExtensionKit via Cocoapods works as expected when you use use_frameworks! in your Podfile.

However, including the library as dynamic linking results in two possible errors:

  • The application fails to build when the library is added to the application target but not to the extension target;
  • Or the lock screen image doesn't show when the library is only added to the extension target, which doesn't get embedded in the application.

As it currently stands, Cocoapods cannot correctly add the XCFramework as a dynamically linked framework when declared in both targets. To work around this issue, we recommend using Swift Package Manager to include NotificareNotificationServiceExtensionKit in the application.

Data Protection capability

Enabling the Data Protection capability for your app will set the default File Protection level to complete. Amongst other things, this causes the OS to restrict access to the database, which is necessary for the good behaviour of our libraries.

Apple recommends setting secure file protection for files containing sensitive data instead of enabling it for everything in the app. However, if you pursue the latter option, you may run into file access errors.

Since our libraries require access to the database when the device is locked (i.e. to process an incoming notification), you can opt to override the file protection level for the database by enabling the following option in your NotificareOptions.plist.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>OVERRIDE_DATABASE_FILE_PROTECTION</key>
	<true/>
</dict>
</plist>