# Troubleshooting

> Turn on the SDK log, then check the common causes when a device does not register or a push does not arrive.

URL: https://docs.xulo.io/ios/troubleshooting
iOS SDK version: 0.1.4

## Turn on the log

```swift
Xulo.logLevel = .verbose
```

The trace prints in the Xcode console. A failed API call prints its action and HTTP status, for example `register failed (401)`. The log never includes the device token. Turn it off again for a live build.

## The device does not register

- **The App ID is empty.** `start` logs `start needs an app id` and does not register.
- **`register failed (401)`.** The App ID is not a registered app. Copy it again from **Settings → Keys & IDs**.
- **`register failed (404)`.** The App ID is right, but the bundle id does not match the one in the dashboard. Correct the bundle id in the dashboard, or pass `bundleId:` to `Xulo.start`.

## Nothing arrives on the simulator

The simulator can call the API. It does not receive remote notifications. Use a physical iPhone.

## Nothing arrives on a build from Xcode

Apple has two push gates: sandbox for builds signed with a development profile, and production for TestFlight and App Store builds. Each install tells Xulo which gate its token belongs to, and Xulo sends to that gate. See [APNs setup](https://docs.xulo.io/ios/apns-setup#sandbox-and-production).

- **The SDK is older than 0.1.4.** Older versions do not report the gate, so the install is sent through production. Apple refuses a token from an Xcode build there, and Xulo marks the install as not subscribed. Update the package. The next registration reports the gate and the subscription again.
- **Check the gate in the log.** With `Xulo.logLevel = .verbose`, each registration prints `push environment sandbox` or `push environment production`. A build run from Xcode with a development profile should print `sandbox`.
- **The install was imported from a CSV or another provider.** An import sets the install to production. The next registration from the SDK sets the gate again.

## A push is not sent

When you press **Send**, the dashboard shows why a push did not leave, and it stays a draft:

- "Still a draft. Apple credentials are missing, so this was not sent." Add a key in **Settings → Platforms**. See [APNs setup](https://docs.xulo.io/ios/apns-setup).
- "Still a draft. Apple accepted none of these devices." Apple refused every token in the audience.

A send to test devices from the composer shows the same reasons, without "Still a draft", and does not save a draft.

## The push has no image

- Both extensions are added, with `XuloExtension`, and the service subclass is its principal class. See [Rich push](https://docs.xulo.io/ios/rich-push).
- The app and both extensions share one App Group, and `XuloAppGroup` is set to it on all three.
- The image address is https.

If the image download fails or runs out of time, the text still arrives. That is expected.

## The long-press view does not show

Set `UNNotificationExtensionCategory` to `xulo` on the content extension.

## An extension does not build

Add `XuloExtension` to the extensions, not `Xulo`.

## A tap does not open the right screen

Check that `Xulo.onOpen` is set before the tap and returns `true` when your app opens the link. If your app has its own notification delegate, it must call `Xulo.didReceive(userInfo:)`. See [Deep links](https://docs.xulo.io/ios/deep-links).

## Crash reports

The SDK reports crashes in its own code, and its own failures such as a refused token, so that they can be fixed. A report does not include the notification text, the push token or a user id. To turn reporting off:

```swift
Xulo.crashesEnabled = false
```
