Booking Item Search

Use this method to fetch a list of booking items based on a search Query.

You can search our catalog for BookingItems with the searchBookingItems method. This method can be called through two options. Via completion blocks or through delegates.

A complete working example on how this method can be used is available here

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

//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
    }
}

This approach returns a BookingItemSearchResult through the delegates. The BookingItemSearchDelegate 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

//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
    }
}

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.


// 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)
    }
}

Last updated