Creating an AutoSuggest text field with Swift
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
iOS Sample Apps
Getting started with Dave, what3words iOS Developer:
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-ap
i) 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
- From Xcode’s
File
menu chooseSwift Packages
thenAdd Package Dependancy
. - The
Choose Package Repository
window appears. Add
https://github.com/what3words/w3w-swift-components.git
in the search box, and click onNext
. - If you are satisfied with the selected version branch choices, click
Next
again. - You should then be shown “Package Product”
W3WSwiftComponents
. ChooseFinish
.
Xcode should now automatically install w3w-swift-components
, and w3w-swift-wrapper
.
In your view controller add the following import statements to the top of the file:
import W3WSwiftCore import W3WSwiftApi import W3WSwiftComponents import CoreLocation
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) }
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”)
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 ?? "") }
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)) ]
let options = W3WOptions().focus(CLLocationCoordinate2D(latitude: 50.0, longitude: 0.1)).clip(to: W3WApiCountry("GB"))
textField.set(options: options)
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)
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.
Property | Type | Description |
---|---|---|
focus | CLLocationCoordinate2D | This 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 / clipToCountries | W3WApiCountry | Restricts AutoSuggest to only return results inside the countries specified by comma-separated list of uppercase ISO 3166-1 alpha-2 country codes |
clipToCircle | center:CLLocationCoordinate2D, radius: Double | Restrict AutoSuggest results to a circle, specified by lat,lng,kilometres, |
clipToBox | southWest: CLLocationCoordinate2D, northEast: CLLocationCoordinate2D | Restrict AutoSuggest results to a bounding box, specified by coordinates. |
clipToPolygon | CLLocationCoordinate2D | Restrict AutoSuggest results to a polygon, specified by a comma-separated list of lat,lng pairs |
language | W3WApiLanguage | For normal text input, specifies a fallback language, which will help guide AutoSuggest if the input is particularly messy. |
voiceLanguage | String | Ask 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'. |
preferLand | Bool | Unless 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))
clipToCountry(W3WApiCountry) / clipToCountries([String])
w3wComponent.set(options: [W3WOption.clipToCountry(W3WApiCountry("GB")])
w3wComponent.set(options: [W3WOption.clipToCountries(["GB", "CA", "NZ", "AU"])])
clipToCircle(center:CLLocationCoordinate2D, radius: Double)
let coord = CLLocationCoordinate2D(latitude: 51.520847, longitude: -0.195521) w3wComponent.set(options: [W3WOption.clipToCircle(center: coord, radius: 10.0)])
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)])
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])])
language(String)
w3wComponent.set(options: [W3WOption.language(W3WApiLanguage(locale: "fr")])
voiceLanguage(String)
w3wComponent.set(options: [W3WOption.voiceLanguage(W3WApiLanguage(locale: "ar"))])
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" } }
For more information, visit our API plans page. If you need further assistance, contact support@what3words.com.