Merge pull request #72 from swift-server/move-samples

move samples into a subdirectory
This commit is contained in:
tomer doron
2020-05-07 09:47:16 -07:00
committed by GitHub
42 changed files with 1886 additions and 7 deletions
+4 -6
View File
@@ -1,11 +1,9 @@
.DS_Store
/.build
/Packages
/*.xcodeproj
Package.pins
*.build
/.xcodeproj
*.pem
/docs
Package.resolved
.podspecs
.swiftpm
.swift-version
xcuserdata
Package.resolved
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:MyLambda">
</FileRef>
<FileRef
location = "group:MyApp/MyApp.xcodeproj">
</FileRef>
<FileRef
location = "group:README.md">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
@@ -0,0 +1,345 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
F7B6C1FE246121E800607A89 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7B6C1FD246121E800607A89 /* AppDelegate.swift */; };
F7B6C200246121E800607A89 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7B6C1FF246121E800607A89 /* SceneDelegate.swift */; };
F7B6C202246121E800607A89 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7B6C201246121E800607A89 /* ContentView.swift */; };
F7B6C204246121E900607A89 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F7B6C203246121E900607A89 /* Assets.xcassets */; };
F7B6C207246121E900607A89 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F7B6C206246121E900607A89 /* Preview Assets.xcassets */; };
F7B6C20A246121E900607A89 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7B6C208246121E900607A89 /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
F7B6C1FA246121E800607A89 /* MyApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MyApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
F7B6C1FD246121E800607A89 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
F7B6C1FF246121E800607A89 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
F7B6C201246121E800607A89 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
F7B6C203246121E900607A89 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
F7B6C206246121E900607A89 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
F7B6C209246121E900607A89 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
F7B6C20B246121E900607A89 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
F7B6C1F7246121E800607A89 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
F7B6C1F1246121E800607A89 = {
isa = PBXGroup;
children = (
F7B6C1FC246121E800607A89 /* MyApp */,
F7B6C1FB246121E800607A89 /* Products */,
);
sourceTree = "<group>";
};
F7B6C1FB246121E800607A89 /* Products */ = {
isa = PBXGroup;
children = (
F7B6C1FA246121E800607A89 /* MyApp.app */,
);
name = Products;
sourceTree = "<group>";
};
F7B6C1FC246121E800607A89 /* MyApp */ = {
isa = PBXGroup;
children = (
F7B6C1FD246121E800607A89 /* AppDelegate.swift */,
F7B6C1FF246121E800607A89 /* SceneDelegate.swift */,
F7B6C201246121E800607A89 /* ContentView.swift */,
F7B6C203246121E900607A89 /* Assets.xcassets */,
F7B6C208246121E900607A89 /* LaunchScreen.storyboard */,
F7B6C20B246121E900607A89 /* Info.plist */,
F7B6C205246121E900607A89 /* Preview Content */,
);
path = MyApp;
sourceTree = "<group>";
};
F7B6C205246121E900607A89 /* Preview Content */ = {
isa = PBXGroup;
children = (
F7B6C206246121E900607A89 /* Preview Assets.xcassets */,
);
path = "Preview Content";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
F7B6C1F9246121E800607A89 /* MyApp */ = {
isa = PBXNativeTarget;
buildConfigurationList = F7B6C20E246121E900607A89 /* Build configuration list for PBXNativeTarget "MyApp" */;
buildPhases = (
F7B6C1F6246121E800607A89 /* Sources */,
F7B6C1F7246121E800607A89 /* Frameworks */,
F7B6C1F8246121E800607A89 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = MyApp;
productName = MyApp;
productReference = F7B6C1FA246121E800607A89 /* MyApp.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
F7B6C1F2246121E800607A89 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1140;
LastUpgradeCheck = 1140;
ORGANIZATIONNAME = "Tom Doron";
TargetAttributes = {
F7B6C1F9246121E800607A89 = {
CreatedOnToolsVersion = 11.4.1;
};
};
};
buildConfigurationList = F7B6C1F5246121E800607A89 /* Build configuration list for PBXProject "MyApp" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = F7B6C1F1246121E800607A89;
productRefGroup = F7B6C1FB246121E800607A89 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
F7B6C1F9246121E800607A89 /* MyApp */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
F7B6C1F8246121E800607A89 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F7B6C20A246121E900607A89 /* LaunchScreen.storyboard in Resources */,
F7B6C207246121E900607A89 /* Preview Assets.xcassets in Resources */,
F7B6C204246121E900607A89 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
F7B6C1F6246121E800607A89 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F7B6C1FE246121E800607A89 /* AppDelegate.swift in Sources */,
F7B6C200246121E800607A89 /* SceneDelegate.swift in Sources */,
F7B6C202246121E800607A89 /* ContentView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
F7B6C208246121E900607A89 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
F7B6C209246121E900607A89 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
F7B6C20C246121E900607A89 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
F7B6C20D246121E900607A89 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
F7B6C20F246121E900607A89 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "\"MyApp/Preview Content\"";
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = MyApp/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.apple.swift.MyApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
F7B6C210246121E900607A89 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "\"MyApp/Preview Content\"";
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = MyApp/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.apple.swift.MyApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
F7B6C1F5246121E800607A89 /* Build configuration list for PBXProject "MyApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F7B6C20C246121E900607A89 /* Debug */,
F7B6C20D246121E900607A89 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F7B6C20E246121E900607A89 /* Build configuration list for PBXNativeTarget "MyApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F7B6C20F246121E900607A89 /* Debug */,
F7B6C210246121E900607A89 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = F7B6C1F2246121E800607A89 /* Project object */;
}
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1140"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F7B6C1F9246121E800607A89"
BuildableName = "MyApp.app"
BlueprintName = "MyApp"
ReferencedContainer = "container:MyApp.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F7B6C1F9246121E800607A89"
BuildableName = "MyApp.app"
BlueprintName = "MyApp"
ReferencedContainer = "container:MyApp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F7B6C1F9246121E800607A89"
BuildableName = "MyApp.app"
BlueprintName = "MyApp"
ReferencedContainer = "container:MyApp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,37 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
@@ -0,0 +1,98 @@
{
"images" : [
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
@@ -0,0 +1,79 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import SwiftUI
struct ContentView: View {
@State var name: String = "World"
@State var response: String = ""
var body: some View {
VStack(alignment: .leading, spacing: 20) {
TextField("Enter your name", text: $name)
Button(
action: self.sayHello,
label: {
Text("say hello")
.padding()
.foregroundColor(.white)
.background(Color.black)
.border(Color.black, width: 2)
}
)
Text(response)
.foregroundColor(response.starts(with: "CommunicationError") ? .red : .black)
}.padding(100)
}
func sayHello() {
guard let url = URL(string: "http://localhost:7000/invoke") else {
fatalError("invalid url")
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = self.name.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
do {
if let error = error {
throw CommunicationError(reason: error.localizedDescription)
}
guard let httpResponse = response as? HTTPURLResponse else {
throw CommunicationError(reason: "invalid response, expected HTTPURLResponse")
}
guard httpResponse.statusCode == 200 else {
throw CommunicationError(reason: "invalid response code: \(httpResponse.statusCode)")
}
guard let data = data else {
throw CommunicationError(reason: "invald response, empty body")
}
self.response = String(data: data, encoding: .utf8)!
} catch {
self.response = "\(error)"
}
}
task.resume()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct CommunicationError: Error {
let reason: String
}
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,65 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import SwiftUI
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView()
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
func sceneDidDisconnect(_: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}
@@ -0,0 +1 @@
.build
@@ -0,0 +1,3 @@
FROM swiftlang/swift:nightly-master-amazonlinux2
RUN yum -y install git zip
@@ -0,0 +1,26 @@
// swift-tools-version:5.2
import PackageDescription
let package = Package(
name: "MyLambda",
platforms: [
.macOS(.v10_13),
],
products: [
.executable(name: "MyLambda", targets: ["MyLambda"]),
],
dependencies: [
// this is the dependency on the swift-aws-lambda-runtime library
// in real-world projects this would say
// .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", from: "1.0.0")
.package(name: "swift-aws-lambda-runtime", path: "../../.."),
],
targets: [
.target(
name: "MyLambda", dependencies: [
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
]
),
]
)
@@ -0,0 +1,21 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import AWSLambdaRuntime
try Lambda.withLocalServer {
Lambda.run { (_: Lambda.Context, payload: String, callback: @escaping (Result<String, Error>) -> Void) in
callback(.success("Hello, \(payload)!"))
}
}
@@ -0,0 +1,15 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
preconditionFailure("use `swift test --enable-test-discovery`")
+65
View File
@@ -0,0 +1,65 @@
#!/bin/bash
##===----------------------------------------------------------------------===##
##
## This source file is part of the SwiftAWSLambdaRuntime open source project
##
## Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
## Licensed under Apache License v2.0
##
## See LICENSE.txt for license information
## See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
##
## SPDX-License-Identifier: Apache-2.0
##
##===----------------------------------------------------------------------===##
set -eu
lambda_name=SwiftSample
s3_bucket=swift-lambda-test
executables=( $(swift package dump-package | sed -e 's|: null|: ""|g' | jq '.products[] | (select(.type.executable)) | .name' | sed -e 's|"||g') )
if [[ ${#executables[@]} = 0 ]]; then
echo "no executables found"
exit 1
elif [[ ${#executables[@]} = 1 ]]; then
executable=${executables[0]}
elif [[ ${#executables[@]} > 1 ]]; then
echo "multiple executables found:"
for executable in ${executables[@]}; do
echo " * $executable"
done
echo ""
read -p "select which executables to deploy: " executable
fi
echo -e "\ndeploying $executable"
echo "-------------------------------------------------------------------------"
echo "preparing docker build image"
echo "-------------------------------------------------------------------------"
docker build . -t builder
echo "-------------------------------------------------------------------------"
echo "building \"$executable\" lambda"
echo "-------------------------------------------------------------------------"
docker run --rm -v `pwd`/../../..:/workspace -w /workspace builder \
bash -cl "cd Examples/EndToEndDebugging/MyLambda &&
swift build --product $executable -c release -Xswiftc -g"
echo "done"
echo "-------------------------------------------------------------------------"
echo "packaging \"$executable\" lambda"
echo "-------------------------------------------------------------------------"
docker run --rm -v `pwd`:/workspace -w /workspace builder bash -cl "./scripts/package.sh $executable"
echo "-------------------------------------------------------------------------"
echo "uploading \"$executable\" lambda to s3"
echo "-------------------------------------------------------------------------"
aws s3 cp .build/lambda/$executable/lambda.zip s3://$s3_bucket/
echo "-------------------------------------------------------------------------"
echo "updating \"$lambda_name\" to latest \"$executable\""
echo "-------------------------------------------------------------------------"
aws lambda update-function-code --function $lambda_name --s3-bucket $s3_bucket --s3-key lambda.zip
+27
View File
@@ -0,0 +1,27 @@
#!/bin/bash
##===----------------------------------------------------------------------===##
##
## This source file is part of the SwiftAWSLambdaRuntime open source project
##
## Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
## Licensed under Apache License v2.0
##
## See LICENSE.txt for license information
## See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
##
## SPDX-License-Identifier: Apache-2.0
##
##===----------------------------------------------------------------------===##
set -eu
executable=$1
target=.build/lambda/$executable
rm -rf "$target"
mkdir -p "$target"
cp ".build/release/$executable" "$target/"
cp -Pv /usr/lib/swift/linux/lib*so* "$target"
cd "$target"
ln -s "$executable" "bootstrap"
zip --symlinks lambda.zip *
+8
View File
@@ -0,0 +1,8 @@
# End-To-End Debugging
This sample project demonstrates how to write a simple Lambda function in Swift,
and how to use local debugging techniques that emulate how the Lambda function
would be invoked by the AWS Lambda Runtime engine.
The sample also includes a simple iOS application that calls the Lambda function
through the emulator, providing an end-to-end debugging experience.
+1
View File
@@ -0,0 +1 @@
.build
@@ -0,0 +1,33 @@
AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: A sample SAM template for deploying Lambda functions.
Resources:
# APIGateway Function
apiGatewayFunction:
Type: AWS::Serverless::Function
Properties:
Handler: Provided
Runtime: provided
CodeUri: .build/lambda/APIGateway/lambda.zip
# Add an API Gateway event source for the Lambda
Events:
HttpGet:
Type: Api
Properties:
RestApiId: !Ref lambdaApiGateway
Path: '/samples/apig'
Method: get
# Instructs new versions to be published to an alias named "live".
AutoPublishAlias: live
lambdaApiGateway:
Type: AWS::Serverless::Api
Properties:
Name: Lambda API Gateway
StageName: Beta
Outputs:
LambdaApiGatewayEndpoint:
Description: 'API Gateway endpoint URL.'
Value: !Sub 'https://${lambdaApiGateway}.execute-api.${AWS::Region}.amazonaws.com/Beta/samples/apig'
@@ -0,0 +1,14 @@
AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: A sample SAM template for deploying Lambda functions.
Resources:
# Benchmark Function
benchmarkFunction:
Type: AWS::Serverless::Function
Properties:
Handler: Provided
Runtime: provided
CodeUri: .build/lambda/Benchmark/lambda.zip
# Instructs new versions to be published to an alias named "live".
AutoPublishAlias: live
@@ -0,0 +1,15 @@
AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: A sample SAM template for deploying Lambda functions.
Resources:
# CurrencyExchange Function
currencyExchangeFunction:
Type: AWS::Serverless::Function
Properties:
Handler: Provided
Runtime: provided
CodeUri: .build/lambda/CurrencyExchange/lambda.zip
Timeout: 300
# Instructs new versions to be published to an alias named "live".
AutoPublishAlias: live
+3
View File
@@ -0,0 +1,3 @@
FROM swiftlang/swift:nightly-master-amazonlinux2
RUN yum -y install git zip
@@ -0,0 +1,14 @@
AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: A sample SAM template for deploying Lambda functions.
Resources:
# ErrorHandling Function
errorHandlingFunction:
Type: AWS::Serverless::Function
Properties:
Handler: Provided
Runtime: provided
CodeUri: .build/lambda/ErrorHandling/lambda.zip
# Instructs new versions to be published to an alias named "live".
AutoPublishAlias: live
@@ -0,0 +1,14 @@
AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: A sample SAM template for deploying Lambda functions.
Resources:
# HelloWorld Function
helloWorldFunction:
Type: AWS::Serverless::Function
Properties:
Handler: Provided
Runtime: provided
CodeUri: .build/lambda/HelloWorld/lambda.zip
# Instructs new versions to be published to an alias named "live".
AutoPublishAlias: live
+45
View File
@@ -0,0 +1,45 @@
// swift-tools-version:5.2
import PackageDescription
let package = Package(
name: "swift-aws-lambda-runtime-samples",
platforms: [
.macOS(.v10_13),
],
products: [
// introductory example
.executable(name: "HelloWorld", targets: ["HelloWorld"]),
// good for benchmarking
.executable(name: "Benchmark", targets: ["Benchmark"]),
// demonstrate different types of error handling
.executable(name: "ErrorHandling", targets: ["ErrorHandling"]),
// demostrate how to integrate with AWS API Gateway
.executable(name: "APIGateway", targets: ["APIGateway"]),
// fully featured example with domain specific business logic
.executable(name: "CurrencyExchange", targets: ["CurrencyExchange"]),
],
dependencies: [
// this is the dependency on the swift-aws-lambda-runtime library
// in real-world projects this would say
// .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", from: "1.0.0")
.package(name: "swift-aws-lambda-runtime", path: "../.."),
],
targets: [
.target(name: "HelloWorld", dependencies: [
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
]),
.target(name: "Benchmark", dependencies: [
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
]),
.target(name: "ErrorHandling", dependencies: [
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
]),
.target(name: "APIGateway", dependencies: [
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
]),
.target(name: "CurrencyExchange", dependencies: [
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
]),
]
)
+81
View File
@@ -0,0 +1,81 @@
# Lambda Functions Examples
This sample project is a collection of Lambda functions that demonstrates
how to write a simple Lambda function in Swift, and how to package and deploy it
to the AWS Lambda platform.
## Deployment instructions using AWS CLI
Steps to deploy this sample to AWS Lambda using the AWS CLI:
1. Login to AWS Console and create an AWS Lambda with the following settings:
* Runtime: Custom runtime
* Handler: Can be any string, does not matter in this case
2. Build, package and deploy the Lambda
```
./scripts/deploy.sh
```
Note: This script assumes you have AWS CLI installed and credentials setup in `~/.aws/credentials`.
### Deployment instructions using AWS SAM (Serverless Application Model)
AWS [Serverless Application Model](https://aws.amazon.com/serverless/sam/) (SAM) is an open-source framework for building serverless applications. This framework allows you to easily deploy other AWS resources and more complex deployment mechanisms such a CI pipelines.
***Note:*** Deploying using SAM will automatically create resources within your AWS account. Charges may apply for these resources.
To use SAM to deploy this sample to AWS:
1. Install the AWS CLI by following the [instructions](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html).
2. Install SAM CLI by following the [instructions](https://aws.amazon.com/serverless/sam/).
3. Build, package and deploy the Lambda
```
./scripts/sam-deploy.sh --guided
```
The script will ask you which sample Lambda you wish to deploy. It will then guide you through the SAM setup process.
```
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]: swift-aws-lambda-runtime-sample
AWS Region [us-east-1]: <your-favourite-region>
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [y/N]: Y
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]: Y
Save arguments to samconfig.toml [Y/n]: Y
```
If you said yes to confirm changes, SAM will ask you to accept changes to the infrastructure you are setting up. For more on this, see [Cloud Formation](https://aws.amazon.com/cloudformation/).
The `sam-deploy` script passes through any parameters to the SAM deploy command.
4. Subsequent deploys can just use the command minus the `guided` parameter:
```
./scripts/sam-deploy.sh
```
The script will ask you which sample Lambda you wish to deploy. If you are deploying a different sample lambda, the deploy process will pull down the previous Lambda.
SAM will still ask you to confirm changes if you said yes to that initially.
5. Testing
For the API Gateway sample:
The SAM template will provide an output labelled `LambdaApiGatewayEndpoint` which you can use to test the Lambda. For example:
```
curl <<LambdaApiGatewayEndpoint>>
```
***Warning:*** This SAM template is only intended as a sample and creates a publicly accessible HTTP endpoint.
For all other samples use the AWS Lambda console.
@@ -0,0 +1,85 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import AWSLambdaRuntime
import NIO
// MARK: - Run Lambda
Lambda.run(APIGatewayProxyLambda())
// MARK: - Handler, Request and Response
// FIXME: Use proper Event abstractions once added to AWSLambdaRuntime
struct APIGatewayProxyLambda: EventLoopLambdaHandler {
public typealias In = APIGatewayRequest
public typealias Out = APIGatewayResponse
public func handle(context: Lambda.Context, payload: APIGatewayRequest) -> EventLoopFuture<APIGatewayResponse> {
context.logger.debug("hello, api gateway!")
return context.eventLoop.makeSucceededFuture(APIGatewayResponse(statusCode: 200,
headers: nil,
multiValueHeaders: nil,
body: "hello, world!",
isBase64Encoded: false))
}
}
struct APIGatewayRequest: Codable {
let resource: String
let path: String
let httpMethod: String?
let headers: [String: String]?
let multiValueHeaders: [String: [String]]?
let queryStringParameters: [String: String]?
let multiValueQueryStringParameters: [String: [String]]?
let pathParameters: [String: String]?
let stageVariables: [String: String]?
let requestContext: Context?
let body: String?
let isBase64Encoded: Bool?
struct Context: Codable {
let accountId: String?
let resourceId: String?
let stage: String?
let requestId: String?
let identity: Identity?
let resourcePath: String?
let httpMethod: String?
let apiId: String
}
struct Identity: Codable {
let cognitoIdentityPoolId: String?
let accountId: String?
let cognitoIdentityId: String?
let caller: String?
let apiKey: String?
let sourceIp: String?
let cognitoAuthenticationType: String?
let cognitoAuthenticationProvider: String?
let userArn: String?
let userAgent: String?
let user: String?
}
}
struct APIGatewayResponse: Codable {
let statusCode: Int
let headers: [String: String]?
let multiValueHeaders: [String: [String]]?
let body: String?
let isBase64Encoded: Bool?
}
@@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import AWSLambdaRuntime
import NIO
// If you would like to benchmark Swift's Lambda Runtime,
// use this example which is more performant.
// `EventLoopLambdaHandler` does not offload the Lambda processing to a separate thread
// while the closure-based handlers do.
Lambda.run(BenchmarkHandler())
struct BenchmarkHandler: EventLoopLambdaHandler {
typealias In = String
typealias Out = String
func handle(context: Lambda.Context, payload: String) -> EventLoopFuture<String> {
context.eventLoop.makeSucceededFuture("hello, world!")
}
}
@@ -0,0 +1,247 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import AWSLambdaRuntime
import Dispatch
import Foundation
#if canImport(FoundationNetworking) && canImport(FoundationXML)
import FoundationNetworking
import FoundationXML
#endif
import Logging
// MARK: - Run Lambda
Lambda.run { (context: Lambda.Context, _: Request, callback: @escaping (Result<[Exchange], Error>) -> Void) in
let calculator = ExchangeRatesCalculator()
calculator.run(logger: context.logger, callback: callback)
}
// MARK: - Business Logic
// This is a contrived example performing currency exchange rate lookup and conversion using URLSession and XML parsing
struct ExchangeRatesCalculator {
static let currencies = ["EUR", "USD", "JPY"]
static let currenciesEmojies = [
"EUR": "💶",
"JPY": "💴",
"USD": "💵",
]
let locale: Locale
let calendar: Calendar
init() {
// This is data from HMRC, the UK tax authority. Therefore we want to use their locale when interpreting data from the server.
self.locale = Locale(identifier: "en_GB")
// Use the UK calendar, not the system one.
var calendar = self.locale.calendar
calendar.timeZone = TimeZone(identifier: "UTC")!
self.calendar = calendar
}
func run(logger: Logger, callback: @escaping (Result<[Exchange], Swift.Error>) -> Void) {
let startDate = Date()
let months = (1 ... 12).map {
self.calendar.date(byAdding: DateComponents(month: -$0), to: startDate)!
}
self.download(logger: logger,
months: months,
monthIndex: months.startIndex,
currencies: Self.currencies,
state: [:]) { result in
switch result {
case .failure(let error):
return callback(.failure(error))
case .success(let downloadedDataByMonth):
logger.debug("Downloads complete")
var result = [Exchange]()
var previousData: [String: Decimal?] = [:]
for (_, exchangeRateData) in downloadedDataByMonth.filter({ $1.period != nil }).sorted(by: { $0.key < $1.key }) {
for (currencyCode, rate) in exchangeRateData.ratesByCurrencyCode.sorted(by: { $0.key < $1.key }) {
if let rate = rate, let currencyEmoji = Self.currenciesEmojies[currencyCode] {
let change: Exchange.Change
switch previousData[currencyCode] {
case .some(.some(let previousRate)) where rate > previousRate:
change = .up
case .some(.some(let previousRate)) where rate < previousRate:
change = .down
case .some(.some(let previousRate)) where rate == previousRate:
change = .none
default:
change = .unknown
}
result.append(Exchange(date: exchangeRateData.period!.start,
from: .init(symbol: "GBP", emoji: "💷"),
to: .init(symbol: currencyCode, emoji: currencyEmoji),
rate: rate,
change: change))
}
}
previousData = exchangeRateData.ratesByCurrencyCode
}
callback(.success(result))
}
}
}
private func download(logger: Logger,
months: [Date],
monthIndex: Array<Date>.Index,
currencies: [String],
state: [Date: ExchangeRates],
callback: @escaping ((Result<[Date: ExchangeRates], Swift.Error>) -> Void)) {
if monthIndex == months.count {
return callback(.success(state))
}
var newState = state
let month = months[monthIndex]
let url = self.exchangeRatesURL(forMonthContaining: month)
logger.debug("requesting exchange rate from \(url)")
let dataTask = URLSession.shared.dataTask(with: url) { data, _, error in
do {
guard let data = data else {
throw error!
}
let exchangeRates = try self.parse(data: data, currencyCodes: Set(currencies))
newState[month] = exchangeRates
logger.debug("Finished downloading month: \(month)")
if let period = exchangeRates.period {
logger.debug("Got data covering period: \(period)")
}
} catch {
return callback(.failure(error))
}
self.download(logger: logger,
months: months,
monthIndex: monthIndex.advanced(by: 1),
currencies: currencies,
state: newState,
callback: callback)
}
dataTask.resume()
}
private func parse(data: Data, currencyCodes: Set<String>) throws -> ExchangeRates {
let document = try XMLDocument(data: data)
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(identifier: "Etc/UTC")!
dateFormatter.dateFormat = "dd/MMM/yy"
let interval: DateInterval?
if let period = try document.nodes(forXPath: "/exchangeRateMonthList/@Period").first?.stringValue,
period.count == 26 {
// "01/Sep/2018 to 30/Sep/2018"
let startString = period[period.startIndex ..< period.index(period.startIndex, offsetBy: 11)]
let to = period[startString.endIndex ..< period.index(startString.endIndex, offsetBy: 4)]
let endString = period[to.endIndex ..< period.index(to.endIndex, offsetBy: 11)]
if let startDate = dateFormatter.date(from: String(startString)),
let startDay = calendar.dateInterval(of: .day, for: startDate),
to == " to ",
let endDate = dateFormatter.date(from: String(endString)),
let endDay = calendar.dateInterval(of: .day, for: endDate) {
interval = DateInterval(start: startDay.start, end: endDay.end)
} else {
interval = nil
}
} else {
interval = nil
}
let ratesByCurrencyCode: [String: Decimal?] = Dictionary(uniqueKeysWithValues: try currencyCodes.map {
let xpathCurrency = $0.replacingOccurrences(of: "'", with: "&apos;")
if let rateString = try document.nodes(forXPath: "/exchangeRateMonthList/exchangeRate/currencyCode[text()='\(xpathCurrency)']/../rateNew/text()").first?.stringValue,
// We must parse the decimal data using the UK locale, not the system one.
let rate = Decimal(string: rateString, locale: self.locale) {
return ($0, rate)
} else {
return ($0, nil)
}
})
return (period: interval, ratesByCurrencyCode: ratesByCurrencyCode)
}
private func makeUTCDateFormatter(dateFormat: String) -> DateFormatter {
let utcTimeZone = TimeZone(identifier: "UTC")!
let result = DateFormatter()
result.locale = Locale(identifier: "en_US_POSIX")
result.timeZone = utcTimeZone
result.dateFormat = dateFormat
return result
}
private func exchangeRatesURL(forMonthContaining date: Date) -> URL {
let exchangeRatesBaseURL = URL(string: "https://www.hmrc.gov.uk/softwaredevelopers/rates")!
let dateFormatter = self.makeUTCDateFormatter(dateFormat: "MMyy")
return exchangeRatesBaseURL.appendingPathComponent("exrates-monthly-\(dateFormatter.string(from: date)).xml")
}
private typealias ExchangeRates = (period: DateInterval?, ratesByCurrencyCode: [String: Decimal?])
private struct Error: Swift.Error, CustomStringConvertible {
let description: String
}
}
// MARK: - Request and Response
struct Request: Decodable {}
struct Exchange: Encodable {
@DateCoding
var date: Date
let from: Currency
let to: Currency
let rate: Decimal
let change: Change
struct Currency: Encodable {
let symbol: String
let emoji: String
}
enum Change: String, Encodable {
case up
case down
case none
case unknown
}
@propertyWrapper
public struct DateCoding: Encodable {
public let wrappedValue: Date
public init(wrappedValue: Date) {
self.wrappedValue = wrappedValue
}
func encode(to encoder: Encoder) throws {
let string = Self.dateFormatter.string(from: self.wrappedValue)
var container = encoder.singleValueContainer()
try container.encode(string)
}
private static var dateFormatter: ISO8601DateFormatter {
let dateFormatter = ISO8601DateFormatter()
dateFormatter.timeZone = TimeZone(identifier: "UTC")!
dateFormatter.formatOptions = [.withYear, .withMonth, .withDashSeparatorInDate]
return dateFormatter
}
}
}
@@ -0,0 +1,101 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import AWSLambdaRuntime
// MARK: - Run Lambda
// switch over the error type "requested" by thr request, and trigger sucg error accordingly
Lambda.run { (context: Lambda.Context, request: Request, callback: (Result<Response, Error>) -> Void) in
switch request.error {
// no error here!
case .none:
callback(.success(Response(awsRequestId: context.requestId, requestId: request.requestId, status: .ok)))
// trigger a "managed" error - domain specific business logic failure
case .managed:
callback(.success(Response(awsRequestId: context.requestId, requestId: request.requestId, status: .error)))
// trigger an "unmanaged" error - an unexpected Swift Error triggered while processing the request
case .unmanaged(let error):
callback(.failure(UnmanagedError(description: error)))
// trigger a "fatal" error - a panic type error which will crash the process
case .fatal:
fatalError("crash!")
}
}
// MARK: - Request and Response
struct Request: Codable {
let requestId: String
let error: Error
public init(requestId: String, error: Error? = nil) {
self.requestId = requestId
self.error = error ?? .none
}
public enum Error: Codable, RawRepresentable {
case none
case managed
case unmanaged(String)
case fatal
public init?(rawValue: String) {
switch rawValue {
case "none":
self = .none
case "managed":
self = .managed
case "fatal":
self = .fatal
default:
self = .unmanaged(rawValue)
}
}
public var rawValue: String {
switch self {
case .none:
return "none"
case .managed:
return "managed"
case .fatal:
return "fatal"
case .unmanaged(let error):
return error
}
}
}
}
struct Response: Codable {
let awsRequestId: String
let requestId: String
let status: Status
public init(awsRequestId: String, requestId: String, status: Status) {
self.awsRequestId = awsRequestId
self.requestId = requestId
self.status = status
}
public enum Status: Int, Codable {
case ok
case error
}
}
struct UnmanagedError: Error {
let description: String
}
@@ -0,0 +1,20 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import AWSLambdaRuntime
// introductory example, the obligatory "hello, world!"
Lambda.run { (_: Lambda.Context, _: String, callback: (Result<String, Error>) -> Void) in
callback(.success("hello, world!"))
}
@@ -0,0 +1,15 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
preconditionFailure("use `swift test --enable-test-discovery`")
+29
View File
@@ -0,0 +1,29 @@
#!/bin/bash
##===----------------------------------------------------------------------===##
##
## This source file is part of the SwiftAWSLambdaRuntime open source project
##
## Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
## Licensed under Apache License v2.0
##
## See LICENSE.txt for license information
## See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
##
## SPDX-License-Identifier: Apache-2.0
##
##===----------------------------------------------------------------------===##
set -eu
executable=$1
echo "-------------------------------------------------------------------------"
echo "building \"$executable\" lambda"
echo "-------------------------------------------------------------------------"
docker run --rm -v `pwd`:/workspace -w /workspace builder bash -cl "swift build --product $executable -c release -Xswiftc -g"
echo "done"
echo "-------------------------------------------------------------------------"
echo "packaging \"$executable\" lambda"
echo "-------------------------------------------------------------------------"
docker run --rm -v `pwd`:/workspace -w /workspace builder bash -cl "./scripts/package.sh $executable"
+65
View File
@@ -0,0 +1,65 @@
#!/bin/bash
##===----------------------------------------------------------------------===##
##
## This source file is part of the SwiftAWSLambdaRuntime open source project
##
## Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
## Licensed under Apache License v2.0
##
## See LICENSE.txt for license information
## See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
##
## SPDX-License-Identifier: Apache-2.0
##
##===----------------------------------------------------------------------===##
set -eu
lambda_name=SwiftSample
s3_bucket=swift-lambda-test
executables=( $(swift package dump-package | sed -e 's|: null|: ""|g' | jq '.products[] | (select(.type.executable)) | .name' | sed -e 's|"||g') )
if [[ ${#executables[@]} = 0 ]]; then
echo "no executables found"
exit 1
elif [[ ${#executables[@]} = 1 ]]; then
executable=${executables[0]}
elif [[ ${#executables[@]} > 1 ]]; then
echo "multiple executables found:"
for executable in ${executables[@]}; do
echo " * $executable"
done
echo ""
read -p "select which executables to deploy: " executable
fi
echo -e "\ndeploying $executable"
echo "-------------------------------------------------------------------------"
echo "preparing docker build image"
echo "-------------------------------------------------------------------------"
docker build . -t builder
echo "-------------------------------------------------------------------------"
echo "building \"$executable\" lambda"
echo "-------------------------------------------------------------------------"
docker run --rm -v `pwd`/../..:/workspace -w /workspace builder \
bash -cl "cd Examples/LambdaFunctions && \
swift build --product $executable -c release -Xswiftc -g"
echo "done"
echo "-------------------------------------------------------------------------"
echo "packaging \"$executable\" lambda"
echo "-------------------------------------------------------------------------"
docker run --rm -v `pwd`:/workspace -w /workspace builder bash -cl "./scripts/package.sh $executable"
echo "-------------------------------------------------------------------------"
echo "uploading \"$executable\" lambda to s3"
echo "-------------------------------------------------------------------------"
aws s3 cp .build/lambda/$executable/lambda.zip s3://$s3_bucket/
echo "-------------------------------------------------------------------------"
echo "updating \"$lambda_name\" to latest \"$executable\""
echo "-------------------------------------------------------------------------"
aws lambda update-function-code --function $lambda_name --s3-bucket $s3_bucket --s3-key lambda.zip
+27
View File
@@ -0,0 +1,27 @@
#!/bin/bash
##===----------------------------------------------------------------------===##
##
## This source file is part of the SwiftAWSLambdaRuntime open source project
##
## Copyright (c) 2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
## Licensed under Apache License v2.0
##
## See LICENSE.txt for license information
## See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
##
## SPDX-License-Identifier: Apache-2.0
##
##===----------------------------------------------------------------------===##
set -eu
executable=$1
target=.build/lambda/$executable
rm -rf "$target"
mkdir -p "$target"
cp ".build/release/$executable" "$target/"
cp -Pv /usr/lib/swift/linux/lib*so* "$target"
cd "$target"
ln -s "$executable" "bootstrap"
zip --symlinks lambda.zip *
+47
View File
@@ -0,0 +1,47 @@
#!/bin/bash
##===----------------------------------------------------------------------===##
##
## This source file is part of the SwiftAWSLambdaRuntime open source project
##
## Copyright (c) 2017-2018 Apple Inc. and the SwiftAWSLambdaRuntime project authors
## Licensed under Apache License v2.0
##
## See LICENSE.txt for license information
## See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
##
## SPDX-License-Identifier: Apache-2.0
##
##===----------------------------------------------------------------------===##
DIR="$(cd "$(dirname "$0")" && pwd)"
executables=( $(swift package dump-package | sed -e 's|: null|: ""|g' | jq '.products[] | (select(.type.executable)) | .name' | sed -e 's|"||g') )
if [[ ${#executables[@]} = 0 ]]; then
echo "no executables found"
exit 1
elif [[ ${#executables[@]} = 1 ]]; then
executable=${executables[0]}
elif [[ ${#executables[@]} > 1 ]]; then
echo "multiple executables found:"
for executable in ${executables[@]}; do
echo " * $executable"
done
echo ""
read -p "select which executables to deploy: " executable
fi
echo -e "\ndeploying $executable"
echo "-------------------------------------------------------------------------"
echo "preparing docker build image"
echo "-------------------------------------------------------------------------"
docker build . -q -t builder
$DIR/build-and-package.sh ${executable}
echo "-------------------------------------------------------------------------"
echo "deploying using SAM"
echo "-------------------------------------------------------------------------"
sam deploy --template "${executable}-template.yml" $@
+1 -1
View File
@@ -112,7 +112,7 @@ EOF
(
cd "$here/.."
find . \
\( \! -path './.build/*' -a \
\( \! -path '*/.build/*' -a \
\( "${matching_files[@]}" \) -a \
\( \! \( "${exceptions[@]}" \) \) \) | while read line; do
if [[ "$(cat "$line" | replace_acceptable_years | head -n $expected_lines | shasum)" != "$expected_sha" ]]; then