# Booking Item Search

You can search our catalog for [`BookingItems`](https://ios.guestlogix.io/Structs/BookingItem.html#/s:11TravelerKit11BookingItemV11isAvailableSbvp) with the `searchBookingItems` method. This method can be called through two options. Via completion blocks or through delegates.&#x20;

A complete working example on how this method can be used is available [here](https://github.com/Guestlogix/traveler-ios/blob/master/traveler-ios-ui/TravelerKitUI/ViewControllers/BookingItemSearchResultViewController.swift)

### Searching with delegates

To execute a booking search it is necessary to inject a `BookingItemQuery` object into the method and to declare an entity conforming to the `BookingItemSearchDelegate`. The method signature also includes an optional identifier. This identifier is meant to be used for pagination purposes, and it is not required.

The example below shows how to execute a basic search

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

```swift
//In an existing ExampleViewController.swift
let searchQuery = BookingItemQuery(text: "Tours in Toronto", range: nil, boundingBox: nil)
Traveler.searchBookingItems(searchQuery: searchQuery, identifier: nil, delegate: self)
}

extension ExampleViewController: BookingItemSearchDelegate {
    func bookingItemSearchDidSucceedWith(_ result: BookingItemSearchResult, identifier: AnyHashable?) {
    // Successful search, deal with results here
    }
    
    func bookingItemsearchDidFailWith(_ error: Error, identifier: AnyHashable?) {
    // Unsuccessul search, deal with error here
    }
}
```

{% endtab %}

{% tab title="Android" %}

{% endtab %}
{% endtabs %}

This approach returns a [`BookingItemSearchResult`](https://ios.guestlogix.io/Structs/BookingItemSearchResult.html) through the delegates. The [`BookingItemSearchDelegate`](https://ios.guestlogix.io/Protocols/BookingItemSearchDelegate.html) also contains methods to deal with paginated results. These have default no-op implementations, so they're not required to conform to the protocol.

Pagination is handled by the SDK by receiving the initial or previous results and merging them to the new results if the search is consistent between calls. Both the previous result and the merged result are transmitted through delegates.

Paginated results can be handled as follows

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

```swift
//In an existing PaginatedViewController.swift
var previousResult: BookingItemSearchResult?
let searchQuery = BookingItemQuery(page: page, for: searchQuery)
Traveler.searchBookingItems(searchQuery: searchQuery, identifier: page, delegate: self)
}

//Suggested approach: Extend booking query to have an initializer that takes pages
extension BookingItemQuery {
    static let pageSize = 10
    init(page: Int, for query: BookingItemQuery) {
        self.init(offset: page * BookingItemQuery.pageSize, take: query.limit, text: query.text, range: query.priceRange, categories: query.categories, boundingBox: query.boundingBox)
    }
}

extension PaginatedViewController: BookingItemSearchDelegate {
    func bookingITemSearchDidSucceedWith(_ result: BookingItemSearchResult, identifier: AnyHashable?) {
        // Deal with successful search
    }
    
    func bookingItemSearchDidReceive(_ result_ BookingItemSearchResult, identifier: AnyHashable?) {
        // Deal with merged results. 
    }
    
    func bookingItemSearchDidFailWith(_ error: Error, identifier: AnyHashable?) {
        // Deal with error while searching
    }
    
    public func previousResult() -> BookingItemSearchResult? {
        // Return previous results to the SDK. 
        return previousResult
    }
}
```

{% endtab %}

{% tab title="Android" %}

{% endtab %}
{% endtabs %}

### Searching with completion blocks

Search with completion blocks is an alternative approach to delegates. Structure is fairly similar, although a minor difference is that the approach with delegates allows the user to ignore pagination (see performing basic search above) whereas this approach forces the user to deal with pagination from the get go.

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

```swift

// In an existing PaginatedViewController.swift
var previousResult: BookingItemSearchResult?
let searchQuery = BookingItemQuery(page: page, for: searchQuery)
Traveler.searchBookingItems(searchQuery: query, identifier: page, previousResultBlock: { () -> BookingItemSearchResult? in
            //Send previous result
            return previousResult
        }, resultBlock: { (mergedResults, identifier) in
            // deal with merged results
        }) { (searchResults, error, identifier) in
            //Deal with search results or error
        }
}

//Suggested approach: Extend booking query to have an initializer that takes pages
extension BookingItemQuery {
    static let pageSize = 10
    init(page: Int, for query: BookingItemQuery) {
        self.init(offset: page * BookingItemQuery.pageSize, take: query.limit, text: query.text, range: query.priceRange, categories: query.categories, boundingBox: query.boundingBox)
    }
}
```

{% endtab %}

{% tab title="Android" %}

{% endtab %}
{% endtabs %}


---

# Agent Instructions: 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:

```
GET https://docs.guestlogix.io/traveler/mobile-sdks/stripe-payment-sdk/booking-item-search.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
