mirror of
https://github.com/swift-server/swift-aws-lambda-runtime.git
synced 2026-06-02 07:27:33 +00:00
Merge pull request #72 from swift-server/move-samples
move samples into a subdirectory
This commit is contained in:
+4
-6
@@ -1,11 +1,9 @@
|
||||
.DS_Store
|
||||
/.build
|
||||
/Packages
|
||||
/*.xcodeproj
|
||||
Package.pins
|
||||
*.build
|
||||
/.xcodeproj
|
||||
*.pem
|
||||
/docs
|
||||
Package.resolved
|
||||
.podspecs
|
||||
.swiftpm
|
||||
.swift-version
|
||||
xcuserdata
|
||||
Package.resolved
|
||||
|
||||
+13
@@ -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>
|
||||
+8
@@ -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>
|
||||
+8
@@ -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 */;
|
||||
}
|
||||
+78
@@ -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.
|
||||
}
|
||||
}
|
||||
+98
@@ -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>
|
||||
+6
@@ -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
@@ -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
@@ -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 *
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"),
|
||||
]),
|
||||
]
|
||||
)
|
||||
@@ -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: "'")
|
||||
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
@@ -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"
|
||||
Executable
+65
@@ -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
|
||||
Executable
+27
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user