iOS Advanced Features
Send Location Information to CleverTap
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
[CleverTap setLocation: newLocation.coordinate];
}
func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation,
fromLocation oldLocation: CLLocation) {
CleverTap.setLocation(newLocation.coordinate)
}
Manually Enable Support for Universal (Deep) Link Tracking
Deep links are a way of launching a native app and providing additional information telling it to do some specific event or show specific content. CleverTap automatically tracks universal links that open your application. If you have universal (deep) links coming to your app, you can capture the incoming UTM parameters easily. Call handleOpenURL:sourceApplication: when the application:openURL:sourceApplication:annotation: message is sent to your app delegate.
- (BOOL) application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
[[CleverTap sharedInstance] handleOpenURL:url sourceApplication:sourceApplication];
return YES;
}
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary *)options {
[[CleverTap sharedInstance] handleOpenURL:url sourceApplication:nil];
return YES;
}
- (void)openURL:(NSURL*)url options:(NSDictionary<NSString *, id> *)options
completionHandler:(void (^ __nullable)(BOOL success))completion {
[[CleverTap sharedInstance] handleOpenURL:url sourceApplication:nil];
if (completion) {
completion(YES);
}
}
func application(application: UIApplication, openURL url: NSURL,
sourceApplication: String?, annotation: AnyObject) -> Bool {
CleverTap.sharedInstance()?.handleOpenURL(url, sourceApplication: sourceApplication)
return true
}
// Swift 3
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
CleverTap.sharedInstance()?.handleOpen(url, sourceApplication: nil)
return true
}
func open(_ url: URL, options: [String : Any] = [:],
completionHandler completion: ((Bool) -> Swift.Void)? = nil) {
CleverTap.sharedInstance()?.handleOpen(url, sourceApplication: nil)
completion?(false)
}
Debugging
By default, CleverTap logs are set to CleverTapLogLevel.info. During development, we recommend that you set the SDK to DEBUG mode, in order to log warnings or other important messages to the iOS logging system. This can be done by setting the debug level to CleverTapLogLevel.debug. If you want to disable CleverTap logs for production environment, you can set the debug level to CleverTapLogLevel.off.
#ifdef DEBUG
[CleverTap setDebugLevel:CleverTapLogDebug];
#else
[CleverTap setDebugLevel:CleverTapLogOff];
#endif
#if DEBUG
CleverTap.setDebugLevel(CleverTapLogLevel.debug.rawValue)
#else
CleverTap.setDebugLevel(CleverTapLogLevel.off.rawValue)
#endif
To debug the device in the CleverTap dashboard and check if events and profiles are being logged successfully on dashboard:
- Copy the CleverTap ID from the logs.
- Open the CleverTap dashboard.
- Navigate to Segments> Find People > search By Identity.
Setting Account Credentials
If you do not wish to insert your account credentials in your app’s Info.plist
, or you want to set your account ID programmatically, you can do so in your app delegate, in application:didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[CleverTap setCredentialsWithAccountID:@"Your account ID here" andToken:@"Your account token here"];
[CleverTap autoIntegrate];
...
return YES;
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject:AnyObject]?) -> Bool {
CleverTap.setCredentialsWithAccountID("Your account ID here", andToken: "Your account token here")
CleverTap.autoIntegrate()
...
return true
}
If you have set used this method to set your CleverTap Account ID and Token, please ensure that you do not make an entry for these values in your info.plist
files.
Checking Push Notifications from CleverTap
If you wish to determine whether a notification originated from CleverTap, call this method:
- (BOOL)isCleverTapNotification:(NSDictionary *)payload;
You must manually call the SDK as follows/add the following CleverTap code to your AppDelegate:
- (void) userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
/**
Use this method to perform the tasks associated with your app's custom actions. When the user responds to a notification, the system calls this method with the results. You use this method to perform the task associated with that action, if at all. At the end of your implementation, you must call the completionHandler block to let the system know that you are done processing the notification.
You specify your app's notification types and custom actions using UNNotificationCategory and UNNotificationAction objects.
You create these objects at initialization time and register them with the user notification center. Even if you register custom actions, the action in the response parameter might indicate that the user dismissed the notification without performing any of your actions.
If you do not implement this method, your app never responds to custom actions.
see https://developer.apple.com/reference/usernotifications/unusernotificationcenterdelegate/1649501-usernotificationcenter?language=objc
**/
if ([[CleverTap sharedInstance] isCleverTapNotification:response.notification.request.content.userInfo]) {
...
}
completionHandler();
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
/**
Use this method to perform the tasks associated with your app's custom actions. When the user responds to a notification, the system calls this method with the results. You use this method to perform the task associated with that action, if at all. At the end of your implementation, you must call the completionHandler block to let the system know that you are done processing the notification.
You specify your app's notification types and custom actions using UNNotificationCategory and UNNotificationAction objects.
You create these objects at initialization time and register them with the user notification center. Even if you register custom actions, the action in the response parameter might indicate that the user dismissed the notification without performing any of your actions.
If you do not implement this method, your app never responds to custom actions.
see https://developer.apple.com/reference/usernotifications/unusernotificationcenterdelegate/1649501-usernotificationcenter
**/
print("APPDELEGATE: didReceiveResponseWithCompletionHandler \(response.notification.request.content.userInfo)")
// If you wish to determine whether a notification originated from CleverTap, you must manually call the SDK as follows:
if CleverTap.sharedInstance().isCleverTapNotification(response.notification.request.content.userInfo) {
...
}
}
Encryption of PII data
PII data is stored across the SDK and could be sensitive information. From CleverTap iOS SDK v5.2.0 onwards, you can enable encryption for PII data such as Email, Identity, Name, and Phone.
Currently, two levels of encryption are supported, i.e., None(0) and Medium(1). The encryption level is None by default.
- None: All stored data is in plaintext
- Medium: PII data is encrypted completely
Default Instance
The only way to set the encryption level for the default instance is from theinfo.plist
. Add the CleverTapEncryptionLevel
string key to info.plist
file where value 1 means Medium and 0 means None. The encryption level will be None if any other value is provided.
Additional Instance
Different instances can have different encryption levels. To set an encryption level for an additional instance:
CleverTapInstanceConfig *ctConfig = [[CleverTapInstanceConfig alloc] initWithAccountId:@"ADDITIONAL_CLEVERTAP_ACCOUNT_ID" accountToken:@"ADDITIONAL_CLEVERTAP_ACCOUNT_TOKEN"];
[ctConfig setEncryptionLevel:CleverTapEncryptionMedium];
CleverTap *additionalCleverTapInstance = [CleverTap instanceWithConfig:ctConfig];
let ctConfig = CleverTapInstanceConfig.init(accountId: "ADDITIONAL_CLEVERTAP_ACCOUNT_ID", accountToken: "ADDITIONAL_CLEVERTAP_ACCOUNT_TOKEN")
ctConfig.encryptionLevel = CleverTapEncryptionLevel.medium
let cleverTapAdditionalInstance = CleverTap.instance(with: ctConfig)
SwiftUI Support
Integration
CleverTap iOS SDK can be integrated into the SwiftUI sample app. SwiftUI provides a way to use AppDelegate within the SwiftUI life cycle by using @UIApplicationDelegateAdaptor
. Create a file, e.g.,AppDelegate.swift
then create a class of AppDelegate and attach it with the main entry point struct by using the @UIApplicationDelegateAdaptor
property wrapper. For more information, refer to sample app.
import UserNotifications
import CleverTapSDK
class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
registerForPush()
CleverTap.setDebugLevel(2)
CleverTap.autoIntegrate()
CleverTap.sharedInstance()?.enableDeviceNetworkInfoReporting(true)
return true
}
func registerForPush() {
// Register for Push notifications
UNUserNotificationCenter.current().delegate = self
// request Permissions
UNUserNotificationCenter.current().requestAuthorization(options: [.sound, .badge, .alert], completionHandler: {granted, error in
if granted {
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
})
}
}
Refer to the AppDelegate in your entry point struct like so:
import SwiftUI
@main
struct SwiftUIStarterApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
App Inbox in SwiftUI
App Inbox controller can be added using UIViewControllerRepresentable
and its callback methods can be used using makeCoordinator
method. For more information, refer to sample app.
struct CTAppInboxRepresentable: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> CleverTapInboxViewController {
let style = CleverTapInboxStyleConfig()
let inboxVC: CleverTapInboxViewController = (CleverTap.sharedInstance()?.newInboxViewController(with: style, andDelegate: context.coordinator))!
return inboxVC
}
func updateUIViewController(_ uiViewController: CleverTapInboxViewController, context: Context) {
// Updates the state of the specified view controller with new information from SwiftUI.
}
func makeCoordinator() -> CTCallbackCoordinator {
// Callback class
}
}
Track Screen Views in SwiftUI
There is no direct replacement for viewDidLoad()
method in SwiftUI, but we can achieve the same behavior using onAppear
modifier. For more information, refer to sample app.
#if canImport(SwiftUI)
import SwiftUI
import CleverTapSDK
@available(iOS 13, *)
internal struct CTViewModifier: ViewModifier {
@State private var viewDidLoad = false
let screenName: String
func body(content: Content) -> some View {
content.onAppear {
if viewDidLoad == false {
// `viewDidLoad` eqivalent in SwiftUI
viewDidLoad = true
// Record any CleverTap events here.
CleverTap.sharedInstance()?.recordEvent(screenName)
}
}
}
}
@available(iOS 13, *)
public extension View {
func recordScreenView(screenName: String) -> some View {
self.modifier(CTViewModifier(screenName: screenName))
}
}
#endif
Updated 10 months ago