> For the complete documentation index, see [llms.txt](https://docs.hackle.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hackle.io/en/development-guide/ios/user-identifier/ios-user-info-crm.md).

# CRM Properties

CRM Properties are stored securely only on the Hackle server and cannot be directly queried through the SDK.

{% hint style="danger" %}
CRM Properties are managed separately and are not deleted or reset when `resetUser()` is called or when `clearAll` is called in `updateUserProperties`.

If a user unregisters or similar actions occur, you must separately call the provided function to delete the information.
{% endhint %}

## Phone Number Collection

{% hint style="info" %}
This feature is supported in iOS SDK 2.46.0 and above.
{% endhint %}

{% hint style="success" %}
Recommendation for Kakao / Text Messages

By mapping the User Identifier to a phone number using this feature, you can use Kakao / Text Messages via Hackle more smoothly.
{% endhint %}

#### setPhoneNumber

Registers the user's phone number.

The phone number is only saved if it is in the correct E.164 format. If no country code is specified, South Korea (+82) is used as the default.

If the user already has a saved phone number, calling this function replaces the existing phone number with the new value.

{% tabs %}
{% tab title="Swift" %}

```swift
let myPhoneNumber = '+821012341234';
hackleApp.setPhoneNumber(phoneNumber: myPhoneNumber);
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec
NSString *myPhoneNumber = @"+821012341234";
[hackleApp setPhoneNumberWithPhoneNumber:myPhoneNumber];
```

{% endtab %}
{% endtabs %}

#### unsetPhoneNumber

Deletes the phone number registered for the user.

{% tabs %}
{% tab title="Swift" %}

```swift
hackleApp.unsetPhoneNumber();
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec
[hackleApp unsetPhoneNumber];
```

{% endtab %}
{% endtabs %}

## CRM Marketing Subscription Consent

{% hint style="info" %}
This feature is supported in iOS SDK 2.50.0 and above.

For details on subscription consent status, refer to the [CRM Marketing Subscription Consent Management](/en/development-guide/sdk/user-identifier/crm-subscription.md) documentation.
{% endhint %}

### Subscription Consent Properties

You can consent to or reject subscriptions by message purpose.

Use `HackleSubscriptionOperationsBuilder` to configure the consent status for the desired properties, then finalize the update using a method like `updatePushSubscriptions()`.

You can update the consent status per message channel.

{% tabs %}
{% tab title="Swift" %}

```swift
import Hackle

let subscriptions = HackleSubscriptionOperationsBuilder()
    .marketing(.subscribed)
    .information(.subscribed)
    .build()

hackle.app.updatePushSubscriptions(subscriptions)
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec
HackleSubscriptionOperationsBuilder *builder = [[HackleSubscriptionOperationsBuilder alloc] init];
[builder marketing:HackleSubscriptionStatusSubscribed];
[builder information:HackleSubscriptionStatusSubscribed];
HackleSubscriptionOperations *subscriptions = [builder build];

[[Hackle app] updatePushSubscriptions:subscriptions];
```

{% endtab %}
{% endtabs %}

#### Promotional Messages

Sets the promotional message subscription consent property.

{% tabs %}
{% tab title="Swift" %}

```swift
import Hackle

let subscriptions = HackleSubscriptionOperationsBuilder()
    .marketing(.subscribed)
    .build()

hackle.app.updatePushSubscriptions(subscriptions)
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec
HackleSubscriptionOperationsBuilder *builder = [[HackleSubscriptionOperationsBuilder alloc] init];
[builder marketing:HackleSubscriptionStatusSubscribed];
HackleSubscriptionOperations *subscriptions = [builder build];

[[Hackle app] updatePushSubscriptions:subscriptions];
```

{% endtab %}
{% endtabs %}

#### Informational Messages

Sets the informational message subscription consent property.

{% tabs %}
{% tab title="Swift" %}

```swift
import Hackle

let subscriptions = HackleSubscriptionOperationsBuilder()
    .information(.subscribed)
    .build()

hackle.app.updatePushSubscriptions(subscriptions)
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec
HackleSubscriptionOperationsBuilder *builder = [[HackleSubscriptionOperationsBuilder alloc] init];
[builder information:HackleSubscriptionStatusSubscribed];
HackleSubscriptionOperations *subscriptions = [builder build];

[[Hackle app] updatePushSubscriptions:subscriptions];
```

{% endtab %}
{% endtabs %}

<table><thead><tr><th width="224.09765625">HackleSubscriptionStatus</th><th>Description</th></tr></thead><tbody><tr><td><code>UNKNOWN</code></td><td>Subscription Consent has not been given or denied (<code>default</code>)</td></tr><tr><td><code>SUBSCRIPTION</code></td><td>Explicitly opted in to receive messages</td></tr><tr><td><code>UNSUBSCRIPTION</code></td><td>Explicitly opted out of receiving messages</td></tr></tbody></table>

### Update Push Subscription Consent Status

Updates the user's Push Message subscription consent status.

{% tabs %}
{% tab title="Swift" %}

```swift
let subscriptions = HackleSubscriptionOperationsBuilder()
    .marketing(.subscribed)
    .information(.subscribed)
    .build()

hackle.app.updatePushSubscriptions(subscriptions)
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec
HackleSubscriptionOperationsBuilder *builder = [[HackleSubscriptionOperationsBuilder alloc] init];
[builder marketing:HackleSubscriptionStatusSubscribed];
[builder information:HackleSubscriptionStatusSubscribed];
HackleSubscriptionOperations *subscriptions = [builder build];

[[Hackle app] updatePushSubscriptions:subscriptions];
```

{% endtab %}
{% endtabs %}

### Update Kakao Message Subscription Consent Status

Updates the user's Kakao Message subscription consent status.

{% tabs %}
{% tab title="Swift" %}

```swift
let subscriptions = HackleSubscriptionOperationsBuilder()
    .marketing(.subscribed)
    .information(.subscribed)
    .build()

hackle.app.updateKakaoSubscriptions(subscriptions)
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec
HackleSubscriptionOperationsBuilder *builder = [[HackleSubscriptionOperationsBuilder alloc] init];
[builder marketing:HackleSubscriptionStatusSubscribed];
[builder information:HackleSubscriptionStatusSubscribed];
HackleSubscriptionOperations *subscriptions = [builder build];

[[Hackle app] updateKakaoSubscriptions:subscriptions];
```

{% endtab %}
{% endtabs %}

### Update Text Message Subscription Consent Status

Updates the user's Text Message subscription consent status.

{% tabs %}
{% tab title="Swift" %}

```swift
let subscriptions = HackleSubscriptionOperationsBuilder()
    .marketing(.subscribed)
    .information(.subscribed)
    .build()

hackle.app.updateSmsSubscriptions(subscriptions)
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec
HackleSubscriptionOperationsBuilder *builder = [[HackleSubscriptionOperationsBuilder alloc] init];
[builder marketing:HackleSubscriptionStatusSubscribed];
[builder information:HackleSubscriptionStatusSubscribed];
HackleSubscriptionOperations *subscriptions = [builder build];

[[Hackle app] updateSmsSubscriptions:subscriptions];
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.hackle.io/en/development-guide/ios/user-identifier/ios-user-info-crm.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
