---
source_url: https://www.pubnub.com/docs/sdks/objective-c/status-events
title: Status Events for Objective-C SDK
updated_at: 2026-06-12T11:26:05.235Z
sdk_name: PubNub Objective-C SDK
sdk_version: 7.0.2
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Status Events for Objective-C SDK

PubNub Objective-C SDK, use the latest version: 7.0.2

Install:

```bash
pod install PubNub@7.0.2
```

There is set of error categories which is returned by PubNub client through API completion blocks or delegate callbacks. Access to a category can be done using the `status.category` property.

Delegate callbacks relate to Subscribe API usage and allow you to handle real-time updates and errors.

:::note
To handle events, your listener should conform to the `PNObjectEventListener` protocol and register as a listener using the `addListener` method on the PubNub client instance.
:::

* [PNAccessDeniedCategory](#pnaccessdeniedcategory)
* [PNTimeoutCategory](#pntimeoutcategory)
* [PNNetworkIssuesCategory](#pnnetworkissuescategory)
* [PNUnexpectedDisconnectCategory](#pnunexpecteddisconnectcategory)
* [PNBadRequestCategory](#pnbadrequestcategory)
* [PNMalformedFilterExpressionCategory](#pnmalformedfilterexpressioncategory)
* [PNMalformedResponseCategory](#pnmalformedresponsecategory)
* [PNDecryptionErrorCategory](#pndecryptionerrorcategory)
* [PNTLSConnectionFailedCategory](#pntlsconnectionfailedcategory)
* [PNTLSUntrustedCertificateCategory](#pntlsuntrustedcertificatecategory)

## PNAccessDeniedCategory

**API:** Subscribe, Publish, History, Presence, State, Stream controller, APNS.

**Description:** **PubNub** Access Manager forbidden access to particular API.

**Reason:** At the moment when API has been used, access rights hasn't been applied to the client with specified authKey yet.

**Handle strategy:** Retry API call few times using provided retry method. If `willAutomaticallyRetry` is set to **YES** there will be no need to call retry method.

It is possible, what access has been revoked and some retry counter should be used to ensure what retry process won't least forever.

:::note Automatic retry functionality
At this moment only `subscribe` API provide automatic retry functionality. Rest API calls explicitly should retry calling retry method which is provided by `PNStatus` subclass instance.
:::

### Delegate callbacks

This is the only API which in case of error access error automatically will retry subscription.

```objectivec
- (void)client:(PubNub *)client didReceiveStatus:(PNStatus *)status {

    if (status.category == PNAccessDeniedCategory) {

        // List of channels for which Access Manager reported access error.
        NSArray<NSString *> *channels = status.errorData.channels;
        // List of channel groups for which Access Manager reported access error.
        NSArray<NSString *> *groups = status.errorData.channelGroups;

        // Stop automatic retry if required.
        if (status.willAutomaticallyRetry && [self shouldStopAutoRetry]) {

            [status cancelAutomaticRetry];
        }
    }
}
```

### Completion blocks

Depending from used api, completion block may pass only `PNStatus` or both: `PNResult` and `PNStatus` subclass instances. For simplification handling code will be demonstrated only for completion block which pass only `PNStatus` subclass instance.

```objectivec
__block NSUInteger retryCount = 0;
NSUInteger maxRetry = 3;
^(PNPublishStatus *status) {

    if (status.category == PNAccessDeniedCategory) {

        if (retryCount + 1 < maxRetry) {
            retryCount ++;
            [status retry];
        }
        else {
            // Report access rights error.
        }
    }
};
```

## PNTimeoutCategory

* API: Subscribe, Publish, History, Presence, State, Stream controller, APNS.
* Description: API processing failed because of request time out.
* Reason: Slow connection when request doesn't have enough time to complete processing (send request body and receive server response).
* Handle strategy: Retry API call few times using provided retry method. If willAutomaticallyRetry is set to YES there will be no need to call retry method.

:::note
At this moment only `subscribe` API provide automatic retry functionality. Rest API calls explicitly should retry calling retry method which is provided by `PNStatus` subclass instance.
:::

### Delegate callbacks

Event listeners will receive this kind of error as `PNUnexpectedDisconnectCategory`. Last API call will be retried in case if `subscribe` API has been used.

```objectivec
- (void)client:(PubNub *)client didReceiveStatus:(PNStatus *)status {

    if (status.category == PNUnexpectedDisconnectCategory) {

        // Stop automatic retry if required.
        if (status.willAutomaticallyRetry && [self shouldStopAutoRetry]) {

            [status cancelAutomaticRetry];
        }
    }
}
```

### Completion blocks

Depending from used api, completion block may pass only `PNStatus` or both: `PNResult` and `PNStatus` subclass instances. For simplification handling code will be demonstrated only for completion block which pass only `PNStatus` subclass instance.

```objectivec
__block NSUInteger retryCount = 0;
NSUInteger maxRetry = 3;
^(PNPublishStatus *status) {

    if (status.category == PNTimeoutCategory) {

        if (retryCount + 1 < maxRetry) {
            retryCount ++;
            [status retry];
        }
        else {

            // Report potential network issues.
        }
    }
};
```

## PNNetworkIssuesCategory

* API: Subscribe, Publish, History, Presence, State, Stream controller, APNS.
* Description: API request is impossible because there is no connection.
* Reason: No active connection to the Internet.
* Handle strategy: Check for network connectivity and retry API call later when internet connection will be restored.

### Delegate callbacks

Event listeners will receive this kind of error as `PNUnexpectedDisconnectCategory`. In case of network issues **PubNub** client use periodic call to time API to check when network connection will be restored.

```objectivec
- (void)client:(PubNub *)client didReceiveStatus:(PNStatus *)status {

    if (status.category == PNUnexpectedDisconnectCategory) {

        // Report 'offline' state.
        // Wait for automatic connection completion or use any
        // reachability API to be notified about network connection
        // restoring.
        // Retry API call on network connection restore (in case of manual
        // network discovery).
    }
}
```

### Completion blocks

```objectivec
^(PNPublishStatus *status) {

    if (status.category == PNNetworkIssuesCategory) {

        // Report operation failure.
         // For automated (not by user request) any reachability API
         // should be used to be notified about network connection restore.
         // Retry API call (on user request or on network connection detection).
    }
};
```

## PNUnexpectedDisconnectCategory

* API: Subscribe.
* Description: Status sent when client unexpectedly lost ability to receive live updates from PubNub service (this status object's error flags is set to NO.
* Reason: Initial or long-poll request failed because of following reasons: timeout, malformed service response, or secure connection handshake error.
* Handle strategy: Retry API call few times using provided retry method. If willAutomaticallyRetry is set to YES there will be no need to call retry method.
* Malformed service response - SDK expects properly formatted JSON objects from the PubNub service. This may happen when you connect to a public WiFi Hotspot that requires you to auth via your web browser first, or if there is a proxy somewhere returning an HTML access denied error, or if there was an intermittent server issue.

### Delegate callbacks

Event listeners will receive this kind of error as `PNUnexpectedDisconnectCategory`. Last API call will be retried in case if `subscribe` API has been used.

```objectivec
- (void)client:(PubNub *)client didReceiveStatus:(PNStatus *)status {

    if (status.category == PNUnexpectedDisconnectCategory) {

        // Stop automatic retry if required.
        if (status.willAutomaticallyRetry && [self shouldStopAutoRetry]) {

            [status cancelAutomaticRetry];
        }
    }
}
```

## PNBadRequestCategory

* API: Subscribe, Publish, History, Presence, State, Stream controller, APNS.
* Description: Status is used to notify what API request from client is malformed.
* Reason: This type of status is possible in case if wrong data type or content has been passed to API.
* Handle strategy: Ensure what empty publish/subscribe keys not used during PubNub client instantiation. Check values passed to API and verify whether their data type and content correspond to expected values (using documentation and IDE warnings).

### Delegate callbacks

Event listeners will receive this kind of error as `PNUnexpectedDisconnectCategory`. Last API call will be retried in case if `subscribe` API has been used.

```objectivec
- (void)client:(PubNub *)client didReceiveStatus:(PNStatus *)status {

    if (status.category == PNUnexpectedDisconnectCategory) {

        // If this is initial subscription after client initialization
        // assertion will be good here to catch potential issues before
        // they will be pushed to production.
    }
}
```

### Completion blocks

```objectivec
^(PNPublishStatus *status) {

    if (status.category == PNBadRequestCategory) {

        // Assertion will be good here to catch potential issues before they
        // will be pushed to production.
    }
};
```

## PNMalformedFilterExpressionCategory

* API: Subscribe.
* Description: Status is used to notify what client has been configured with malformed filtering expression.
* Reason: In case if this status arrive, check syntax used for filterExpression property.
* Handle strategy: Please use message filtering documentation to validate used expression. Check what all used single/double quotes paired and escaped if required.

### Delegate callbacks

In case of this kind of error `subscribe` request automatic retry disabled.

```objectivec
- (void)client:(PubNub *)client didReceiveStatus:(PNStatus *)status {

    if (status.category == PNMalformedFilterExpressionCategory) {

        // Assertion will be good here to catch potential issues before they
        // will be pushed to production.
    }
}
```

## PNMalformedResponseCategory

* API: Subscribe, Publish, History, Presence, State, Stream controller, APNS.
* Description: PubNub because of some issues sent malformed response.
* Reason: This may happen when you connect to a public WiFi Hotspot that requires you to auth via your web browser first, or if there is a proxy somewhere returning an HTML access denied error, or if there was an intermittent server issue.
* Handle strategy: Retry API call few times using provided retry method. If willAutomaticallyRetry is set to YES there will be no need to call retry method.

:::note
At this moment only `subscribe` API provide automatic retry functionality. Rest API calls explicitly should retry calling retry method which is provided by `PNStatus` subclass instance.
:::

### Delegate callbacks

Event listeners will receive this kind of error as `PNUnexpectedDisconnectCategory`. Last API call will be retried in case if `subscribe` API has been used.

```objectivec
- (void)client:(PubNub *)client didReceiveStatus:(PNStatus *)status {

    if (status.category == PNUnexpectedDisconnectCategory) {

        // Stop automatic retry if required.
        if (status.willAutomaticallyRetry && [self shouldStopAutoRetry]) {

            [status cancelAutomaticRetry];
        }
    }
}
```

### Completion blocks

Depending from used api, completion block may pass only `PNStatus` or both: `PNResult` and `PNStatus` subclass instances. For simplification handling code will be demonstrated only for completion block which pass only `PNStatus` subclass instance.

```objectivec
__block NSUInteger retryCount = 0;
NSUInteger maxRetry = 3;
^(PNPublishStatus *status) {

    if (status.category == PNMalformedResponseCategory) {

        if (retryCount + 1 < maxRetry) {
            retryCount ++;
            [status retry];
        }
        else {

            // Report request processing error.
        }
    }
};
```

## PNDecryptionErrorCategory

* API: Subscribe, History.
* Description: PubNub client can't use provided cipherKey to decrypt received message.
* Reason: PubNub client configured with different cipherKey then key which has been used to encrypt message. PubNub client configured with cipherKey but unencrypted message has been received.

### Delegate callbacks

```objectivec
- (void)client:(PubNub *)client didReceiveStatus:(PNStatus *)status {

    if (status.category == PNDecryptionErrorCategory) {

        PNErrorStatus *errorStatus = (PNErrorStatus *)status;
        PNMessageData *data = (PNMessageData *)errorStatus.associatedObject;
        // Reference on channel on which message has been received.
        NSString *channel = data.channel;
        // Reference on message which SDK was unable to decrypt.
        id message = data.message;
    }
}
```

### Completion blocks

Depending from used api, completion block may pass only `PNStatus` or both: `PNResult` and `PNStatus` subclass instances. For simplification handling code will be demonstrated only for completion block which pass only `PNStatus` subclass instance.

```objectivec
[self.client historyForChannel: @"my_channel"
                withCompletion:^(PNHistoryResult *result, PNErrorStatus *status) {

    if (status.category == PNDecryptionErrorCategory) {

        PNErrorStatus *errorStatus = (PNErrorStatus *)status;
        PNHistoryData *data = (PNHistoryData *)errorStatus.associatedObject;
        // Reference on received list of messages.
        NSArray *messages = data.messages;
    }
}];
```

## PNTLSConnectionFailedCategory

* API: Subscribe, Publish, History, Presence, State, Stream controller, APNS.
* Description: Status is sent in case if client was unable to use API using secured connection.
* Reason: Secured connection handshake did fail because of: certificate issues or handshake process issues because of too slow connection or too big packets loss.
* Handle strategy: Retry API call few times using provided retry method. If willAutomaticallyRetry is set to YES there will be no need to call retry method.

:::note
At this moment only `subscribe` API provide automatic retry functionality. Rest API calls explicitly should retry calling retry method which is provided by `PNStatus` subclass instance.
:::

### Delegate callbacks

Event listeners will receive this kind of error as `PNUnexpectedDisconnectCategory`. Last API call will be retried in case if `subscribe` API has been used.

```objectivec
- (void)client:(PubNub *)client didReceiveStatus:(PNStatus *)status {

    if (status.category == PNUnexpectedDisconnectCategory) {

        // Stop automatic retry if required.
        if (status.willAutomaticallyRetry && [self shouldStopAutoRetry]) {

            [status cancelAutomaticRetry];
        }
    }
}
```

### Completion blocks

Depending from used api, completion block may pass only `PNStatus` or both: `PNResult` and `PNStatus` subclass instances. For simplification handling code will be demonstrated only for completion block which pass only `PNStatus` subclass instance.

```objectivec
__block NSUInteger retryCount = 0;
NSUInteger maxRetry = 3;
^(PNPublishStatus *status) {

    if (status.category == PNTLSConnectionFailedCategory) {

        if (retryCount + 1 < maxRetry) {
            retryCount ++;
            [status retry];
        }
        else {

            // Report request processing error.
        }
    }
};
```

## PNTLSUntrustedCertificateCategory

* API: Subscribe, Publish, History, Presence, State, Stream controller, APNS.
* Description: Status is sent in case if client unable to check certificates trust chain.
* Reason: Secured connection handshake did fail because of proxy or VPN which has been used to connect to internet.
* Handle strategy: Retry API call few times using provided retry method. If willAutomaticallyRetry is set to YES there will be no need to call retry method.

:::note
At this moment only `subscribe` API provide automatic retry functionality. Rest API calls explicitly should retry calling retry method which is provided by `PNStatus` subclass instance.
:::

### Delegate callbacks

Event listeners will receive this kind of error as `PNUnexpectedDisconnectCategory`. Last API call will be retried in case if `subscribe` API has been used.

```objectivec
- (void)client:(PubNub *)client didReceiveStatus:(PNStatus *)status {

    if (status.category == PNUnexpectedDisconnectCategory) {

        // Stop automatic retry if required.
        if (status.willAutomaticallyRetry && [self shouldStopAutoRetry]) {

            [status cancelAutomaticRetry];
        }
    }
}
```

### Completion blocks

Depending from used api, completion block may pass only `PNStatus` or both: `PNResult` and `PNStatus` subclass instances. For simplification handling code will be demonstrated only for completion block which pass only `PNStatus` subclass instance.

```objectivec
__block NSUInteger retryCount = 0;
NSUInteger maxRetry = 3;
^(PNPublishStatus *status) {

    if (status.category == PNTLSUntrustedCertificateCategory) {

        if (retryCount + 1 < maxRetry) {
            retryCount ++;
            [status retry];
        }
        else {

            // Report request processing error.
        }
    }
};
```