> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hakumedia.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# iOS

> Integración del SDK de Haku en una app iOS.

| Requisito | Versión         |
| --------- | --------------- |
| iOS       | 15.0 o superior |
| Swift     | 5.9 o superior  |
| Xcode     | 15.0 o superior |

El SDK no tiene dependencias de terceros.

## Instalación

Se instala con Swift Package Manager o CocoaPods. El acceso al paquete se entrega al
comenzar la integración.

## Configuración

Una vez, al iniciar la app:

```swift theme={"dark"}
import HakuSDK

Haku.configure(accountId: 182804)

// Con opciones
Haku.configure(accountId: 182804, options: HakuOptions(
    testMode: false,
    logLevel: .debug   // .none, .error, .warning, .info, .debug
))
```

## Banner

<CodeGroup>
  ```swift SwiftUI theme={"dark"}
  import HakuSDK

  struct ContentView: View {
      var body: some View {
          HakuBanner(request: AdRequest(zoneId: 12345)) { event in
              switch event {
              case .loaded(let response):
                  print("Cargado: \(response.width)x\(response.height)")
              case .failed(let error):
                  print("Error: \(error.localizedDescription)")
              case .impression:
                  print("Impresión visible")
              case .click:
                  print("Clic")
              }
          }
          .frame(height: 250)
      }
  }
  ```

  ```swift UIKit theme={"dark"}
  import HakuSDK

  class ViewController: UIViewController, HakuBannerViewDelegate {
      private let bannerView = HakuBannerView()

      override func viewDidLoad() {
          super.viewDidLoad()
          bannerView.delegate = self
          bannerView.translatesAutoresizingMaskIntoConstraints = false
          view.addSubview(bannerView)

          NSLayoutConstraint.activate([
              bannerView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
              bannerView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
              bannerView.widthAnchor.constraint(equalToConstant: 300),
              bannerView.heightAnchor.constraint(equalToConstant: 250),
          ])

          bannerView.load(request: AdRequest(zoneId: 12345))
      }

      func bannerView(_ bannerView: HakuBannerView, didLoad response: AdResponse) {}
      func bannerView(_ bannerView: HakuBannerView, didFailWith error: HakuError) {}
      func bannerViewDidRecordImpression(_ bannerView: HakuBannerView) {}
      func bannerViewDidRecordClick(_ bannerView: HakuBannerView) {}
  }
  ```
</CodeGroup>

El banner se renueva solo según el tiempo configurado en la zona. Para detenerlo:

```swift theme={"dark"}
bannerView.stopAutoRefresh()
```

## Interstitial

Se carga por adelantado y se muestra cuando la app lo decide.

```swift theme={"dark"}
interstitialAd = try await HakuInterstitialAd.load(
    request: AdRequest(zoneId: 67890)
)

if let ad = interstitialAd, ad.isReady {
    ad.present(from: self)
}
```

## Nativo

```swift theme={"dark"}
let nativeAd = try await HakuNativeAd.load(
    request: AdRequest(zoneId: 11111)
)
nativeAd.onImpression = { print("Impresión") }
nativeAd.onClick = { print("Clic") }
nativeAd.present(in: adContainer)
```

## Opciones del pedido

```swift theme={"dark"}
let request = AdRequest(zoneId: 12345)
    .keywords(["deportes", "running"])
    .size(width: 300, height: 250)
    .dataKeyTargeting(["categoria": "electro", "tipo_pagina": "producto"])
    .referrer("https://miapp.com/articulo/123")
    .uniqueDelivery(pageId: 1, place: 0)
```

## Errores

```swift theme={"dark"}
do {
    let ad = try await HakuInterstitialAd.load(request: AdRequest(zoneId: 123))
} catch HakuError.notConfigured {
    // Falta llamar a Haku.configure
} catch HakuError.noAdAvailable {
    // No hay anuncio para esta zona
} catch HakuError.networkError(let underlying) {
    // Problema de red
} catch HakuError.serverError(let code, let body) {
    // Error del servidor
}
```
