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.

Full sample apps for the component can be found in our Github repo
github icon white iOS Sample Apps

Getting started with Dave, what3words iOS Developer:

1Get API key
Signup to create key
2Installation

Updated Package Structure

We’ve made changes to our Swift packages to provide more flexibility. Here’s what you need to know:

1. Separate Voice Package (w3w-swift-voice-api):
If your application only requires what3words voice functionality, you can now import the voice package independently by including w3w-swift-voice-api in your project.
This reduces unnecessary dependencies if you don’t need the full API wrapper.

2. Backwards Compatibility:
The newest version of the w3w-swift-wrapper remains backwards compatible. If you already use the wrapper, no changes are needed; your existing code will continue to work without modification.

To maintain backwards compatibility, the w3w-swift-wrapper now includes the voice package (w3w-swift-voice-api) automatically. This ensures that developers relying on the old wrapper for voice functionality won’t experience any breaking changes.

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.

3Basic usage

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

import W3WSwiftCore
import W3WSwiftApi
import W3WSwiftComponents
import CoreLocation
Copied

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

    override func viewDidLoad() {
     super.viewDidLoad()
     // instantiate the API
     let api = What3WordsV4(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(W3WApiCountry(code: "GB")),
  W3WOption.focus(CLLocationCoordinate2D(latitude: 50.0, longitude: 0.1))
]
Copied
let options = W3WOptions().focus(CLLocationCoordinate2D(latitude: 50.0, longitude: 0.1)).clip(to: W3WApiCountry("GB"))
Copied
textField.set(options: options)
Copied
4Voice 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
5Advanced 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 / clipToCountriesW3WApiCountryRestricts 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
languageW3WApiLanguageFor 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(W3WApiCountry) / clipToCountries([String])

w3wComponent.set(options: [W3WOption.clipToCountry(W3WApiCountry("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(W3WApiLanguage(locale: "fr")])
Copied

voiceLanguage(String)

w3wComponent.set(options: [W3WOption.voiceLanguage(W3WApiLanguage(locale: "ar"))])
Copied
6Troubleshooting

If you encounter errors or issues related to convert-to-coordinate, convert-to-3wa and grid-section requests while using the Free plan, please check the network panel for the following error message Error 402 payment required and its response, indicating the need to upgrade to a higher plan:

{
    "error": {
        "code": "QuotaExceeded",
        "message": "Quota exceeded or API plan does not have access to this feature. Please change your plan at https://accounts.what3words.com/select-plan, or contact support@what3words.com"
    }
}
Copied

For more information, visit our API plans page. If you need further assistance, contact support@what3words.com.

Mobile AppAdd a 3 word address input fieldSwift

Related tutorials