{"id":34499678,"url":"https://github.com/jointag/jtproximitysdk-ios","last_synced_at":"2025-12-24T02:00:11.357Z","repository":{"id":47130298,"uuid":"104330200","full_name":"jointag/JTProximitySDK-iOS","owner":"jointag","description":"Jointag Proximity SDK for iOS. Library with example and CocoaPods spec.","archived":false,"fork":false,"pushed_at":"2025-12-03T10:19:24.000Z","size":77784,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-12-06T13:19:46.760Z","etag":null,"topics":["cocoapods","idfa","ios-library","library","objective-c","proximity","proximity-advertising","sdk"],"latest_commit_sha":null,"homepage":"https://www.jointag.com","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jointag.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-09-21T09:46:31.000Z","updated_at":"2025-12-03T10:19:14.000Z","dependencies_parsed_at":"2022-08-20T21:20:24.531Z","dependency_job_id":null,"html_url":"https://github.com/jointag/JTProximitySDK-iOS","commit_stats":null,"previous_names":[],"tags_count":37,"template":false,"template_full_name":null,"purl":"pkg:github/jointag/JTProximitySDK-iOS","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jointag%2FJTProximitySDK-iOS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jointag%2FJTProximitySDK-iOS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jointag%2FJTProximitySDK-iOS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jointag%2FJTProximitySDK-iOS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jointag","download_url":"https://codeload.github.com/jointag/JTProximitySDK-iOS/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jointag%2FJTProximitySDK-iOS/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27992995,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-23T02:00:07.087Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cocoapods","idfa","ios-library","library","objective-c","proximity","proximity-advertising","sdk"],"created_at":"2025-12-24T02:00:05.825Z","updated_at":"2025-12-24T02:00:11.328Z","avatar_url":"https://github.com/jointag.png","language":"Objective-C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Jointag Proximity SDK Documentation\n\n## Table of Contents\n\n1. [📋 Overview](#user-content--overview)\n2. [📦 Installation](#user-content--installation)\n    1. [Installation using CocoaPods](#user-content-installation-using-cocoapods)\n    2. [Manual Installation](#user-content-manual-installation)\n3. [🔐 Permissions and Settings](#user-content--permissions-and-settings)\n    1. [User Tracking Permission](#user-content-user-tracking-permission)\n    2. [Notifications Permission](#user-content-notifications-permission)\n    3. [Location Permission](#user-content-location-permission)\n4. [🚀 Setup](#user-content--setup)\n    1. [Initializing the SDK](#user-content-initializing-the-sdk)\n    2. [iOS 13 Scenes](#user-content-ios-13-scenes)\n    3. [Handling Notifications](#user-content-handling-notifications)\n5. [🔧 Advanced Configurations](#user-content--advanced-configurations)\n    1. [Tracking User Identifiers](#user-content-tracking-user-identifiers)\n    2. [Data Tags](#user-content-data-tags)\n    3. [Programmatically Disable Advertising](#user-content-programmatically-disable-advertising)\n    4. [Receive custom events](#user-content-receive-custom-events)\n    5. [Notification Content Extensions](#user-content-notification-content-extensions)\n6. [👤 User Consent and GDPR](#user-content--user-consent-and-gdpr)\n    1. [Using a Consent Management Platform (CMP)](#user-content-using-a-consent-management-platform-cmp)\n    2. [Manual Consent Management](#user-content-manual-consent-management)\n\n---\n\n## 📋 Overview\n\nThe Jointag Proximity SDK enables iOS applications to leverage advanced\nproximity marketing capabilities with minimal integration effort.\n\nOnce integrated, the SDK operates mostly in a “start and forget” fashion: after\ninitialization and permission requests, it autonomously manages its lifecycle,\ncollecting movement and location data, and delivering targeted notifications to\nthe user.\n\nWhat the SDK does:\n\n- **User behavior analysis**:\n  \n  Tracks user movements using geofences and\nBluetooth beacons, allowing advanced segmentation and insights.\n- **Proximity marketing delivery**:\n\n  Displays location-aware notifications to the user, enabling personalized campaigns based on physical context.\n\nWhat the developer needs to do:\n\n- Add the SDK to the project (via CocoaPods or manual installation).\n- Initialize the SDK with the provided API key and secret.\n- Request the necessary user permissions (tracking, location, notifications).\n\nEverything else—such as monitoring, proximity event detection, and notification\ndelivery—is handled automatically by the SDK.\n\n```mermaid\nflowchart TD\n\nA[App Launch] --\u003e B[\"Initialize SDK \u003cbr\u003e with API Key \u0026 Secret\"]\nB --\u003e C[\"Request Permissions \u003cbr\u003e(Tracking, Location, Notifications)\"]\nC --\u003e D[\"SDK Active ✅\"]\nD --\u003e E[\"SDK Manages Proximity Events \u003cbr\u003e \u0026 Notifications Automatically\"]\nE --\u003e F[\"Optional: App uses \u003cbr\u003e ExternalUserId / Tags / Consent\"]\n```\n\n---\n\n## 📦 Installation\n\nThe Jointag Proximity SDK is available as a compiled **xcframework** that can be\nintegrated into your project either via [CocoaPods](https://cocoapods.org) or\nmanually.\n\n### Installation using CocoaPods\n\nTo install the Jointag Proximity SDK using CocoaPods, follow these steps:\n\n1.  Install or update `CocoaPods` to version **1.9.0 or later**, which is\n    essential for proper support of the new *xcframework* format.\n2.  In your terminal execute `pod init` from your project directory, if the\n    project is not already pod-enabled\n3.  Edit your project Podfile and add `pod 'JTProximitySDK'` to your main\n    application target\n4.  In your terminal execute `pod install` from your project directory.\n\neg:\n\n```ruby\ntarget 'MyApp' do\n  use_frameworks!\n  pod 'JTProximitySDK'\nend\n```\n\nMore on [CocoaPods here](https://cocoapods.org/).\n\n---\n\n### Manual Installation\n\nJointag Proximity SDK is distribute as a compiled **xcframework** with binaries\nfor both device and simulator. To add it to your project, include the\n*JTProximitySDK.xcframework* as follow:\n\n1. Drag and drop the JTProximitySDK.xcframework framework folder into your Xcode\nproject (remember to check *\"Copy items if needed\"*).\n\n2. Make sure the JTProximitySDK.xcframework appears in the **Frameworks,\nLibraries, and Embedded Content** section of the **General** tab of your project\nand that the *embed* mode is **Embed \u0026 Sign**\n\n---\n\n## 🔐 Permissions and Settings\n\nThe following section describes the permissions required by the SDK, along with\nthe necessary keys that must be added to the application Info.plist file.\n\n\u003e ⚠️ **Attention** : Starting with SDK version **1.12.0**, all the required\n\u003e permissions are no longer automatically requested when starting the SDK, but\n\u003e must be requested from the user by the application itself. To simplify this\n\u003e process, the SDK exposes helper methods to request them (such methods are\n\u003e presented below).\n\n---\n\n### User Tracking Permission\n\nAs described [here](user-tracking-usage-description), user tracking\npermission requires the following key to be added to the application\n**Info.plist** file:\n\n```xml\n\u003ckey\u003eNSUserTrackingUsageDescription\u003c/key\u003e\n\u003cstring\u003eUser Tracking Usage Description\u003c/string\u003e\n```\n\nA helper method is provided to easily request tracking authorization:\n\n**Swift**\n\n```swift\nProximity.shared.requestTrackingAuthorization()\n```\n\n**Objective-C**\n\n```objc\n[JTProximitySDK.sharedInstance requestTrackingAuthorization];\n```\n\n---\n\n### Notifications Permission\n\nA helper method is provided to easily request notification authorization:\n\n**Swift**\n\n```swift\nProximity.shared.requestNotificationAuthorization()\n```\n\n**Objective-C**\n\n```objc\n[JTProximitySDK.sharedInstance requestNotificationAuthorization];\n```\n\n---\n\n### Location Permission\n\nAs described [here](location-usage-description), user location permission\nrequires the following keys to be added to the application **Info.plist**\nfile:\n\n```xml\n\u003ckey\u003eNSLocationAlwaysAndWhenInUseUsageDescription\u003c/key\u003e\n\u003cstring\u003eLocation usage description\u003c/string\u003e\n\u003ckey\u003eNSLocationWhenInUseUsageDescription\u003c/key\u003e\n\u003cstring\u003eLocation usage description\u003c/string\u003e\n```\n\nA helper method is provided to easily request location authorization:\n\n**Objective-C**\n\n```objc\n[JTProximitySDK.sharedInstance requestLocationAuthorization];\n```\n\n**Swift**\n\n```swift\nProximity.shared.requestLocationAuthorization()\n```\n\n---\n\n## 🚀 Setup\n\n### Initializing the SDK\n\nPlace the following code inside the `UIApplicationDelegate` of your application:\n\n**Objective-C**\n\n```objc\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n    [JTProximitySDK.sharedInstance initWithLaunchOptions:launchOptions apiKey:@\"YOUR_API_KEY\" apiSecret:@\"YOUR_API_SECRET\"];\n    // Other application logics\n}\n```\n\n**Swift**\n\n```swift\nfunc application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -\u003e Bool {\n    ProximitySDK.shared.initWithLaunchOptions(launchOptions, apiKey: \"YOUR_API_KEY\", apiSecret: \"YOUR_API_SECRET\")\n    // Other application logics\n    return true\n}\n```\n\n\u003e ℹ️ **Class naming note**: The SDK exposes its main singleton instance with two\n\u003e different names depending on the language:\n\u003e\n\u003e - **Swift** → `Proximity.shared` (shortened naming to avoid conflicts with the\n\u003e framework name)\n\u003e - **Objective-C** → `JTProximitySDK.sharedInstance`\n\u003e\n\u003e Both variants provide the same APIs and lifecycle. Please make sure to use the\n\u003e correct one depending on your project’s language.\n\n---\n\n### iOS 13 Scenes\n\nIf your application make use of iOS 13 scenes, an additional requirement is to\nupdate the SDK windowSceneDelegate reference with the current active\nUIWindowSceneDelegate.\n\nTo do this you must add the following code to your current UIWindowSceneDelegate\n`scene:willConnectToSession:options:` :\n\n**Swift**\n\n```swift\nimport UIKit\nimport JTProximitySDK\n\nclass SceneDelegate: UIResponder, UIWindowSceneDelegate {\n\n    var window: UIWindow?\n\n    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {\n        ProximitySDK.shared.windowSceneDelegate = self\n        guard let _ = (scene as? UIWindowScene) else { return }\n    }\n}\n```\n\n---\n\n### Handling Notifications\n\nTo enable the SDK to correctly send and manager advertising notifications, you\nmust implement the following method in your `UNUserNotificationCenterDelegate`:\n\n**Objective-C**\n\n```objc\n- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler __IOS_AVAILABLE(10.0) {\n    if ([JTProximitySDK.sharedInstance userNotificationCenter:center willPresentNotification:notification]) {\n        completionHandler(UNNotificationPresentationOptionAlert|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound);\n        return;\n    }\n    // Other application logics\n}\n\n- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler __IOS_AVAILABLE(10.0) {\n    if ([JTProximitySDK.sharedInstance userNotificationCenter:center didReceiveNotificationResponse:response]) {\n        completionHandler();\n        return;\n    }\n    // Other application logics\n}\n```\n\n**Swift**\n\n```swift\n@available(iOS 10.0, *)\nfunc userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -\u003e Void) {\n    if ProximitySDK.shared.userNotificationCenter(center, willPresent: notification) {\n        completionHandler([.alert, .badge, .sound])\n        return\n    }\n    // Other application logics\n}\n\n@available(iOS 10.0, *)\nfunc userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -\u003e Void) {\n    if ProximitySDK.shared.userNotificationCenter(center, didReceive: response) {\n        completionHandler()\n        return\n    }\n    // Other application logics\n}\n```\n\n\u003e ⚠️ **Attention**: Many third-party push notification libraries adopt the practice\n\u003e of replacing the default `UNUserNotificationCenterDelegate` entirely, or to\n\u003e _swizzle_ the methods of the current delegate. In this case you will notice\n\u003e that the normal delegate methods are not called, and the **Jointag Proximity\n\u003e SDK** will not display or open proximity notifications.\n\u003e\n\u003e Usually the libraries that have this kind of implementation offers alternative\n\u003e methods to receive the required events.\n\u003e\n\u003e If this is your case, **please read carefully the third-party library\n\u003e documentation** to know how to implement the above methods via their library.\n\n---\n\n## 🔧 Advanced Configurations\n\n### Tracking User Identifiers\n\n#### Advertising ID and Installation ID\n\nThe SDK associates each tracked request with the *advertisingId*. If the\n*advertisingId* is not available due to a user permission denial, the device can\nbe identified by the *installationId*. The *installationId* is a randomly\ngenerated UUID created during the first initialization that hence identifies a\nspecific installation of the SDK for that application. If the app containing the\nSDK is uninstalled and then installed again the *installationId* will be a\ndifferent one. You can retrieve the *installationId* after the initialization of\nthe SDK anywhere in your code with the following line:\n\n**Objective-C**\n\n```objc\nJTProximitySDK.sharedInstance.installationId;\n```\n\n**Swift**\n\n```swift\nProximitySDK.shared.installationId()\n```\n\n#### External User ID\n\n\nThe `externalUserId` is an identifier you set to pair a unique user identifier\nof your choice with our` installationId`. Typically this identifier must be set\nafter a user has signed in to your application, and must be removed after the\nsame user decides to sign out of your application.\n\nYou can choose any string of 255 characters or less as externalUserId.\n\nYour **externalUserId** can be paired with multiple **installationId**, for\nexample if the same user uses your app on multiple devices, or if the same user\nuninstalled and installed your app multiple times.\n\nOn the other hand, the same **installationId** can be associated with one and\nonly one **externalUserId**, usually the last one sent.\n\nFor example, you can use the user record id of your database or your CRM, or the\nhash of an email address, or a third party platform identifier.\n\nUse the `setExternalUserId` method to add your unique external user ids:\n\n**Objective-C**\n\n```objc\n// Set\n[JTProximitySDK.sharedInstance setExternalUserId: @\"SOME ID\"];\n// Unset\n[JTProximitySDK.sharedInstance setExternalUserId: nil];\n```\n\n**Swift**\n\n```swift\n// Set\nProximitySDK.shared.externalUserId = \"SOME ID\"\n// Unset\nProximitySDK.shared.externalUserId = nil\n```\n\n---\n\n### Data Tags\n\nTags are custom key-value pairs of `string`, `number`, `boolean` or `NSNull` type,\nthat can be sent to our server through the SDK methods and that allow you a more\neffective campaigns targeting, or to receive personalized analysis based on the\ncharacteristics of your users.\n\nTags can be set or unset (with a `nil` value) using the following methods:\n\n#### sendTag\n\nThe `sendTag` method allow to set or unset a single tag at a time.\n\nThe method can be called multiple times. When sending different keys, its\neffects are cumulative. If the same key is used, the last value overwrites the\nprevious ones.\n\n**Objective-C**\n\n```objc\n[JTProximitySDK.sharedInstance sendTag: @\"value\" forKey: \"key1\"];\n// -\u003e { \"key1\" : \"value\" }\n[JTProximitySDK.sharedInstance sendTag:@1 forKey:@\"key2\"];\n// -\u003e { \"key1\" : \"value\", \"key2\" : 1 }\n[JTProximitySDK.sharedInstance sendTag:@YES forKey:@\"key3\"];\n// -\u003e { \"key1\" : \"value\", \"key2\" : 1, \"key3\" : true }\n[JTProximitySDK.sharedInstance sendTag:@NO forKey:@\"key3\"];\n// -\u003e { \"key1\" : \"value\", \"key2\" : 1, \"key3\" : false }\n[JTProximitySDK.sharedInstance sendTag:nil forKey:@\"key2\"];\n// -\u003e { \"key1\" : \"value\", \"key3\" : false }\n```\n\n**Swift**\n\n```swift\nProximitySDK.shared.sendTag(\"value\", for: \"key1\");\n// -\u003e { \"key1\" : \"value\" }\nProximitySDK.shared.sendTag(1, for: \"key2\");\n// -\u003e { \"key1\" : \"value\", \"key2\" : 1 }\nProximitySDK.shared.sendTag(true, for: \"key3\");\n// -\u003e { \"key1\" : \"value\", \"key2\" : 1, \"key3\" : true }\nProximitySDK.shared.sendTag(false, for: \"key3\");\n// -\u003e { \"key1\" : \"value\", \"key2\" : 1, \"key3\" : false }\nProximitySDK.shared.sendTag(nil, for: \"key2\");\n// -\u003e { \"key1\" : \"value\", \"key3\" : false }\n```\n\n#### sendTags\n\nThe `sendTags` method allow to set or unset a multiple tags at a time.\n\nThe method can be called multiple times. When sending different keys, its\neffects are cumulative. If the same key is used, the last value overwrites the\nprevious ones.\n\n\u003e **Note**: To send a `null` value using a Dictionary you must pass the value\n\u003e using a `NSNull` instance.\n\n**Objective-C**\n\n```objc\n[JTProximitySDK.sharedInstance sendTags:@{\n    @\"key1\" : \"value\",\n    @\"key2\" : @1,\n    @\"key3\" : @YES,\n}];\n// -\u003e { \"key1\" : \"value\", \"key2\" : 1, \"key3\" : true }\n[JTProximitySDK.sharedInstance sendTags:@{\n    @\"key2\" : [NSNull null],\n    @\"key3\" : @NO,\n}];\n// -\u003e { \"key1\" : \"value\", \"key3\" : false }\n```\n\n**Swift**\n\n```swift\nProximitySDK.shared.sendTags([\n    \"key1\" : \"value\",\n    \"key2\" : 1,\n    \"key3\" : true\n])\n// -\u003e { \"key1\" : \"value\", \"key2\" : 1, \"key3\" : true }\nProximitySDK.shared.sendTags([\n    \"key2\" : NSNull(),\n    \"key3\" : false\n])\n// -\u003e { \"key1\" : \"value\", \"key3\" : false }\n```\n\n---\n\n### Programmatically Disable Advertising\n\nIt is possible to programmatically disable/enable the advertising delivery by\nsetting the SDK's `advertisingEnabled` property to `false`. It is useful for\nexample to disable the delivery of advertising for specific users of the\napplication. In that case, simply change the property as soon as the user sign\nin or out of the application.\nThe default value for the property is `true`.\n\n**Objective-C**\n\n```objc\n// disable advertising delivery\n[JTProximitySDK.sharedInstance setAdvertisingEnabled:NO];\n// enable advertising delivery\n[JTProximitySDK.sharedInstance setAdvertisingEnabled:YES];\n```\n\n**Swift**\n\n```swift\n// disable advertising delivery\nProximitySDK.shared.advertisingEnabled = false\n// enable advertising delivery\nProximitySDK.shared.advertisingEnabled = true\n```\n\n---\n\n### Receive Custom Events\n\nYou can receive custom advertising events (if configured in the backend) to\nintegrate application-specific features by using the `customDelegate` property\nof `ProximitySDK` instance.\n\nWhen the application user interacts with a custom-action notification, the\n`jtProximityDidReceiveCustomAction:` method is invoked by passing a\n`customAction` NSString object.\n\n---\n\n### Notification Content Extensions\n\nStarting from SDK version 1.16.0, the Proximity SDK supports rich notification content through custom notification content extensions. Currently supported categories include:\n\n- **Gallery Notifications**: Display a gallery of images within the notification.\n\n#### Setting up Gallery Notifications Extension\n\nTo enable gallery notifications in your application, follow these steps:\n\n1. **Create a Notification Content Extension**\n\n    In Xcode, add a new target to your project:\n   - File → New → Target → Notification Content Extension\n   - Name it appropriately (e.g., \"MyAppGalleryNotificationExtension\")\n\n2. **Add the SDK to the Extension Target**\n\n    The notification content extension must have access to the JTProximitySDK\n    framework to use the gallery components.\n\n    **If using CocoaPods:**\n\n    Update your Podfile to include the SDK for the extension target:\n\n    ```ruby\n    target 'MyApp' do\n        use_frameworks!\n        pod 'JTProximitySDK'\n    end\n\n    target 'MyAppGalleryNotificationExtension' do\n        use_frameworks!\n        pod 'JTProximitySDK'\n    end\n    ```\n\n    Then run `pod install` in your terminal.\n\n    **If using Manual Installation:**\n\n    1. Select your project in the Xcode navigator\n    2. Select the notification extension target\n    3. Go to the **General** tab\n    4. In the **Frameworks, Libraries, and Embedded Content** section, click the \"+\" button\n    5. Add **JTProximitySDK.xcframework** and set it to **Embed \u0026 Sign**\n\n3. **Configure the Extension Info.plist**\n\n   Edit and update the `Info.plist` of your newly created notification content\n   extension with the following:\n\n   ```xml\n   \u003ckey\u003eNSExtension\u003c/key\u003e\n   \u003cdict\u003e\n       \u003ckey\u003eNSExtensionAttributes\u003c/key\u003e\n       \u003cdict\u003e\n           \u003ckey\u003eUNNotificationExtensionCategory\u003c/key\u003e\n           \u003cstring\u003ecom.jointag.notification.category.gallery\u003c/string\u003e\n           \u003ckey\u003eUNNotificationExtensionInitialContentSizeRatio\u003c/key\u003e\n           \u003creal\u003e1\u003c/real\u003e\n\t\t   \u003ckey\u003eUNNotificationExtensionUserInteractionEnabled\u003c/key\u003e\n\t\t   \u003ctrue/\u003e\n       \u003c/dict\u003e\n       \u003ckey\u003eNSExtensionPrincipalClass\u003c/key\u003e\n       \u003cstring\u003e$(PRODUCT_MODULE_NAME).NotificationViewController\u003c/string\u003e\n       \u003ckey\u003eNSExtensionPointIdentifier\u003c/key\u003e\n       \u003cstring\u003ecom.apple.usernotifications.content-extension\u003c/string\u003e\n   \u003c/dict\u003e\n   ```\n\n   **Important Details:**\n   - `UNNotificationExtensionCategory`: Must be exactly `com.jointag.notification.category.gallery`\n   - `UNNotificationExtensionInitialContentSizeRatio`: Must be set to `1.0`\n   - `UNNotificationExtensionUserInteractionEnabled`: Must be set to `true` to enable user interactions\n   - `NSExtensionPrincipalClass`: Use `$(PRODUCT_MODULE_NAME).NotificationViewController` to automatically reference your view controller class\n\n   \u003e **Note**: When Xcode creates the notification content extension, it automatically\n   generates a storyboard-based setup. Since the UI is created programmatically\n   by the SDK, you can safely delete the `MainInterface.storyboard` file from\n   the extension target.\n\n4. **Implement the Extension View Controller**\n\n   Replace the content of your extension's view controller with the following implementation:\n\n   **Swift**\n\n   ```swift\n   import UIKit\n   import JTProximitySDK\n   import UserNotifications\n   import UserNotificationsUI\n\n   class NotificationViewController: UIViewController, UNNotificationContentExtension {\n       private let galleryView = JTNotificationGalleryView()\n\n       override func viewDidLoad() {\n           super.viewDidLoad()\n           self.galleryView.translatesAutoresizingMaskIntoConstraints = false\n           self.view.addSubview(self.galleryView)\n           NSLayoutConstraint.activate([\n               self.galleryView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),\n               self.galleryView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),\n               self.galleryView.topAnchor.constraint(equalTo: self.view.topAnchor),\n               self.galleryView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)\n           ])\n       }\n\n       func didReceive(_ notification: UNNotification) {\n           self.galleryView.configure(with: notification, in: self.extensionContext)\n       }\n   }\n   ```\n\n5. **Enable Content Extension Support in the Main App**\n\n   After implementing the content extension, you must notify the SDK about the supported categories by setting the `contentExtensionCategories` property before initializing the SDK:\n\n   **Objective-C**\n\n   ```objc\n   - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n       // Enable gallery notifications support\n       [JTProximitySDK.sharedInstance setContentExtensionCategories:JTContentExtensionCategoryGallery];\n       \n       // Initialize the SDK\n       [JTProximitySDK.sharedInstance initWithLaunchOptions:launchOptions apiKey:@\"YOUR_API_KEY\" apiSecret:@\"YOUR_API_SECRET\"];\n       \n       // Other application logics\n       return YES;\n   }\n   ```\n\n   **Swift**\n\n   ```swift\n   func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -\u003e Bool {\n       // Enable gallery notifications support\n       ProximitySDK.shared.contentExtensionCategories = .gallery\n       \n       // Initialize the SDK\n       ProximitySDK.shared.initWithLaunchOptions(launchOptions, apiKey: \"YOUR_API_KEY\", apiSecret: \"YOUR_API_SECRET\")\n       \n       // Other application logics\n       return true\n   }\n   ```\n\n   You can also combine multiple extension categories using bitwise OR operations:\n\n   **Objective-C**\n\n   ```objc\n   // Enable multiple categories (when available)\n   [JTProximitySDK.sharedInstance setContentExtensionCategories:JTContentExtensionCategoryGallery | JTContentExtensionCategoryOther];\n   ```\n\n   **Swift**\n\n   ```swift\n   // Enable multiple categories (when available)\n   ProximitySDK.shared.contentExtensionCategories = [.gallery, .other]\n   ```\n\n    \u003e ⚠️ **Important**: The `contentExtensionCategories` property must be set\n    \u003e **before** calling the SDK initialization method\n    \u003e `initWithLaunchOptions:apiKey:apiSecret:` to ensure proper functionality.\n\n---\n\n## 👤 User Consent and GDPR\n\nThe SDK supports two approaches for handling user consent:\n\n1. **Automatic CMP Integration**: Use with IAB-compatible Consent Management\n   Platforms\n2. **Manual Consent Management**: Implement your own consent flow\n\n### Using a Consent Management Platform (CMP)\n\n**Enabling the Consent Flow support**\n\nIf you're using an IAB-compatible CMP:\n\n```objc\n// Enable CMP support BEFORE initialization\n[JTProximitySDK.sharedInstance setCmpEnabled:YES];\n[JTProximitySDK.sharedInstance initWithLaunchOptions:launchOptions apiKey:@\"YOUR_API_KEY\" apiSecret:@\"YOUR_API_SECRET\"];\n```\n\n**Requirements**\n\nWhen configuring a third-party CMP to use with the Jointag Proximity SDK, the\nfollowing requirements must be met:\n\n- The CMP must be IAB Europe v2.0 compatible.\n- In order to enable the delivery of advertising, a `custom publisher purpose`\n    **must be** configured in the CMP, and it **must be** the first custom\n    purpose.\n\n### Manual Consent Management\n\nIf implementing your own consent flow:\n\n**Objective-C**\n\n```objc\n// Set individual consent types\n[JTProximitySDK.sharedInstance getManualConsentForType:JTPManualConsentProfiling];\n[JTProximitySDK.sharedInstance setManualConsent:YES forType:JTPManualConsentProfiling];\n\n// Retrieve or update the manual user monitoring consent\n[JTProximitySDK.sharedInstance getManualConsentForType:JTPManualConsentMonitoring];\n[JTProximitySDK.sharedInstance setManualConsent:YES forType:JTPManualConsentMonitoring];\n\n// Retrieve or update the manual user advertising consent\n[JTProximitySDK.sharedInstance getManualConsentForType:JTPManualConsentAdvertising];\n[JTProximitySDK.sharedInstance setManualConsent:YES forType:JTPManualConsentAdvertising];\n\n// Retrieve or update the manual user advanced tracking consent\n[JTProximitySDK.sharedInstance getManualConsentForType:JTPManualConsentAdvancedTracking];\n[JTProximitySDK.sharedInstance setManualConsent:YES forType:JTPManualConsentAdvancedTracking];\n```\n\n**Swift**\n\n```swift\n// Retrieve or update the manual user profiling consent\nProximitySDK.shared.getManualConsent(for: .profiling);\nProximitySDK.shared.setManualConsent(true, for: .profiling);\n\n// Retrieve or update the manual user monitoring consent\nProximitySDK.shared.getManualConsent(for: .monitoring);\nProximitySDK.shared.setManualConsent(true, for: .monitoring);\n\n// Retrieve or update the manual user advertising consent\nProximitySDK.shared.getManualConsent(for: .advertising);\nProximitySDK.shared.setManualConsent(true, for: .advertising);\n\n// Retrieve or update the manual user advanced tracking consent\nProximitySDK.shared.getManualConsent(for: .advancedTracking);\nProximitySDK.shared.setManualConsent(true, for: .advancedTracking);\n```\n\n**Available Consent Types:**\n- `JTPManualConsentProfiling`: User profiling for targeting\n- `JTPManualConsentMonitoring`: Location and behavior monitoring\n- `JTPManualConsentAdvertising`: Advertising delivery\n- `JTPManualConsentAdvancedTracking`: Advanced analytics tracking\n\n---\n\n\u003e ⚠️ **Attention**: When the **manual consent method** is used in the presence\n\u003e of a **CMP library**, the choices made using the above methods take precedence\n\u003e over the choices made by the user in the CMP library screen.\n\n---\n\n[user-tracking-usage-description]: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription\n[location-usage-description]: https://developer.apple.com/documentation/bundleresources/information_property_list/nslocationalwaysandwheninuseusagedescription\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjointag%2Fjtproximitysdk-ios","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjointag%2Fjtproximitysdk-ios","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjointag%2Fjtproximitysdk-ios/lists"}