Skip to content

Latest commit

 

History

History
339 lines (272 loc) · 9.09 KB

File metadata and controls

339 lines (272 loc) · 9.09 KB

THN Native SDK Integration Guide

Overview

The THN Native SDK enables seamless integration of The Hotels Network widgets into your native iOS and Android applications. This SDK provides a lightweight bridge between your app and THN's web-based personalization features.

Requirements

iOS

  • iOS 15.0+
  • Xcode 14+
  • Swift 5.0+

Android

  • Android API 21+ (Android 5.0 Lollipop)
  • AndroidX compatibility

Installation

iOS Installation

Manual Installation

  1. Download the THNNativeSDK.xcframework from the latest release
  2. Drag the framework into your project
  3. Ensure it's added to the "Embed & Sign" section in your target's settings

Android Installation

Manual Installation

  1. Download the AAR file from the latest release
  2. Place it in your app's libs directory
  3. Add the following to your build.gradle:
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.aar'])
}

Quickstart

iOS Integration (UIKit)

import UIKit
import THNNativeSDK

class HotelViewController: UIViewController {
    private var widgetLoader: THNWidgetLoader!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Create and configure the widget
        let data = THNData(
            propertyId: "YOUR_PROPERTY_ID",
            pageName: .roomsAndRates,
            languageCode: "en"
        )
        
        // Create a binding for the data
        let dataBinding = Binding(
            get: { data },
            set: { _ in }
        )
        
        // Create bindings for error and visibility states
        let errorBinding = Binding<Error?>(
            get: { nil },
            set: { _ in }
        )
        
        let visibilityBinding = Binding(
            get: { true },
            set: { _ in }
        )
        
        // Create the widget
        widgetLoader = THNWidgetLoader(
            data: dataBinding,
            error: errorBinding,
            debugMode: false,
            isVisible: visibilityBinding
        )
        
        // Add it to your view
        let hostedView = UIHostingController(rootView: widgetLoader)
        addChild(hostedView)
        view.addSubview(hostedView.view)
        hostedView.view.frame = view.bounds
        hostedView.didMove(toParent: self)
    }
}

iOS Integration (SwiftUI)

import SwiftUI
import THNNativeSDK

struct HotelView: View {
    @State private var thnData = THNData(
        propertyId: "YOUR_PROPERTY_ID",
        pageName: .roomsAndRates,
        languageCode: "en",
        currencyCode: "USD"
    )
    @State private var isVisible: Bool = true
    @State private var error: Error? = nil
    
    var body: some View {
        ZStack {
            // Your content here
            
            // THN Widget
            THNWidgetLoader(
                data: $thnData,
                error: $error,
                debugMode: false,
                isVisible: $isVisible
            )
        }
    }
}

Android Integration

import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.thehotelsnetwork.thnnativesdk.THNData
import com.thehotelsnetwork.thnnativesdk.THNPageName
import com.thehotelsnetwork.thnnativesdk.THNWidgetLoader

class HotelActivity : AppCompatActivity() {
    private lateinit var widgetLoader: THNWidgetLoader
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_hotel)
        
        widgetLoader = findViewById(R.id.thn_widget)
        
        // Create the data for the widget
        val thnData = THNData(
            propertyId = "YOUR_PROPERTY_ID",
            pageName = THNPageName.ROOMS_AND_RATES,
            languageCode = "en",
            currencyCode = "USD"
        )
        
        // Configure the widget
        widgetLoader.configure(
            data = thnData,
            debugMode = false,
            isVisible = { isVisible ->
                // Handle visibility changes
            }
        )
    }
}

Layout XML:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <!-- Your other views here -->
    
    <com.thehotelsnetwork.thnnativesdk.THNWidgetLoader
        android:id="@+id/thn_widget"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
        
</androidx.constraintlayout.widget.ConstraintLayout>

Advanced Usage

Working with Data Models

The THN SDK uses several data models to structure information:

THNData

The main container for all widget data:

// Swift
THNData(
    propertyId: String,               // Your THN property ID
    pageName: THNPageName,            // Current page type
    languageCode: String? = nil,      // Optional language code (e.g., "en")
    currencyCode: String? = nil,      // Optional currency code (e.g., "USD")
    bookingId: String? = nil,         // Optional booking identifier
    search: THNSearch? = nil,         // Optional search parameters
    results: THNResults? = nil        // Optional search results
)
// Kotlin
THNData(
    propertyId: String,               // Your THN property ID
    pageName: THNPageName,            // Current page type
    languageCode: String? = null,     // Optional language code (e.g., "en")
    currencyCode: String? = null,     // Optional currency code (e.g., "USD")
    bookingId: String? = null,        // Optional booking identifier
    search: THNSearch? = null,        // Optional search parameters
    results: THNResults? = null       // Optional search results
)

THNPageName

Enum that identifies the current page type:

// Swift
enum THNPageName {
    case index                  // Homepage
    case search                 // Search page
    case roomsAndRates          // Rooms and rates page
    case booking                // Booking page
    case bookingConfirmed       // Booking confirmation page
}
// Kotlin
enum class THNPageName {
    INDEX,                      // Homepage
    SEARCH,                     // Search page
    ROOMS_AND_RATES,            // Rooms and rates page
    BOOKING,                    // Booking page
    BOOKING_CONFIRMED           // Booking confirmation page
}

THNSearch

Search parameters for hotel rooms:

// Swift
THNSearch(
    checkIn: String,                   // Check-in date (format: "YYYY-MM-DD")
    checkOut: String,                  // Check-out date (format: "YYYY-MM-DD")
    promoCode: String? = nil,          // Optional promotion code
    adults: Int? = nil,                // Optional number of adults
    children: Int? = nil,              // Optional number of children
    rooms: [THNRoom] = []              // List of room configurations
)
// Kotlin
THNSearch(
    checkIn: String,                   // Check-in date (format: "YYYY-MM-DD")
    checkOut: String,                  // Check-out date (format: "YYYY-MM-DD")
    promoCode: String? = null,         // Optional promotion code
    adults: Int? = null,               // Optional number of adults
    children: Int? = null,             // Optional number of children
    rooms: List<THNRoom> = emptyList() // List of room configurations
)

Debugging

Enable debug mode to help with integration issues:

// Swift
THNWidgetLoader(
    data: $thnData,
    error: $error,
    debugMode: true,   // Enable debug mode
    isVisible: $isVisible
)
// Kotlin
widgetLoader.configure(
    data = thnData,
    debugMode = true,  // Enable debug mode
    isVisible = { isVisible ->
        // Handle visibility changes
    }
)

When debug mode is enabled:

  • A border appears around the widget area
  • Enhanced logging is active
  • WebView inspection is available
  • Touch events are visualized

Troubleshooting

Common Issues

  1. Widget Not Loading

    • Verify your internet connection
    • Check that the property ID is correct
    • Ensure the widget is properly initialized in your lifecycle methods
  2. Widget Shows Nothing

    • Make sure the isVisible binding is set to true
    • Verify your data model is properly structured
    • Check the error binding for any loading errors
  3. Memory Issues

    • iOS: Make sure your bindings don't create reference cycles
    • Android: Properly handle the widget lifecycle and clear listeners when needed
  4. Touch Events Not Working

    • Make sure your widget is properly sized and visible
    • On Android, verify the touch interception is working correctly
    • Enable debug mode to visualize touch boundaries

Getting Help

For additional support:

  1. Enable debug mode to get detailed logs
  2. Check our sample applications for reference implementations
  3. Contact support at tech@thehotelsnetwork.com