#
Objective-C and W3W Components
Overview
--------
This explains how to add what3words iOS components to your Objective C project.
While this is implemented in Swift, it is compatible with Objective C and designed to be used excusively with Objective C. The thinking is that it made more sense to provide a light ObjC wrapper and maintain a pure Swift project than to infuse @obj directives throughout the entire code base, and to adjust for peculiarities of NSObject derived Swift classes.
Two text components are provided:
- `W3WObjcAutoSuggestTextField` is derived from `UITextField`
- `W3WAutoSuggestSearchController` is derived from `UISearchController`.
Other than the differences of the base classes, these both have the same interface.
TLDR
----
Too long? Don't want to read? Jump to the [example at the end of this document](#tldrex), or go to the [Objective-C tutorial](ObjectiveCTutorial.md) document.
Installation
------------
#### Authentication
To use this library you’ll need a what3words API key, which can be signed up for [here](https://what3words.com/select-plan). If you wish to use the Voice API calls then you must add a Voice API plan to your [account](https://accounts.what3words.com/billing).
#### Swift Package Manager
You can install with [Swift Package Manager](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app) by adding the URL below to Swift Packages under your project settings:
```
https://github.com/what3words/w3w-swift-components.git
```
Import the libraries into your Objective-C code:
```objective-c
@import W3WSwiftComponents;
@import W3WSwiftApi;
#import
```
##### Note:
If you are using the Voice API on device, you should include Microphone permissions in your Info.plist
Usage
-----
#### Setup
```objective-c
// some coordinates for the component
CGRect frame = CGRectMake(16.0, 300.0, self.view.frame.size.width - 32.0, 32.0);
// make the textfield
W3WObjcAutoSuggestTextField *textfield = [[W3WObjcAutoSuggestTextField alloc] initWithFrame:frame];
/// Assign the API key
[textfield setApiKey: @"YourApiKey"];
// Add it to your view
[self.view addSubview:textfield];
```
#### Callbacks
To be notified when the user selects an address:
```objective-c
[textfield setSuggestionCallback: ^(W3WObjcSuggestion *suggestion) {
NSLog(@"%@", suggestion.words);
}];
```
To be notified about errors:
```objective-c
[textfield setErrorCallback: ^(NSError *error) {
NSLog(@"Error: %@", error.localizedDescription);
}];
```
If you want to monitor the user input keystroke by keystroke
```objective-c
[textfield setTextChangedCallback: ^(NSString *text) {
NSLog(@"%@", text);
}];
```
### Options
Options alter the behaviour of the autosuggest function and filter the addresses that are presented to the user. For example, you can set an `ClipToCountry` option so that only addresses in a particular country are shown.
It is *strongly recoomended* that you at least set the focus option so that addresses nearest your user get priority.
Options are set using the `W3WObjcOptions` object:
```objective-c
// Make an option object
W3WObjcOptions *options = [[W3WObjcOptions alloc] init];
// Add any options you want
[options addFocus: CLLocationCoordinate2DMake(51.520847,-0.195521)];
[options addClipToCountry: @"GB"];
// Finally, set these options on the component:
[textfield setOptions: options];
```
### Example
Here is an example of presenting a W3WObjcAutoSuggestTextField in UIViewcontroller's viewDidLoad:
```objective-c
@import W3WSwiftComponents;
@import W3WSwiftApi;
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// some coordinates for the component
CGRect frame = CGRectMake(16.0, 300.0, self.view.frame.size.width - 32.0, 32.0);
// make the autosuggest component
W3WObjcAutoSuggestTextField *textfield = [[W3WObjcAutoSuggestTextField alloc] initWithFrame:frame];
// assign the API key an set the desired language
[textfield setApiKey:@"YourApiKey"];
[textfield setLanguage:@"en"];
// make focus and countryClipping options
W3WObjcOptions *options = [[W3WObjcOptions alloc] init];
[options addFocus: CLLocationCoordinate2DMake(51.520847,-0.195521)];
[options addClipToCountry: @"GB"];
[textfield setOptions: options];
// add the component to the view
[self.view addSubview:textfield];
// print out any address that the user chooses
[textfield setSuggestionCallback: ^(W3WObjcSuggestion *suggestion) {
NSLog(@"%@", suggestion.words);
}];
// print out any error
[textfield setErrorCallback: ^(NSError *error) {
NSLog(@"Error: %@", error.localizedDescription);
}];
}
@end
```
### Method Reference
#### setApi
Set the API key
` [textfield setApiKey:@"YourApiKey"];`
#### setLanguage
Set the expected input language. Defaults to English.
` [textfield setLanguage:@"en"];`
#### setVoice
Turn on voice recognition if available. Set to true by default
`[textfield setVoice: YES];`
#### setAllowInvalid3wa
This prevents the component from sending an error if the user leaves the field without entering a valid three word address. Default is `NO`.
`[textfield setAllowInvalid3wa: YES];'
#### setFreeformText
Allows any character to be typed in. Defaults to `YES`. If set to `NO` then all characters that are not part of a valid three word address will not be registered or displayed.
`[textfield setFreeformText:NO];`
#### setOptions
Sets the options to use when calling autosuggest
`[textfield setOptions: options];`
#### setSuggestionCallback
Sets a closure that gets called when the user selects an address
```
[textfield setSuggestionCallback: ^(W3WObjcSuggestion *suggestion) {
NSLog(@"%@", suggestion.words);
}];
```
#### setErrorCallback
Sets a closure that gets called when there is an error
```
[textfield setErrorCallback: ^(NSError *error) {
NSLog(@"Error: %@", error.localizedDescription);
}];
```
#### setTextChangedCallback
Sets a closure that gets called when the text in the textfield changes
```
[textfield setTextChangedCallback: ^(NSString *text) {
NSLog(@"%@", text);
}];
```
### W3WObjcSuggestion
This object contains the values for a suggestion
```
NSString *words
NSString *country
NSString *nearestPlace
NSString *distanceToFocus
NSString *language
```
### W3WObjcOptions
To fully understand the options please read the options section in the [API documentation](https://developer.what3words.com/public-api/docs).
#### addFocus
Provides addresses sorted by relavance to a location
`[options addFocus: CLLocationCoordinate2DMake(51.520847,-0.195521)];`
#### addClipToCountry
Restricts addresses to only one country
`[options addClipToCountry: @"GB"];`
#### addClipToCountries
Restricts results to a list of countries
`[options addClipToCountries: @[@"GB", @"CA"]];`
#### addVoiceLanguage
Sets the language to use for voice input
`[options addVoiceLanguage: @"en"];`
#### addClipToCircle:radius
Restricts results to a geographic circle
`[options addClipToCircle: CLLocationCoordinate2DMake(50.0, -0.1) radius: 10.0];`
#### addClipToBoxSouthWest:northEast
Restricts results to a geographic rectangle
`[options addClipToBoxSouthWest:CLLocationCoordinate2DMake(51.51481,-0.204366) northEast:CLLocationCoordinate2DMake(51.535589,-0.168336)];`
#### addPreferLand
Gives preference to land based addresses. Default is `YES`
`[options addPreferLand: NO];`
#### addClipToPolygon
Clips resutls to a geographic poliganal shape.
```
[options addClipToPolygon: @[
[NSValue valueWithMKCoordinate:CLLocationCoordinate2DMake(51.51481,-0.204366)],
[NSValue valueWithMKCoordinate:CLLocationCoordinate2DMake(51.56378,-0.329019)],
[NSValue valueWithMKCoordinate:CLLocationCoordinate2DMake(51.535589,-0.168336)],
[NSValue valueWithMKCoordinate:CLLocationCoordinate2DMake(51.402153,-0.075661)],
[NSValue valueWithMKCoordinate:CLLocationCoordinate2DMake(51.51481,-0.204366)]
]];
```