SMARTY DISCLAIMER: Subject to the terms of the associated license agreement, this software is freely available for your use. This software is FREE, AS IN PUPPIES, and is a gift. Enjoy your new responsibility. This means that while we may consider enhancement requests, we may or may not choose to entertain requests at our sole and absolute discretion.
The official iOS SDK for accessing Smarty address validation APIs from Swift and Objective-C. Requires Swift 5.0+ and has no external dependencies.
"Getting started with the SmartyStreets iOS SDK" (Click to play on YouTube)
Add the package to your Package.swift dependencies:
dependencies: [
.package(url: "https://github.com/smartystreets/smartystreets-ios-sdk.git", from: "8.10.17"),
]Then add SmartyStreets to your target's dependencies. In Xcode, use File → Add Package Dependencies and enter the repository URL.
import SmartyStreets
let authId = ProcessInfo.processInfo.environment["SMARTY_AUTH_ID"] ?? ""
let authToken = ProcessInfo.processInfo.environment["SMARTY_AUTH_TOKEN"] ?? ""
let client = ClientBuilder.withBasicAuth(authId: authId, authToken: authToken)
.buildUsStreetApiClient()
var lookup = USStreetLookup()
lookup.street = "1600 Amphitheatre Parkway"
lookup.city = "Mountain View"
lookup.state = "CA"
lookup.maxCandidates = 3
var error: NSError! = nil
_ = client.sendLookup(lookup: &lookup, error: &error)
if let error = error {
print("Error: \(error.localizedDescription)")
} else if let candidate = lookup.result.first {
print("ZIP: \(candidate.components?.zipCode ?? "")")
}let client = ClientBuilder.withBasicAuth(authId: authId, authToken: authToken)
.buildUSAutocompleteProApiClient()
var lookup = USAutocompleteProLookup().withSearch(search: "4770 Lincoln")
lookup.maxResults = 10
lookup.addPreferState(state: "IL")
var error: NSError! = nil
_ = client.sendLookup(lookup: &lookup, error: &error)
if let suggestions = lookup.result?.suggestions {
for s in suggestions {
print("\(s.streetLine ?? "") \(s.city ?? ""), \(s.state ?? "") \(s.zipcode ?? "")")
}
}| API | Lookup Type | Build Method | Example |
|---|---|---|---|
| US Street | USStreetLookup |
buildUsStreetApiClient() |
example |
| US Zipcode | USZipCodeLookup |
buildUsZIPCodeApiClient() |
example |
| US Autocomplete Pro | USAutocompleteProLookup |
buildUSAutocompleteProApiClient() |
example |
| US Extract | USExtractLookup |
buildUsExtractApiClient() |
example |
| US Enrichment | EnrichmentLookup |
buildUsEnrichmentApiClient() |
example |
| US Reverse Geocoding | USReverseGeoLookup |
buildUsReverseGeoApiClient() |
example |
| International Street | InternationalStreetLookup |
buildInternationalStreetApiClient() |
example |
| International Autocomplete | InternationalAutocompleteLookup |
buildInternationalAutocompleteApiClient() |
example |
| International Postal Code | InternationalPostalCodeLookup |
buildInternationalPostalCodeApiClient() |
example |
Three credential types are available:
ClientBuilder(authId:authToken:)— Server-to-server using auth-id and auth-token (passed as query parameters).ClientBuilder.withBasicAuth(authId:authToken:)— HTTP Basic Auth.ClientBuilder(id:hostname:)— Client-side (mobile/browser) authentication using an embedded key andRefererhostname. Does not support batch (POST) requests.
// Server-to-server (query params)
let client = ClientBuilder(authId: authId, authToken: authToken).buildUsStreetApiClient()
// HTTP Basic Auth
let client = ClientBuilder.withBasicAuth(authId: authId, authToken: authToken).buildUsStreetApiClient()
// Client-side with a website key
let client = ClientBuilder(id: embeddedKey, hostname: "yourhost.com").buildUsStreetApiClient()Credentials should be stored in environment variables or a secure keychain — never checked into source control.
Send up to 100 lookups in a single request (not available with embedded-key credentials):
let batch = USStreetBatch()
var error: NSError! = nil
_ = batch.add(newAddress: address1, error: &error)
_ = batch.add(newAddress: address2, error: &error)
_ = client.sendBatch(batch: batch, error: &error)API errors are returned as NSError values in the SmartyErrorDomain. The sendLookup(lookup:error:) family uses the inout pointer pattern for Objective-C compatibility:
var error: NSError! = nil
_ = client.sendLookup(lookup: &lookup, error: &error)
if let error = error {
print("Domain: \(error.domain)")
print("Code: \(error.code)")
print("Description: \(error.localizedDescription)")
}let client = ClientBuilder.withBasicAuth(authId: authId, authToken: authToken)
.retryAtMost(maxRetries: 5)
.withMaxTimeout(maxTimeout: 10000)
.buildUsStreetApiClient()let client = ClientBuilder.withBasicAuth(authId: authId, authToken: authToken)
.withProxy(host: "proxy.example.com", port: 8080)
.buildUsStreetApiClient()let client = ClientBuilder.withBasicAuth(authId: authId, authToken: authToken)
.withCustomHeader(key: "X-Custom-Header", value: "value")
.buildUsStreetApiClient()Note: custom User-Agent values are appended to the SDK's default (smartystreets (sdk:ios@<version>)) rather than replacing it. All other headers replace as expected.
Optional US Street features can be enabled on the builder:
let client = ClientBuilder.withBasicAuth(authId: authId, authToken: authToken)
.withFeatureComponentAnalysis()
.withFeatureIanaTimeZone()
.buildUsStreetApiClient()All public classes are marked @objcMembers and inherit from NSObject, so the SDK is usable from Objective-C projects. Requests are synchronous — the SDK uses DispatchSemaphore internally. Call from a background queue if you need to avoid blocking the main thread.
Full API documentation is available at smarty.com/docs/sdk/ios.
