Documentation

 

SmartyStreets iOS SDK

If you want to access our US Street Address API or US ZIP Code API from an app written in Objective-C or Swift, the SmartyStreets iOS SDK can make it a lot easier. Our iOS SDK includes ready-made data structures and takes care of all the gritty, low-level HTTP intricacies for you.

Contents

  1. Requirements
  2. How to Get It
    1. CocoaPods
    2. Carthage
    3. Download the Source Code
  3. How to Use It
    1. Demo
    2. Examples
  4. API Reference Material

Requirements

  1. Decide to build a software project using Objective-C or Swift.
  2. Download and install XCode.
  3. Make sure you are using iOS 8.4 or higher as your target framework.
  4. Build enough of the project to realize that you now need an address verification component.
  5. Wisely conclude that you don't want to build your own address verification component.
  6. Realize that SmartyStreets has already created an address verification component.
  7. Congratulations! You are now ready to use the SmartyStreets iOS SDK.

How to Get It

CocoaPods

The easiest way to get your giddy hands on this goodness is by using CocoaPods. You can then use the SmartyStreets framework in your iOS project. (See the examples below.)

Carthage

While it's easier to install frameworks through CocoaPods, Carthage is a more flexible approach to installing third-party frameworks.

Download the Source Code

You can download the source code from the SmartyStreets iOS SDK repository on Github.

Use the source, Luke!

How to Use It

iOS Objective-C Demo

iOS Swift Demo

macOS Demo

Examples

Here are a few pieces of example code to show how to use our iOS framework. Full example projects are also found here on github. All of the SDK functionality may be invoked using Swift or Objective-C.

Objective-C: Verifying a Single US Street Address

package examples;

#import "SSUSStreetSingleAddressExample.h"

@implementation SSUSStreetSingleAddressExample

- (NSString*)run {
    id<SSCredentials> mobile = [[SSSharedCredentials alloc] initWithId:@"SMARTY WEBSITE KEY HERE" hostname:@"HOST HERE"];
    SSStreetClient *client = [[SSStreetClientBuilder alloc] initWithSigner:mobile].build;
//    Uncomment the following line to use Static Credentials
//    SSStreetClient *client = [[SSStreetClientBuilder alloc] initWithAuthId:@"YOUR AUTH-ID HERE" authToken:@"YOUR AUTH-TOKEN HERE"].build;

    SSStreetLookup *lookup = [[SSStreetLookup alloc] init];
    lookup.street = @"1600 Amphitheatre Pkwy";
    lookup.city = @"Mountain View";
    lookup.state = @"CA";

    NSError *error = nil;
    [client sendLookup:lookup error:&error];

    if (error != nil) {
        NSLog(@"Domain: %@", error.domain);
        NSLog(@"Error Code: %i", (int)error.code);
        NSLog(@"Description: %@", [error localizedDescription]);
        return @"Error sending request";
    }

    NSArray<SSCandidate*> *results = lookup.result;
    NSMutableString *output = [[NSMutableString alloc] init];

    if (results.count == 0) {
        [output appendString:@"Error. Address is not valid"];
        return output;
    }

    SSCandidate *candidate = [results objectAtIndex:0];

    [output appendString:@"Address is valid. (There is at least one candidate)\n\n"];
    [output appendString:[@"\nZIP Code: " stringByAppendingString:candidate.components.zipCode]];
    [output appendString:[@"\nCounty: " stringByAppendingString:candidate.metadata.countyName]];
    NSNumber *latitude = [NSNumber numberWithDouble:candidate.metadata.latitude];
    NSNumber *longitute = [NSNumber numberWithDouble:candidate.metadata.longitude];
    [output appendString:[@"\nLatitude: " stringByAppendingString:[latitude stringValue]]];
    [output appendString:[@"\nLongitude: " stringByAppendingString:[longitute stringValue]]];

    return output;
}

@end

Objective-C: Verifying Multiple US Street Addresses

package examples;

#import "SSUSStreetMultipleLookupsExample.h"

@implementation SSUSStreetMultipleLookupsExample

- (NSString*)run {
    SSStreetClient *client = [[SSStreetClientBuilder alloc] initWithAuthId:@"YOUR AUTH-ID HERE" authToken:@"YOUR AUTH-TOKEN HERE"].build;

    SSStreetBatch *batch = [[SSStreetBatch alloc] init];
    NSError *error = nil;

    SSStreetLookup *address0 = [[SSStreetLookup alloc] init];
    address0.street = @"1600 amphitheatre parkway";
    address0.city = @"Mountain view";
    address0.state = @"california";

    SSStreetLookup *address1 = [[SSStreetLookup alloc] initWithFreeformAddress:@"1 Rosedale, Baltimore, Maryland"];
    [address1 setMaxCandidates:10 error:&error];

    SSStreetLookup *address2 = [[SSStreetLookup alloc] initWithFreeformAddress:@"123 Bogus Street, Pretend Lake, Oklahoma"];

    SSStreetLookup *address3 = [[SSStreetLookup alloc] init];
    address3.street = @"1 Infinite Loop";
    address3.zipCode = @"95014";

    [batch add:address0 error:&error];
    [batch add:address1 error:&error];
    [batch add:address2 error:&error];
    [batch add:address3 error:&error];

    if (error != nil) {
        if ([error.domain isEqualToString:@"SSSmartyErrorDomain"] && error.code == BatchFullError) {
            NSLog(@"Description: %@", [error localizedDescription]);
            return @"Error. The batch is already full.";
        }
    }

    [client sendBatch:batch error:&error];

    if (error != nil) {
        NSLog(@"Domain: %@", error.domain);
        NSLog(@"Error Code: %i", (int)error.code);
        NSLog(@"Description: %@", [error localizedDescription]);
        return @"Error sending request";
    }

    NSArray<SSStreetLookup*> *lookups = batch.allLookups;
    NSMutableString *output = [[NSMutableString alloc] init];

    for (int i = 0; i < batch.count; i++) {
        NSArray<SSCandidate*> *candidates = [[lookups objectAtIndex:i] result];

        if (candidates.count == 0) {
            [output appendString:[NSString stringWithFormat:@"\nAddress %i is invalid\n", i]];
            continue;
        }

        [output appendString:[NSString stringWithFormat:@"\nAddress %i is valid. (There is at least one candidate)", i]];

        for (SSCandidate *candidate in candidates) {
            SSComponents const *components = candidate.components;
            SSMetadata const *metadata = candidate.metadata;

            [output appendString:[NSString stringWithFormat:@"\n\nCandidate %i :", candidate.candidateIndex]];
            [output appendString:[@"\nDelivery line 1:  " stringByAppendingString:candidate.deliveryLine1]];
            [output appendString:[@"\nLast line:        " stringByAppendingString:candidate.lastline]];
            [output appendString:[@"\nZIP Code:         " stringByAppendingString:components.zipCode]];
            [output appendString:[@"-" stringByAppendingString:components.plus4Code]];
            [output appendString:[@"\nCounty:           " stringByAppendingString:metadata.countyName]];

            NSNumber *latitude = [NSNumber numberWithDouble:metadata.latitude];
            NSNumber *longitute = [NSNumber numberWithDouble:metadata.longitude];
            [output appendString:[@"\nLatitude:         " stringByAppendingString:[latitude stringValue]]];
            [output appendString:[@"\nLongitude:        " stringByAppendingString:[longitute stringValue]]];
        }

        [output appendString:@"\n***********************************\n"];
    }

    NSLog(@"Output = %@", output);
    return output;
}

@end

Swift: Sending a Single Lookup to the US ZIP Code API

package examples;

import Foundation
import SmartystreetsSDK

class ZipCodeSingleLookupExample {

    func run() -> String {
        let mobile = SSSharedCredentials(id: "SMARTY WEBSITE KEY HERE", hostname: "HOST HERE")
        let client = SSZipCodeClientBuilder(signer: mobile).build()
//        Uncomment the following line to use Static Credentials
//        let client = SSZipCodeClientBuilder(authId: "YOUR AUTH-ID HERE", authToken: "YOUR AUTH-TOKEN HERE").build()

        let lookup = SSZipCodeLookup()
        lookup.city = "Mountain View"
        lookup.state = "California"

        do {
            try client?.send(lookup)
        } catch let error as NSError {
            print(String(format: "Domain: %@", error.domain))
            print(String(format: "Error Code: %i", error.code))
            print(String(format: "Description: %@", error.localizedDescription))
            return "Error sending request"
        }

        let result: SSResult = lookup.result
        let zipCodes = result.zipCodes
        let cities = result.cities

        var output: String = String()

        if (cities == nil && zipCodes == nil) {
            output += "Error getting cities and zip codes."
            return output
        }

        for city in cities! {
            output += "\nCity: " + (city as! SSCity).city
            output += "\nState: " + (city as! SSCity).state
            output += "\nMailable City: " + ((city as! SSCity).mailableCity ? "YES" : "NO") + "\n"
        }

        for zip in zipCodes! {
            output += "\nZIP Code: " + (zip as! SSZipCode).zipCode
            output += "\nLatitude: " + String(format:"%f", (zip as! SSZipCode).latitude)
            output += "\nLongitude: " + String(format:"%f", (zip as! SSZipCode).longitude) + "\n"
        }

        return output
    }
}

Swift: Sending Multiple Lookups to the US ZIP Code API

package examples;

import Foundation
import SmartystreetsSDK

class ZipCodeMultipleLookupsExample {

    func run() -> String {
        let client = SSZipCodeClientBuilder(authId: "YOUR AUTH-ID HERE", authToken: "YOUR AUTH-TOKEN HERE").build()

        let batch = SSZipCodeBatch()

        let lookup1 = SSZipCodeLookup()
        lookup1.zipcode = "12345" // A Lookup may have a ZIP Code, city and state, or city, state, and ZIP Code

        let lookup2 = SSZipCodeLookup()
        lookup2.city = "Phoenix"
        lookup2.state = "Arizona"

        let lookup3 = SSZipCodeLookup(city: "cupertino", state: "CA", zipcode: "95014")

        do {
            try batch.add(lookup1)
            try batch.add(lookup2)
            try batch.add(lookup3)
            try client?.send(batch)
        } catch let error as NSError {
            if error.domain == "SSSmartyErrorDomain" && error.code == SSErrors.BatchFullError.rawValue {
                print(String(format: "Description: %@", error.localizedDescription))
                return "Error. The batch is already full"
            }
            else {
                print(String(format: "Domain: %@", error.domain))
                print(String(format: "Error Code: %i", error.code))
                print(String(format: "Description: %@", error.localizedDescription))
                return "Error sending request"
            }
        }

        var lookups = batch.allLookups as [AnyObject] as! Array<SSZipCodeLookup>
        var output = String()

        for i in 0...batch.count() - 1 {
            let result = lookups[Int(i)].result
            output += "\nLookup " + String(format:"%i", i) + "\n"

            if result?.status != nil {
                output += "Status: " + (result?.status)!
                output += "\nReason: " + (result?.reason)! + "\n"
                continue
            }

            if result?.cities == nil && result?.zipCodes == nil {
                output += "Error getting cities and zip codes.\n\n"
                output += "***************\n\n"
                continue
            }

            let cities = result?.cities
            output += String(format:"%i", (cities?.count)!)
            output += " City and States match(es)"

            for city in cities! {
                output += "\nCity: " + (city as! SSCity).city
                output += "\nState: " + (city as! SSCity).state
                output += "\nMailable City: " + ((city as! SSCity).mailableCity ? "YES" : "NO") + "\n"
            }

            output += "\n"
            let zipCodes = result?.zipCodes
            output += String(format:"%i", (zipCodes?.count)!)
            output += " ZIP Code match(es):"

            for zip in zipCodes! {
                output += "\nZIP Code: " + (zip as! SSZipCode).zipCode
                output += "\nCounty: " + (zip as! SSZipCode).countyName
                output += "\nLatitude: " + String(format:"%f", (zip as! SSZipCode).latitude)
                output += "\nLongitude: " + String(format:"%f", (zip as! SSZipCode).longitude) + "\n"
            }
            output += "***********************************\n"
        }

        return output
    }
}