Creating an AutoSuggest text field with Swift

easy

The Swift library provides UITexfield component to make using the what3words API even easier. In this tutorial, we will go through using a component from the wrapper which allows the user to get a search input for their app, powered by the what3words API AutoSuggest function. As you will see it is straightforward to use and allows you to configure it for your needs using a range of properties.

The W3WAutoSuggestTextField is derived from UITextField iOS component.

iOS Component

Full sample apps for the component can be found in our Github repo.

You will need a what3words API key to complete this tutorial.

2

Installation

Add the Swift Package at https://github.com/what3words/w3w-swift-components to your project.

https://github.com/what3words/w3w-swift-components.git
Copied
  1. From Xcode’s File menu choose Swift Packages then Add Package Dependancy.
  2. The Choose Package Repository window appears. Add
    https://github.com/what3words/w3w-swift-components.git in the search box, and click on Next.
  3.  If you are satisfied with the selected version branch choices, click Next again.
  4. You should then be shown “Package Product” W3WSwiftComponents. Choose Finish.

Xcode should now automatically install w3w-swift-components, and w3w-swift-wrapper.

3

Basic usage

In your view controller add the following import statements to the top of the file:

import W3WSwiftApi
import W3WSwiftComponents
import CoreLocation
Copied

Add the following to viewDidLoad(). You’ll need to add your what3words API key to let api = What3WordsV3(apiKey: "YourApiKey")

    override func viewDidLoad() {
     super.viewDidLoad()
     // instantiate the API
     let api = What3WordsV3(apiKey: "YourApiKey")
     // make the text field, and give it a place in the view
     let textField = W3WAutoSuggestTextField(frame: CGRect(x: 16.0, y: (UIApplication.shared.windows.first?.windowScene?.statusBarManager?.statusBarFrame.height ?? 64.0) + 16.0, width: view.frame.size.width - 32.0, height: 32.0))
     // assign the API to the text field
     textField.set(api)
     // tell autosuggest where the user is to get more relevant resultes use focus
     textField.set(options: W3WOption.focus(coords))
    
     // assign a code block to execute when the user has selected an address
     textField.suggestionSelected = { suggestion in
       print(suggestion.words ?? "")
     }
     // the error can be captured using onError
     textField.onError = { error in
       print(String(describing: error))
     }
     // place in the view
     view.addSubview(textField)
   }
Copied

Run the app

You can now run the app and you will see the new field appear. Type a 3 word address and you should see suggestions appear after you start typing the 3rd word.

Enterprise Suite

If you run our Enterprise Suite API Server yourself, you may specify the URL to your own server:

suggestionField!.setAPIKey(APIKey:<Secret API Key>, apiUrl: “https://api.yourserver.com”)
Copied

Obtaining suggestions details

To be informed when the user chooses a suggestion from the list, assign a closure to suggestionSelected. It is called with a struct that conforms to the W3WSuggestion protocol.

textField.suggestionSelected = { suggestion in
  print("User chose:", suggestion.words ?? "")
}
Copied

Configuring AutoSuggest properties

You may set any of the AutoSuggest options for these text fields. If you use voice search, then these options will be automatically applied to that as well. In addition a number of other properties can be applied to configure the component. A full list can be found in the Advanced usage section of the tutorial.

You may specify options as an array of W3WOption, or using the W3WOptions factory:

let options = [
  W3WOption.clipToCountry("GB"),
  W3WOption.focus(CLLocationCoordinate2D(latitude: 50.0, longitude: 0.1))
]
Copied
let options = W3WOptions().focus(CLLocationCoordinate2D(latitude: 50.0, longitude: 0.1)).clipToCountry("GB")
Copied
textField.set(options: options)
Copied
4

Voice support

The component also allows for voice input using the what3words Voice API. This feature allows the user to say 3 words and using speech recognition technology displays 3 word address suggestions to the user.

Before enabling Voice AutoSuggest you will need to add a Voice API plan in your account.

By default, the voice language is set to English but this can be changed using the voiceLanguage property (for a list of available languages please check the properties table below). Voice input respects the clipping and focus options applied within the general properties. We recommend applying clipping and focus where possible to display as accurate suggestions as possible.

 textField.set(voice: true)
Copied
5

Advanced usage

In order to customise the iOS component, there are a number of properties that can be set. These match the wrapper for the main API to configure properties such as country clipping and focus.

PropertyTypeDescription
focusCLLocationCoordinate2DThis is a location, specified as latitude,longitude (often where the user making the query is). If specified, the results will be weighted to give preference to those near the focus
clipToCountry / clipToCountriesStringRestricts AutoSuggest to only return results inside the countries specified by comma-separated list of uppercase ISO 3166-1 alpha-2 country codes
clipToCirclecenter:CLLocationCoordinate2D, radius: DoubleRestrict AutoSuggest results to a circle, specified by lat,lng,kilometres,
clipToBoxsouthWest: CLLocationCoordinate2D, northEast: CLLocationCoordinate2DRestrict AutoSuggest results to a bounding box, specified by coordinates.
clipToPolygonCLLocationCoordinate2DRestrict AutoSuggest results to a polygon, specified by a comma-separated list of lat,lng pairs
languageStringFor normal text input, specifies a fallback language, which will help guide AutoSuggest if the input is particularly messy.
voiceLanguageStringAsk for results from the voice API in a particulalr language. Language must be an ISO 639-1 2 letter code, such as 'en' or 'fr'.
preferLandBoolUnless your application deals mostly with locations in the ocean it's best to leave this default.

W3WOption is an enum with each case carrying a parameter representing one possible option. W3WOptions is a class that contains an array of W3WOption.

Here are the case values of W3WOption:

focus(CLLocationCoordinate2D)

let coords = CLLocationCoordinate2D(latitude: 50.0, longitude: 0.1)
w3wComponent.set(options: W3WOption.focus(coords))
Copied

clipToCountry(String) / clipToCountries([String])

w3wComponent.set(options: [W3WOption.clipToCountry("GB")])
Copied
w3wComponent.set(options: [W3WOption.clipToCountries(["GB", "CA", "NZ", "AU"])])
Copied

clipToCircle(center:CLLocationCoordinate2D, radius: Double)

let coord = CLLocationCoordinate2D(latitude: 51.520847, longitude: -0.195521)
w3wComponent.set(options: [W3WOption.clipToCircle(center: coord, radius: 10.0)])
Copied

clipToBox(southWest: CLLocationCoordinate2D, northEast: CLLocationCoordinate2D)

let southWest = CLLocationCoordinate2D(latitude: 51.51481, longitude: -0.204366)
let northEast = CLLocationCoordinate2D(latitude: 51.535589, longitude: -0.168336)
w3wComponent.set(options: [W3WOption.clipToBox(southWest: southWest, northEast: northEast)])
Copied

clipToPolygon([CLLocationCoordinate2D])

let p0 = CLLocationCoordinate2D(latitude: 51.51481, longitude: -0.204366)
let p1 = CLLocationCoordinate2D(latitude: 51.56378, longitude: -0.329019)
let p2 = CLLocationCoordinate2D(latitude: 51.535589, longitude: -0.168336)
let p3 = CLLocationCoordinate2D(latitude: 51.402153, longitude: -0.075661)
w3wComponent.set(options: [W3WOption.clipToPolygon([p0, p1, p2, p3, p1])])
Copied

language(String)

w3wComponent.set(options: [W3WOption.language("fr")])
Copied

voiceLanguage(String)

w3wComponent.set(options: [W3WOption.voiceLanguage("ar")])
Copied

Related tutorials

Back to top