Practical Get Started With Swift

Recently, I had to get started (fast) with Swift on a series of existing iOS projects. I would classify myself as being able to get to fourth gear in a Honda Accord with a manual transmission when it comes to using and applying Swift. I look forward to the day when my Swift knowledge is equivalent to running full out on the Nurburgring in a Bugati Veyron.

My background is C, C++, C#, Objective-C, with a side of JavaScript along the way.

I will never admit to any classic Visual Basic, or VB.NET, code ever being typed by my fingers, ever!

When it comes to learning a new language, I find myself in ‘Use it or lose it’ mode. Learning Swift comes very naturally if you have a concrete task which allows you to add a feature, or refactor an existing iOS project, with brand new Swift code.

I found that becoming proficient with Swift was very easy given the general C language progression in my career. In very short order, I was able to do almost all the tasks in Swift that I would normally do in Objective-C against the CocoaTouch / UIKit API surface. More advanced Swift language constructs exist, which I have barely touched, and hope to be able to learn and apply some day—I am looking at you, protocol extensions and generics.

Swift is an expansive language with many hidden gems and great language constructs. The Swift Programming Language (Swift 2.2) iBook is over 1,000 pages (as paginated at my screen size, your mileage may vary) and has so many great samples and documented language features that your brain quickly fills up as you read through it. It may seem daunting, but, once the basics of Swift are mastered, the advanced techniques will follow.

This very rough guide is meant to expose you to the philosophy behind the Swift language and provide references to the point where you feel comfortable doing almost any task in Swift.

What follows are references, philosophy, history, and a general story of what I went through while revving up with the Swift language. You will notice I don’t have any Swift code in this post. At all. Apple does such an amazing job in the The Swift Programming Language (Swift 2.2) iBook that I recommend you just go there for all the startup samples you need. Rev up your Mac, install Xcode, rev up a Playground, put the Swift Programming Language book on Monitor 2, and get started learning Swift.

I sincerely hope that your experience is as good as mine was as I started learning Swift.

Reference and Learning

iBooks – The Swift Programming Language (Swift 2.2)

iBooks – Using Swift with Cocoa and Objective-C (Swift 2.2)

  • These 2 iBooks are the definitive guide to the Swift language. They are sweeping and comprehensive and serve to build you up gradually from basics to advanced Swift language constructs.

iTunes U – Developing iOS 9 Apps with Swift by Stanford

  • I cannot recommend these movies more highly. These serve as a great simultaneous companion to the Apple Swift iBooks.

Ray Wenderlich – Swift 2 Tutorial: A Quick Start

  • Nobody does amazingly useful and entertaining tutorials like Mr. Wenderlich and his companions. Dig deeper at this site to find even more useful iOS code snippets.

Github – Awesome Swift – Includes tutorials and frameworks

  • Yet another great list of maintained links related to Swift language ‘Get Started’ guides and Swift based Frameworks.

Subscribe to Swift Weekly

  • Swift Weekly does a great job of summarizing what is happening with the constantly changing Swift language development, in addition to providing some really great links that should help you be more ‘Swifty’ with your code and thinking.

Swift Frameworks I can recommend

Github – Decodable – Translate JSON to Swift structs

  • I like Decodable more than Argo + Curry and SwiftyJSON for JSON to Swift struct translation.
  • IMHO: Nothing beats C# + Newtonsoft.JSON (or JSON.NET) for seamless and awesome JSON translation. But Decodable makes JSON to object conversion way easier than anything in Objective-C.
  • Side note: In order to use these frameworks in your iOS project, you probably also need to become proficient with Carthage or CocoaPods based dependency management within an Xcode project.

WWDC Swift Sessions

I hate to say: “Watch them all”, but …

From WWDC 2015:

What’s New in Swift

  • Worth it to see how the language evolved between Swift 1.0 and Swift 2.x

Protocol-Oriented Programming in Swift

  • Worth it to get exposure to a series of more advanced language features
  • The focus on class vs. struct (or reference vs. value types) is also a great object lesson (pardon the pun).
  • For those of you with C# experience this video is fascinating when you realize that protocol in Swift is the exact same thing as interface in C#.

Building Better Apps with Value Types in Swift

  • Helps reinforce the concepts from the Protocol-Oriented Programming in Swift video.

Swift and Objective-C Interoperability

  • Much of the Interoperability rules are changing with Swift 3.0. Especially naming.

Swift in Practice

Improving Your Existing Apps with Swift

Optimizing Swift Performance

WWDC 2016 promises Swift 3.0 videos and much more Swift architecture goodness.

Swift Futures

Swift is now all open source out on Github with a very active community of developers. To stay on top of things be sure to join the community and the mailing lists.

  • To give you an idea regarding Swift language topics discussed:
    • The community has talked about completely removing the for statement from the language and requiring a closure like replacement along the lines of map.

The Talk Show Podcast – Episode 139Transcript

  • Craig Federighi discusses the Swift language history and future.
  • There is a great follow up by John Siracusa.

Key Concepts You Should ‘Grok’

I believe that the following things are the practical takeaways from all that reference material for any starting Swift programming experience:

  • Optionals and unpacking – Over the long haul, this will become the #1 thing that you are always thinking about as you program in Swift. For C programmers, Optionals and unpacking is the same as malloc and free. Every variable and member needs to be thought of in terms of whether or not to make it optional. You will get so tired of the red dot in Xcode telling you to add a ! here and a ? there. The more you grok optionals and unpacking, the less friction you will have day-to-day with the language.
  • if .. let – If let is a great helper for all the optional access and value unpacking you will need to do. If let is a huge helper as you interface with legacy CocoaTouch / UIKit constructs.
  • var and let – Every variable declared needs to be thought of as mutable or immutable. This concept coupled with optionals is a huge mind shift, especially for Javascript and C# programmers.
  • Class vs. struct or reference vs. value types – Knowing the difference between reference and value types can help improve performance and also give you a leg up on the mutation of your object across calls. The weirdness that results when the Swift String is actually a value type (and not a reference type such as NSString*) is also an interesting brain twister.
  • Closures – Closures in Swift are similar to blocks in Objective-C, however the cleaner (and possibly more complex) language handling of closures can be mind bending. This is especially true for closures as the last parameter to a function where the function call can be closed, but the closure can go on.
  • Threading / Async – Unfortunately, Swift has no native language construct for async or multiple thread handling. This means that you are on your own with GCD calls, or other thread handling techniques you already do with Objective-C, only in an all new language.
    • C# people will really start to miss async / await, and Javascript people will start to dislike the GCD nastiness around their closures. You can only type dispatch_get_main_queue() so many times before you start to lose more hair than a 42 year old with a bald maternal grandfather.

Philosophical and Design Takeaways

  • Swift is a perpetual Beta language – I am being kind of vicious with this statement. Apple continues to evolve Swift at a rapid pace (see also the community links above). Apple has stated that they have no issues with changing the language so your code won’t compile under future versions of Swift. This is both good and bad. It is good in that Apple is very dedicated to awesome Swift futures. It is bad in that future refactoring of your code could include things like rewriting every for loop as the for keyword is rendered obsolete by the compiler.
  • Swift is designed to eliminate null access crashes – Apple has tons of app crash metric data. From that metric data they learned that EXC_BAD_ACCESS is probably the #1 problem all apps suffer from. To eliminate the dreaded null access crashes, Swift is designed from the ground up to make sure that you know how every memory chunk is being accessed from each variable.
  • Apple has shipped very few applications that utilize Swift code on iOS as of January 2016Unfortunately, this is believed to be true. As Apple really starts to ramp up on Swift, there will be more and more changes to the language, and much more stability to the language and runtime.
  • Swift may not be for you, your company, or your project, yet – Your company probably has a ton of assets in Javascript, C, C++, C#, and Java. Those assets are crown jewels. You should treasure them. There are many ways to reuse those assets on iOS that won’t break the bank and require you to learn a whole new Swift based technology stack. Swift may not be for you if you don’t have any Objective-C based resources yet.
    • Javascript – Take a look at React Mobile, PhoneGap, or other Javascript based app frameworks.
    • C# – Take a look at Xamarin and Xamarin.iOS / MonoDroid, portable assemblies, and .NET Core futures.
    • Java – Take a look at the Android platform. If you need to be on iOS take a look at J2ObjC. With all that Objective-C code generated from your Java code, you can always bring in Swift on an as-needed basis.

I come from a diverse background of technologies across Windows and iOS, front end and server side. I can say that Swift is a dramatic improvement over Objective-C on many levels. However, as with all new things that are working against 20-year-old code (and the ideas behind that code), there are going to be bugs and changes as things evolve. Sometimes it is best to use what you have, be ready for what is coming, then jump in feet first into something like the current Swift stack.

Knowing the depths of Objective-C helps you learn Swift

It is 1000 times easier to use Swift if you have a firm grounding in Objective-C.

There, I said it. Apple doesn’t want to admit it, but you can become efficient with Swift much faster if you understand all the concepts behind Objective-C.

Message passing, reference counting, automatic reference counting, strong / weak references, protocols, delegates, the whole philosophical and technological surface of CocoaTouch / UIKit, function naming conventions—All of that Objective-C knowledge will only help you ramp up rapidly on Swift.

Swift is way easier to learn if you can intuitively grok that behind all those smooth Swift wrapped CocoaTouch / UIKit calls exist a ragged, crunchy, 20-year-old Objective-C core. There are classes that still start with NS in there! NS stands for NeXTSTEP! Yes, that black cube thing from the bad Steve Jobs movie [Rotten Tomatoes Score of 74%—Maybe not so bad], of which 5,000 total were sold!

There are a ton of great Swift based frameworks out there, but for the foreseeable future you will still have to pull down Objective-C libraries and frameworks to get your real work done.

For so many tasks, nothing can substitute an Objective-C, C, C++ based approach due to the need to go ‘to the metal’ for memory management. Being able to go ‘to the metal’ lets you get the best out of pure native APIs like OpenGL, CoreAudio, and the Accelerate Framework. I don’t doubt that someday Swift will be optimal when used at those layers too, but for now the code samples and libraries that maximize certain kinds of apps are still rooted in Objective-C, C, or C++.

The great thing that Apple has done with the iOS tooling is the seamless way a single app can contain Objective-C, C, C++, and Swift code all mixed together in a single project. This is a great development story, and an amazing technological feat.

There are whole swaths of APIs within CocoaTouch / UIKit which are easier to use in Swift if you know how to exercise them in Objective-C. There is a reason that Apple’s Using Swift with Cocoa and Objective-C (Swift 2.2) reference is 81 pages long (and also well worth reading from front to back).

From the Fringe- NSClassFromString – Using Swift from Objective-C

In a recent project I wanted to use a Swift based class as a transplant into some legacy Objective-C code. The Swift class had to be instantiated using the NSClassFromString call.

I did what anyone would do, revved up my Swift class within my Objective-C project. Then tried to call NSClassFromString(“MyCoolSwiftClass”)

It didn’t work.

Well after Googling and a series of Stack Overflow articles, I stumbled onto a function and reference code that properly takes your Swift class name and makes it work via NSClassFromString.

According to Apple’s Using Swift with Cocoa and Objective-C (Swift 2.2) reference you have to include the app name into the string to use it. So NSClassFromString(“MyApp.MyCoolSwiftClass”) is the way to go.

Unfortunately, the journey doesn’t stop there. It still didn’t work.

The project I was working on had multiple build configurations, and the app name would change depending on the build configuration. So after much sadness and gnashing of teeth, I stumbled onto this Objective-C helper function thanks to Kevin Delord on Stack Overflow:

- (Class)swiftClassFromString:(NSString *)className {
    NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];

    NSString *classStringName = [NSString stringWithFormat:@"_TtC%d%@%d%@", appName.length,  appName, className.length, className];

    return NSClassFromString(classStringName);
}

In Objective-C we have to go and parse out the bundle name from the main app bundle, and append that with the Swift class name in order to use our shiny new Swift class within our legacy code.

In all honesty, I don’t know what happens if you try to instantiate a Swift class that was brought in via a Framework (most likely via Carthage). The above code may not work because we are just looking at the main bundle name, not the Framework bundle name. Further investigation is needed here.

This won’t be the last time that I will need to know Objective-C in order to really use Swift effectively. Many more examples exist, and many future examples will be created, as the Swift language continues to evolve and Objective-C slowly dissolves. We are already starting to see cracks showing up in the Swift and Objective-C interoperability story via the ongoing discussions of dynamism and the Application Binary Interface (ABI).

Mix / Match of Objective-C and Swift in the same project

I am going to seek to summarize Apple’s great developer documentation in the Mix and Match section of the Using Swift with Cocoa and Objective-C (Swift 2.2) iBook.

To use Swift classes in your Objective-C files the compiler will generate a header named:

YourAppName-Swift.h

At the top of your Objective-C .m files you #import this file to use your Swift classes within Objective-C:

#import <YourAppName-Swift.h>

To use Objective-C classes in your Swift code the compiler will automatically include all headers you add to the Swift bridging header file:

YourAppName-Bridging-Header.h

You do not need to import anything within your Swift code as the bridging header will take care of all class bridging from the #import(ed) Objective-C headers for you.

The 2 header files mentioned above are part of the Build Settings of your main app project.

The file name that you add Objective-C header #import(s) to so you can use Objective-C classes in Swift code:

  • Swift Compiler – Code Generation
    • Objective-C Bridging Header

The file name that you #import into Objective-C  files in order to use Swift types:

  • Swift Compiler – Code Generation
    • Objective-C Generated Interface Header Name

To use Frameworks that are referenced at the project level within your Swift code you do need to import the Framework by name at the top of your Swift file.

For example:

In the links at the top of the article I recommend the Decodable framework to translate JSON into populated Swift structs.

To use Decodable within Swift code you need to include the Framework within your project and you also have to import the Decodable framework at the top of your Swift file:

import Decodable

Good Luck!

In general, if you are starting an iOS application from scratch, and you have made the decision to go pure native with Xcode based tooling, I highly recommend learning Swift and using it from the start. Your software quality will be awesome from day 1 as you start to internalize if .. let, optionals, completion handlers, and other ‘Swifty’ techniques of doing things.

You lose nothing by starting your new application in Swift because you can always mix/match Objective-C, C, and C++ as needed throughout the development cycle.

In your existing application, I would start to try out Swift for certain non-essential components and ramp up Swift usage as your knowledge, the language, and tooling matures. I have started using Swift for wrappers around legacy Objective-C based static libraries, to standard UITableViewController implementations, and to simplify JSON to struct processing. The mix / match nature of Swift to existing Objective-C code is seamless and stable for all tasks within an existing application.

You should find that you will be writing much less code, getting more done, at a high stability level, with Swift within the first couple of weeks. The clarity and readability of your code should also be much higher as you fall into the groove of using the Swift language.

Swift really is the future of iOS and Mac OS X app development. The time is now to start learning and improving your Swift skills.

Adding Amazon Alexa Voice Services to Your iOS App with Swift

Major thanks to the MacLexa project out on Github for providing motivation, source code, and a great starting place for this blog post.

secure

Amazon Echo is an always listening device which acts as an always available assistant. Thanks to the deep integrations that the Amazon Echo has to online services you can issue a wide variety of questions and commands via voice and get real world responses.

Once your Amazon Echo is setup it is always listening for commands. The key word being listened for is “Alexa”. For example: “Alexa, play Taylor Swift.” If you have an Amazon Music account, and you have purchased Taylor Swift songs (who doesn’t have the 1989 album by this point?), then your Amazon Echo will start playing Taylor Swift.

Notice that I used “Alexa” as a prefix in the above audio command. Saying “Alexa” to an Amazon Echo is the trigger word. It is like saying “Hey Siri” to your iPhone, “OK, Google” to your Android Phone, or “Xbox” to your Xbox, then issuing a voice command. Once you have spoken “Alexa” the Amazon Echo device will record the rest of your voice command and relay it to Amazon’s Alexa Voice Service which will take specific actions and return a response from Amazon.

The Alexa Voice Service has another trick up its sleeve: Skills. Third-parties can create a Skill using Amazon’s Alexa Skills Kit which can extend the Alexa Voice Service via additional service integrations.

  • Fidelity has created a stock value skill that allows you to get answers to questions about values on the stock market. Once you have activated the Fidelity stock skill for your Amazon login via an Android or iOS app, then you can ask Alexa: “What is the value of Microsoft stock?” and get back an answer via the Fidelity stock skill.
  • There is a skill called Yonomi that integrates with Phillips Hue lightbulbs. It allows you to change the color of your lights with a voice command, so you could flood the room with red light whenever you say: “Alexa, set lights to ‘Game of Thrones’ mode.”
  • Of course, you can also buy stuff from Amazon. Just say: “Alexa, buy me some Moon Cheese” If you are an Amazon Prime subscriber, and you have already ordered Moon Cheese, it will be ordered automatically and FedEx will deliver it to your doorstep in 2 days or less (or the same day if you have Amazon Prime Now).
  • If you have a Spotify subscription, you can configure Alexa to integrate with the Spotify Skill and issue voice commands to playback all the music you can stream from that service.

Let’s review all the terms in this Amazon voice control and audio device realm:

  • Echo — The always-on, standalone device that listens and responds to voice commands.
  • Alexa — The keyword that the Amazon Echo uses to determine when a voice command is being listened for. It is also the brand name for the back-end voice services.
  • Alexa Voice Service — The backend service that receives voice commands and delivers audio responses to voice commands.
  • Skill — A third party add-on to handle special voice commands.
  • Alexa Skills Kit — The collection of APIs and resources developers use to create skills.

 

iOS App Integration of the Alexa Voice Service

The Amazon Echo is an interesting device, however, I have an iPhone that has a perfectly good microphone + speaker combination in it. Lets integrate Amazon’s Alexa Voice Service (AVS) directly within an iOS app.

Why would you want to do this kind of in-app Alexa Voice Service integration?

  • It is just plain fun to see this actually work.
  • It is an interesting in-iOS-app stop gap that addresses the limitations of SiriKit’s intent domains for your specific app type.
  • Promote and do in-app integration of your own custom AVS Skill.
  • Get insight into Amazon’s web API design methodology.

Side Note: Not to be underestimated is the amazing configurability that Cortana allows app developers for Windows 10 Universal Windows Platform apps. However, Cortana integration and LUIS are topics for a different Blog post.

Let’s go through the steps needed to perform AVS integration within your native iOS app.

If you have a Mac and want to try out Alexa Voice Services + Skills on your Mac right now check out MacLexa.

There is a 4 step in-app procedure to follow for integrating the Alexa Voice Service into your iOS application:

  • Authorize the app via Login with Amazon and retrieve an Access Token.
    • This requires a user account with Amazon.
    • It is used to associate future Alexa Voice Service requests with the Alexa settings that any Amazon user has setup on their own personal Amazon account.
    • This step also lets your in-app Alexa integration fully work with any Skills that are associated to an Alexa + Amazon account via Amazon’s Alexa configuration apps.
  • Record audio from the device microphone and store it locally to your app.
  • HTTP POST the Access Token and the audio from the device microphone to the Alexa Voice Service.
  • Playback Alexa’s voice response audio which is returned raw from the Alexa Voice Service.

 

amazon-voice-services

Sample Source Code

Feel free to pull from my AlexaVoiceIntegration Github repo for a full working sample. (Sorry, it is still in Swift 2.3)

The most fun chunk of code is the upload function which performs the upload to AVS and the playback of the Alexa voice response.

 

Registration of your Alexa Voice Service app integration with Amazon Developer Portal

In order for your app to integrate with Alexa Voice Services you need to go to the Amazon Developer Portal and get certain specific keys:

  • Application Type ID
  • Bundle Id
  • API Key

To get started:

The end goal for the in-app Alexa startup procedure is to get an access token string that we can send via HTTP to the Alexa Voice Service API.

We get the access token by using the LoginWithAmazon.framework for iOS feeding in the Application Type IDBundle Id, and API Key values you will configure and generate on the Amazon Developer Portal.

From your Amazon Developer Portal / Alexa configuration you need the following values:

  • Application Type ID from your created Alexa Application / Application Type Info section
    • ApplicationTypeID
  • API Key and Bundle Id pair that you will create in the Alexa Application / Security Profile / iOS Settings area
    • iOSSettings

Be sure to keep track of the Application Type ID, API Key, and Bundle Id. We are going to need these later on when we setup our iOS app.

 

iOS code and Xcode project setup to use the LoginWithAmazon.framework from Swift

Start by going through Amazon’s documented steps to get the LoginWithAmazon.framework file.

What follows is a fairly standard way of using a standard iOS framework within an existing Xcode project.

Copy the LoginWithAmazon.framework file to a folder within your iOS Xcode project.

Open Xcode and go to your iOS project General settings:

XcodeConfig

In the Embedded Binaries section press the + button.

Navigate the file chooser to where you copied the LoginWithAmazon.framework bundle. Press OK.

You should see something like the above where the LoginWithAmazon.framework file is in the Embedded Binaries and Linked Frameworks and Libraries section.

To fix an app deployment bug with the framework go to the Build Phases section and ensure that the Copy only when installing checkbox is checked:

CopyOnlyWhenInstalling

The final step is to ensure that the master header from the LoginWithAmazon.framework is included in your Objective-C to Swift bridge header file.

If you already have an Objective-C to Swift bridge header file, then include the following line:

#import “LoginWithAmazon/LoginWithAmazon.h”

If you do not have a bridge header file, then you need to configure your Xcode project with an Objective-C to Swift bridge header, then include the above line in it.

See also the official Swift and Objective-C in the Same Project documentation provided by Apple.

Test to see if all this worked:

  • Get a clean build of your app.
  • Go into a Swift source file and use the standard auto-complete to try and access the AIMobileLib static class.
    • The auto-complete should present the list of functions you can call.

 

Configure your app with the API Key, Bundle Id, and Application Type ID from the Amazon Developer Portal

First up is to ensure that Bundle Id, API Key, and other values are properly configured in your Info.plist and application.

Open up your app’s Info.plist within Xcode:

AmazonInfoPList

 

Bundle identifier

Whoa, that’s a lot of weirdness with $(…) stuff.

As you can see the core of our needed Login With Amazon values is the value of $(PRODUCT_BUNDLE_IDENTIFIER).

The value for $(PRODUCT_BUNDLE_IDENTIFIER) comes from your General project setting page within Xcode:

BundleIdentifier

The above value in the Bundle Identifier field has to match the Bundle Id value from the Amazon Developer Portal.

If the Bundle Ids don’t match, then it is easy to go back to the Amazon Developer Portal and add a new value. Just be sure to track the right API Key and Application Type Id with the updated Bundle Id.

 

URL Types in Info.plist 

The LoginWithAmazon.framework file uses an in-app UIWebView to handle user login scenarios.

Part of those login scenarios involve the UIWebView needing to navigate or redirect to a URL on login success / failure scenarios.

The redirect URL used is generated by the LoginWithAmazon.framework using your Bundle Id as a seed.

When the login result redirect happens within the UIWebView during login the main AppDelegate – openURL function is called in your app.

This boilerplate Swift implementation ensures that openURL portion of the login procedure properly routes through the LoginWithAmazon.framework file to call back on all the properly setup delegates:

 func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool 
{
   return AIMobileLib.handleOpenURL(url, sourceApplication: sourceApplication)
}

Debugging Tip: If you place a breakpoint on the above function and it is never hit during the login procedure, then you have a misconfigured Info.plist –> URL Types area.

App Transport Security Settings

The settings shown above are the most liberal and allow all HTTP traffic from within the process to be sent. To really lock this down, you should follow Amazon’s instructions which only allow requests to be sent from your app to specific Amazon domains.

API Key

The API Key entry within the Info.plist is read up and processed by the LoginWithAmazon.framework to get all the right IDs for all the requests (i.e. Client ID, and others). The API Key has to 100% match what the Amazon Developer Portal provided. It will be a fairly huge blob of text, and that is OK.

 

Config is now done! Woo hoo! Let’s login with AIMobileLib

ViewController.swift up on my Github repo shows how login will all come together.

The AIMobileLib is your static gateway provided by the LoginWithAmazon.framework.

Side note: I have ‘Swiftified’ my calls into LoginWithAmazon.framework by using an AIAuthenticationEventHandler wrapper class that implements the AIAuthenticationDelegate and bridges the delegate calls to closures.

The call chain to AIMobileLib to successfully login to Amazon:

  • clearAuthorizationState – Clear out any stored tokens and values.
    • authorizeUserForScopes – Pops a web view, user logs in, retrieves an authorization token.
      • getAccessTokenForScopes – Takes all the cookies and keychain stored values from authorizeUserForScopes and retrieves the access token.
        • We then use the access token in calls to the Alexa Voice Service.

In this sample I chose to clear out any stored tokens and values by using the clearAuthorizationState function on every run.

AIMobileLib.clearAuthorizationState(AIAuthenticationEventHandler(
            name: "Clear Or Logout",
            fail: {() -> Void in
                NSLog("Clear Or Logout Fail")
            },
            success: {(result : APIResult!) -> Void in
                NSLog("Clear Or Logout Success")
        }));

 

Now that all tokens / cookies have been cleared, let’s have the user login via authorizeUserForScopes.

Finally, we are at the location where we need to use that Application Type Id from the Amazon Developer Portal.

We need to feed in the Application Type Id from the Amazon Developer Portal into the option scope JSON:

 let options = [kAIOptionScopeData: "{\"alexa:all\":{\"productID\":\"Application Product Id\",
 \"productInstanceAttributes\": {\"deviceSerialNumber\":\"1234567890\"}}}"]
       

Note: kAIOptionScopeData key value comes from the LoginWithAmazon.framework headers.

 

When authorizeUserForScopes is successful we then turn around and call the getAccessTokenForScopes function.

When getAccessTokenForScopes is successful we now have the access token string we can use in pure calls to the Alexa Voice Service.

 

We have the access token!  Let’s call into that Alexa Voice Service.

The Alexa Voice Service makes sending voice commands, and receiving voice responses, a very straight forward process:

  • Record the user’s question as sound data from the microphone as PCM data.
  • Send an HTTP POST request to the Alexa Voice Service that contains the sound data.
  • In the response to the HTTP POST will be the sound data to playback to the user which answers their question.

The Alexa Voice Service calls are all handled within the AVSUploader class.

  • startUpload – The master function that manages the upload process. Takes in completion handlers for success / failure.
    • start – Just a general internal helper function, checks parameters and other cleanup.
      • postRecording – Manages an HTTP POST operation to the Alexa Voice Service using the access token, some boilerplate JSON, and the raw PCM data recorded from the device microphone.
    • When postRecording is successful, the completion handler fed into startUpload will be called.
      • A parameter to the success completion handler is the raw PCM sound data (in the form of NSData) from the Alexa Voice Service that contains the voice response for the recorded user command.

The PCM sound data returned from the Alexa Voice Service can then be played through an AVAudioPlayer (From ViewController.swift):

self.player = try AVAudioPlayer(data: audioData)
self.player?.play()

 

Go out and play… and also take a look at making your own Skill

The sample Swift code to access the Alexa Voice Services is just meant to get you started. It allows you to have some level of control in how Alexa Voice Services are accessed and used within your own app. It can also be used to test any Skills you choose to integrate with your Amazon profile without needing an Amazon Echo device.

The techniques outlined above can also be fully replicated for any other other native device, platform, or front end.