AWS Full Stack Swift with Apple CarPlay

Overview

AWS Full Stack Swift with Apple CarPlay

This application demonstrates a full-stack Apple CarPlay app that uses Swift for both the UI and the backend services in AWS. The app implements the latest features of AWS Lambda that allow you to develop and deploy functions written in Swift as Docker images.

This is important as it allows frontend developers who are proficient in Swift to leverage their skills in building out the backend of their applications. It also enables an entire geneation of Swift engineers to build apps on AWS using their language of choice.

This sample app is useful for iOS/CarPlay developers learning how to interact with backend services running on AWS. It is also beneficial for customers who want to build their backend infrastructure using Swift, regardless if there is an iOS front end component. Explore the CDK portion of this project to discover how to build and deploy Swift based Lambda functions to AWS.

Image description

The application tracks the user's current location and displays the current weather, air quality, and nearby points of interest such as coffee, food, and fuel. The app also allows you to send messages from the AWS Cloud to the app which are displayed in real-time to the user.

Architecture

Image description

  1. The Apple CarPlay app is written in Swift and uses AWS Amplify libraries to communicate with services in the AWS Cloud.
  2. All data is served to the client application via an AWS AppSync GraphQL API. As the client changes its location, queries are sent via the API to obtain weather, air quality, and points of interest in the vicinity of the user.
  3. The AWS AppSync GraphQL API uses Lambda functions written in Swift to interact with Amazon Location Service for points of interest. It also communicates with a 3rd party API outside of AWS for weather and air quality. The API key for the 3rd party weather service is stored in AWS Secrets Manager.
  4. The client establishes a subscription to AWS AppSync to receive real-time notifications triggered from the cloud. These messages are also stored in an Amazon DynamoDB table.

At the time of creating this sample AWS does not have an official Swift SDK. For this project we used the open source SOTO SDK in the Lambda functions to interact with AWS Services.

Getting Started

Prerequisites

The following software was used in the development of this application. While it may work with alternative versions, we recommend you deploy the specified minimum version.

  1. An AWS account in which you have Administrator access.

  2. AWS CLI (2.1.32) the AWS Command Line Interface (CLI) is used to configure your connection credentials to AWS. These credentials are used by the CDK, Amplify, and the CLI.

  3. Node.js (^15.12.0) with NPM (^7.7.4)

  4. Typescript (^4.2.4) Typescript is required by the Cloud Development Kit (CDK) in the next step.

  5. AWS Cloud Development Kit (CDK) (1.98.0). The CDK is used to deploy the Swift based Lambda functions to AWS.

  6. Amplify CLI (^4.47.1) Amplify is used to create the AWS AppSync API and generate the client side Swift code to interact with AWS.

  7. IQ Air is a 3rd party API used to obtain weather and air quality for a specified location. Create a free Community Edition API key.

  8. Docker Desktop (3.3.0) Docker is used to compile the Swift Lambda functions into a Docker image.

  9. Xcode (12.4) Xcode is used to build and debug the CarPlay application. You will need iOS Simulator 14.2 enabled.

Installation

The application utilizes the AWS Cloud Development Kit (CDK) and Docker to compile and deploy your Swift based Lambda functions. It also utilizes AWS Amplify to build the AppSync GraphQL API the front-end uses to receive data.

Make sure you have configured the AWS CLI prior to following these instructions as several steps assume you gave defined credentials for your default AWS account.

Clone this code repository

$ git clone [email protected]:aws-samples/aws-serverless-fullstack-swift-apple-carplay-example.git

Switch to the project's CDK folder

$ cd aws-serverless-fullstack-swift-apple-carplay-example/cdk

Install the CDK app's Node.js packages

$ npm install

Deploy the CDK project

If you have not used the CDK in your AWS account you must first bootstrap the CDK. This will configure your AWS account for interaction with the CDK.

$ cdk bootstrap

View the resources the CDK will deploy into your account:

$ cdk diff

Deploy the resources into your account. This will create 2 Lambda functions and a Secrets Manager secret. The CDK will use Docker on your local machine to compile the Lambda Function Swift code into images and push them to the Amazon Elastic Container Registry (ECR).

$ cdk synth
$ cdk deploy

When the CDK has completed the deployment, it will output the name of the Secrets Manager secret. Retain this name for a future step.

 ✅  CdkAWSStackSwiftCarplayLocation

Outputs:
CdkAWSStackSwiftCarplayLocation.aqiAPIKeySecretName = Secretxxx-xxx

Configure Secrets Manager with the IQ Air API Key

The CDK created a secret in AWS Secrets Manager to hold the IQ Air API key. Lambda will use this secret for the key to access the IQ Air API. The name of the secret was output from the cdk deploy command above. Use the AWS CLI to update the secret with the API key you obtained from the IQ Air site.

Replace the values in brackets with your values:

$ aws secretsmanager put-secret-value --secret-id [secret name from CDK output] --secret-string [your IQ Air API key]

If you forgot to record the secret name from the output of the CDK deployment, you can view the name with the following AWS CLI command. Select the "Name:" value from the output.

$ aws secretsmanager list-secrets

Create the Amazon Location Place Index

The application utilizes the Amazon Location Service to identify points of interest (Coffee, Food, and Fuel) in the vicinity of the user. To use Amazon Location you must create a Place Index with the AWC CLI.

Run this command from the command line:

$ aws location create-place-index --data-source "Esri" --index-name "SwiftCarplayLocation" --pricing-plan "RequestBasedUsage"

Initialize the CarPlay app and AWS AppSync API

Switch to the mobile folder of the application:

$ cd ../mobile

Initialize the Amplify project that will create the AppSync GraphQL API

$ amplify init

? Enter a name for the environment (dev)
? Choose your default editor: (Xcode Mac OS only)
? Select the authentication method you want to use: (AWS profile)
? Please choose the profile you want to use (default)

Amplify will then begin to provision your account for the project deployment. Once your account has been provisioned, entering the amplify status command will show you the resources Amplify will create in your account:

$ amplify status
Current Environment: dev

| Category | Resource name        | Operation | Provider plugin   |
| -------- | -------------------- | --------- | ----------------- |
| Api      | swiftcarplaylocation | Create    | awscloudformation |

Deploy the API to your AWS account

$ amplify push

? Do you want to update code for your updated GraphQL API (Y/n) N

You will then see a series of output messages as Amplify builds and deploys the app's CloudFormation templates, creating the API in your AWS account.

Resources being created in your account include:

  • AppSync GraphQL API
  • DynamoDB Table

Generate the Swift client side code and credentials:

This command will generate the Swift class and configuration files for your app to communicate with the the API.

$ amplify codegen models

Run the CarPlay app

From the mobile folder of the application open the project in Xcode:

$ open mobile.xcodeproj

Note - you can also open the project from the Xcode UI

Once the project loads in Xcode, select an iPhone simulator from the menu bar and the "Run" arrow button to start the app.

Once the iPhone app is running in the iOS Simulator, initiate a "Freeway Drive" to simulate the user driving:

Image description

As the user's location changes:

  • Select the Weather button at the bottom of the iOS app to view the weather and air quality of the current location.

  • Select the Places button to view coffee, food, and fuel locations in the vicinity of the user.

  • Select the Messages button to view messages sent to the user from the AWS Cloud. Instructions for sending messages are detailed below.

If the simulator does not display the feature to simulate a Freeway Drive, ensure Location Simulation is enabled in Xcode:

From the Xcode menu select Product -> Scheme -> Edit Scheme

Then ensure Core Location: Allow Location Simulation is checked.

Image description

Start the CarPlay simulator

From the Simulator menu select I/O -> External Displays -> CarPlay:

Image description

When the CarPlay simulator screen launches select the AWS app:

Image description

The app will display a map with the user's current location. Click the map to view the navbar buttons and select the Weather and Places buttons.

Note - when selecting a location from the Places screen (Coffee, Food, or Fuel) the screen will display a navigation alert to "Go" to that location. For this sample we have not implemented navigation functionality. That is functionality you may want to add to your version of this app.

Send a real-time message to the application from AWS

To send a message to the driver, logon to the AWS Console and navigate to the AppSync service. From there select the swiftcarplaylocation API.

From the API screen select the Run a Query button. Paste the following GraphQL mutation code into the middle query panel and click the orange Run arrow button

mutation MyMutation {
  createVehicleMessage(input: {
    message: "Pickup package", 
    owner: "Vehicle1", 
    timestamp: "2021-04-21T19:36:30.653Z"}
  ) {
    createdAt
    id
    message
    owner
    timestamp
    updatedAt
  }
}

Console screenshot:

Image description

You should see the message delivered to both the CarPlay and iPhone apps.

Cleanup

Once you are finished working with this project, you may want to delete the resources it created in your AWS account.

Delete the Amazon Location Place index:

$ aws location delete-place-index --index-name SwiftCarplayLocation

From the mobile folder delete the resources created by Amplify:

$ amplify delete

From the cdk folder delete the resources created by the CDK:

$ cdk destroy

License

This sample code is made available under a modified MIT-0 license. See the LICENSE file.

You might also like...
An Elegant Spotify Web API Library Written in Swift for iOS and macOS
An Elegant Spotify Web API Library Written in Swift for iOS and macOS

Written in Swift 4.2 Spartan is a lightweight, elegant, and easy to use Spotify Web API wrapper library for iOS and macOS written in Swift 3. Under th

An Elegant Financial Markets Library Written in Swift
An Elegant Financial Markets Library Written in Swift

Notice As of May 20th, 2017, it appears that Yahoo is dropping support for a few features that BigBoard supports or there is an outage on their end ca

Swift Wrapper For Bittrex API

BittrexApiKit Swift client for Bittrex api. It support all APIs with most recent changes. more info here let api = Bittrex(apikey: "api key", secretke

iOS/macOS Cross-platform Ark-Ecosystem Framework in Swift | Powered by Ѧrk.io |
iOS/macOS Cross-platform Ark-Ecosystem Framework in Swift | Powered by Ѧrk.io |

a macOS & iOS Swift Framework for Ark.io. What is ARKKit? ARKKit is wrapper for interacting with the Ark Ecosystem. It is written purely in Swift 4.0,

Instagram API client written in Swift
Instagram API client written in Swift

SwiftInstagram is a wrapper for the Instagram API written in Swift. It allows you to authenticate users and request data from Instagram effortlessly.

A Swift Framework build for the Ark Ecosystem
A Swift Framework build for the Ark Ecosystem

Introduction Overview SwiftyArk is a simple, lightweight framework for the Ark Ecosystem. SwiftyArk provides a simple wrapper for accessing Ark accoun

A Slack API Client for the Perfect Server-Side Swift Framework

PerfectSlackAPIClient is an API Client to access the Slack API from your Perfect Server Side Swift application. It is build on top of PerfectAPIClient

The Waterwheel Swift SDK provides classes to natively connect iOS, macOS, tvOS, and watchOS applications to Drupal 7 and 8.
The Waterwheel Swift SDK provides classes to natively connect iOS, macOS, tvOS, and watchOS applications to Drupal 7 and 8.

Waterwheel Swift SDK for Drupal Waterwheel makes using Drupal as a backend with iOS, macOS, tvOS, or watchOS enjoyable by combining the most used feat

A Swift library for the Forecast.io Dark Sky API
A Swift library for the Forecast.io Dark Sky API

Requirements To use ForecastIO, all you need is an API key for the Dark Sky API. ForecastIO supports iOS (≥9.0), macOS (≥10.10), watchOS (≥2.0), and t

Comments
  • Issue while doing deployment

    Issue while doing deployment "npx cdk deploy"

    Hello, We are getting below error while deploying the app to AWS. Please see below error log.


    #18 988.3 remark: Incremental compilation has been disabled: it is not compatible with whole module optimization[850/851] Compiling get_weather main.swift #18 988.6 /build-lambda/Sources/get-weather/main.swift:53:32: error: 'async' call in a function that does not support concurrency #18 988.6 let secretsManagerClient = try SecretsManagerClient() #18 988.6 ^ #18 988.6 /build-lambda/Sources/get-weather/main.swift:98:55: error: extra trailing closure passed in call #18 988.6 secretsManagerClient.getSecretValue(input: input) { result in #18 988.6 ^~~~~~~~~~~ #18 ERROR: executor failed running [/bin/sh -c cd /build-lambda && swift package clean && swift build -c release]: exit code: 1

    [builder 9/9] RUN cd /build-lambda && swift package clean && swift build -c release:


    executor failed running [/bin/sh -c cd /build-lambda && swift package clean && swift build -c release]: exit code: 1

    ❌ CdkAWSStackSwiftCarplayLocation failed: Error: Failed to publish one or more assets. See the error messages above for more information. at Object.publishAssets (D:\Praneeth\Learnings\CarPlay\aws-serverless-fullstack-swift-apple-carplay-example-main\cdk\node_modules\aws-cdk\lib\util\asset-publishing.ts:25:11) at Object.deployStack (D:\Praneeth\Learnings\CarPlay\aws-serverless-fullstack-swift-apple-carplay-example-main\cdk\node_modules\aws-cdk\lib\api\deploy-stack.ts:252:3) at CdkToolkit.deploy (D:\Praneeth\Learnings\CarPlay\aws-serverless-fullstack-swift-apple-carplay-example-main\cdk\node_modules\aws-cdk\lib\cdk-toolkit.ts:189:24) at initCommandLine (D:\Praneeth\Learnings\CarPlay\aws-serverless-fullstack-swift-apple-carplay-example-main\cdk\node_modules\aws-cdk\bin\cdk.ts:225:9) Failed to publish one or more assets. See the error messages above for more information.


    Could you please help us with this?

    opened by saiprp 0
Owner
AWS Samples
AWS Samples
A Swift wrapper for Foursquare API. iOS and OSX.

Das Quadrat Das Quadrat is Foursquare API wrapper written in Swift. Features Supports iOS and OSX. Covers all API endpoints. Authorization process imp

Constantine Fry 171 Jun 18, 2022
Pokeapi wrapper, written in Swift

PokemonKit What is this? PokemonKit is a swift wrapper for Pokeapi. PokemonKit use Alamofire and PromiseKit for async web requests handling. Usage imp

Continuous Learning 105 Nov 16, 2022
Unofficial GitHub API client in Swift

Github.swift ❤️ Support my apps ❤️ Push Hero - pure Swift native macOS application to test push notifications PastePal - Pasteboard, note and shortcut

Khoa 184 Nov 25, 2022
A swift SDK for Medium's OAuth2 API

Medium SDK - Swift A library to allow access to Medium API for any Swift iOS application. Features Medium.com authorization & token handling Login sta

null 11 Jan 22, 2022
A Twitter framework for iOS & OS X written in Swift

Getting Started Installation If you're using Xcode 6 and above, Swifter can be installed by simply dragging the Swifter Xcode project into your own pr

Matt Donnelly 2.4k Dec 30, 2022
Build Slack apps, in Swift

SlackKit: Slack Apps in Swift Description SlackKit makes it easy to build Slack apps in Swift. It's intended to expose all of the functionality of Sla

Peter Zignego 1k Dec 20, 2022
👤 Framework to Generate Random Users - An Unofficial Swift SDK for randomuser.me

RandomUserSwift is an easy to use Swift framework that provides the ability to generate random users and their accompanying data for your Swift applic

Wilson Ding 95 Sep 9, 2022
Swift 3 framework for accessing data in Event Registry (http://eventregistry.org/)

PPEventRegistryAPI Swift 3 framework for accessing data in Event Registry (http://eventregistry.org/) Supported API calls Log In Get Event By Identifi

Pavel Pantus 8 Nov 1, 2016
Swift client for Unsplash

Unsplash API client written in Swift. Unsplash offers 2 APIs: Source API (unlimited requests) Official API JSON API (5000 requests / hour) JSON API is

Modo 188 Nov 12, 2022
The Swift-est way to build native mobile apps that connect to Salesforce.

Swiftly Salesforce is the Swift-est way to build native mobile apps that connect to Salesforce: Written entirely in Swift. Very easy to install and up

Michael Epstein 131 Nov 23, 2022