This is an automated email from the ASF dual-hosted git repository.

mssun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave.git

commit 6d71fd50433281cb42e1ffeb6d25c5ee25228536
Author: Mingshen Sun <[email protected]>
AuthorDate: Wed Feb 3 14:49:09 2021 -0800

    Add iOS framework
---
 .../TeaclaveClientSDK.xcodeproj/project.pbxproj    | 533 +++++++++++++++++++++
 .../project.xcworkspace/contents.xcworkspacedata   |   7 +
 .../xcshareddata/IDEWorkspaceChecks.plist          |   8 +
 .../xcshareddata/swiftpm/Package.resolved          |  16 +
 .../UserInterfaceState.xcuserstate                 | Bin 0 -> 54147 bytes
 .../xcdebugger/Breakpoints_v2.xcbkptlist           |   6 +
 .../xcschemes/xcschememanagement.plist             |  19 +
 .../TeaclaveClientSDK/TeaclaveClientSDK/Info.plist |  22 +
 .../TeaclaveClientSDK/TeaclaveClientSDK.h          |  26 +
 .../TeaclaveClientSDK/TeaclaveClientSDK.modulemap  |   9 +
 .../TeaclaveClientSDK/TeaclaveClientSDK.swift      | 327 +++++++++++++
 .../TeaclaveClientSDKTests/Info.plist              |  22 +
 .../TeaclaveClientSDKTests.swift                   | 174 +++++++
 13 files changed, 1169 insertions(+)

diff --git 
a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.pbxproj 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..826b9a5
--- /dev/null
+++ b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.pbxproj
@@ -0,0 +1,533 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 52;
+       objects = {
+
+/* Begin PBXBuildFile section */
+               9AA3BE6925C9D33B00A2BA83 /* TeaclaveClientSDK.framework in 
Frameworks */ = {isa = PBXBuildFile; fileRef = 9AA3BE5F25C9D33B00A2BA83 /* 
TeaclaveClientSDK.framework */; };
+               9AA3BE6E25C9D33B00A2BA83 /* TeaclaveClientSDKTests.swift in 
Sources */ = {isa = PBXBuildFile; fileRef = 9AA3BE6D25C9D33B00A2BA83 /* 
TeaclaveClientSDKTests.swift */; };
+               9AA3BE7025C9D33B00A2BA83 /* TeaclaveClientSDK.h in Headers */ = 
{isa = PBXBuildFile; fileRef = 9AA3BE6225C9D33B00A2BA83 /* TeaclaveClientSDK.h 
*/; settings = {ATTRIBUTES = (Public, ); }; };
+               9ABF3E5625C9EBFB003D7DDC /* TeaclaveClientSDK.swift in Sources 
*/ = {isa = PBXBuildFile; fileRef = 9ABF3E5525C9EBFB003D7DDC /* 
TeaclaveClientSDK.swift */; };
+               9AD06D1225C9FBB500651504 /* teaclave_client_sdk.h in Headers */ 
= {isa = PBXBuildFile; fileRef = 9AD06D1125C9FBB500651504 /* 
teaclave_client_sdk.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               9AD06D2825CA042D00651504 /* libteaclave_client_sdk.a in 
Frameworks */ = {isa = PBXBuildFile; fileRef = 9AD06D2725CA042D00651504 /* 
libteaclave_client_sdk.a */; };
+               9AD06D4325CA061100651504 /* OpenSSL in Frameworks */ = {isa = 
PBXBuildFile; productRef = 9AD06D4225CA061100651504 /* OpenSSL */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+               9AA3BE6A25C9D33B00A2BA83 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 9AA3BE5625C9D33B00A2BA83 /* Project 
object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 9AA3BE5E25C9D33B00A2BA83;
+                       remoteInfo = TeaclaveClientSDK;
+               };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+               9AA3BE5F25C9D33B00A2BA83 /* TeaclaveClientSDK.framework */ = 
{isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 
0; path = TeaclaveClientSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+               9AA3BE6225C9D33B00A2BA83 /* TeaclaveClientSDK.h */ = {isa = 
PBXFileReference; lastKnownFileType = sourcecode.c.h; path = 
TeaclaveClientSDK.h; sourceTree = "<group>"; };
+               9AA3BE6325C9D33B00A2BA83 /* Info.plist */ = {isa = 
PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; 
sourceTree = "<group>"; };
+               9AA3BE6825C9D33B00A2BA83 /* TeaclaveClientSDKTests.xctest */ = 
{isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 
0; path = TeaclaveClientSDKTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+               9AA3BE6D25C9D33B00A2BA83 /* TeaclaveClientSDKTests.swift */ = 
{isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = 
TeaclaveClientSDKTests.swift; sourceTree = "<group>"; };
+               9AA3BE6F25C9D33B00A2BA83 /* Info.plist */ = {isa = 
PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; 
sourceTree = "<group>"; };
+               9ABF3E5525C9EBFB003D7DDC /* TeaclaveClientSDK.swift */ = {isa = 
PBXFileReference; lastKnownFileType = sourcecode.swift; path = 
TeaclaveClientSDK.swift; sourceTree = "<group>"; };
+               9AD06D1125C9FBB500651504 /* teaclave_client_sdk.h */ = {isa = 
PBXFileReference; lastKnownFileType = sourcecode.c.h; name = 
teaclave_client_sdk.h; path = ../../c/teaclave_client_sdk.h; sourceTree = 
"<group>"; };
+               9AD06D2725CA042D00651504 /* libteaclave_client_sdk.a */ = {isa 
= PBXFileReference; lastKnownFileType = archive.ar; name = 
libteaclave_client_sdk.a; path = 
../../rust/target/universal/debug/libteaclave_client_sdk.a; sourceTree = 
"<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+               9AA3BE5C25C9D33B00A2BA83 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               9AD06D2825CA042D00651504 /* 
libteaclave_client_sdk.a in Frameworks */,
+                               9AD06D4325CA061100651504 /* OpenSSL in 
Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               9AA3BE6525C9D33B00A2BA83 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               9AA3BE6925C9D33B00A2BA83 /* 
TeaclaveClientSDK.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+               9AA3BE5525C9D33A00A2BA83 = {
+                       isa = PBXGroup;
+                       children = (
+                               9AD06D1125C9FBB500651504 /* 
teaclave_client_sdk.h */,
+                               9AA3BE6125C9D33B00A2BA83 /* TeaclaveClientSDK 
*/,
+                               9AA3BE6C25C9D33B00A2BA83 /* 
TeaclaveClientSDKTests */,
+                               9AA3BE6025C9D33B00A2BA83 /* Products */,
+                               9AA3BE8825C9D71200A2BA83 /* Frameworks */,
+                       );
+                       sourceTree = "<group>";
+               };
+               9AA3BE6025C9D33B00A2BA83 /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               9AA3BE5F25C9D33B00A2BA83 /* 
TeaclaveClientSDK.framework */,
+                               9AA3BE6825C9D33B00A2BA83 /* 
TeaclaveClientSDKTests.xctest */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
+               9AA3BE6125C9D33B00A2BA83 /* TeaclaveClientSDK */ = {
+                       isa = PBXGroup;
+                       children = (
+                               9AA3BE6225C9D33B00A2BA83 /* TeaclaveClientSDK.h 
*/,
+                               9AA3BE6325C9D33B00A2BA83 /* Info.plist */,
+                               9ABF3E5525C9EBFB003D7DDC /* 
TeaclaveClientSDK.swift */,
+                       );
+                       path = TeaclaveClientSDK;
+                       sourceTree = "<group>";
+               };
+               9AA3BE6C25C9D33B00A2BA83 /* TeaclaveClientSDKTests */ = {
+                       isa = PBXGroup;
+                       children = (
+                               9AA3BE6D25C9D33B00A2BA83 /* 
TeaclaveClientSDKTests.swift */,
+                               9AA3BE6F25C9D33B00A2BA83 /* Info.plist */,
+                       );
+                       path = TeaclaveClientSDKTests;
+                       sourceTree = "<group>";
+               };
+               9AA3BE8825C9D71200A2BA83 /* Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               9AD06D2725CA042D00651504 /* 
libteaclave_client_sdk.a */,
+                       );
+                       name = Frameworks;
+                       sourceTree = "<group>";
+               };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+               9AA3BE5A25C9D33B00A2BA83 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               9AA3BE7025C9D33B00A2BA83 /* TeaclaveClientSDK.h 
in Headers */,
+                               9AD06D1225C9FBB500651504 /* 
teaclave_client_sdk.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+               9AA3BE5E25C9D33B00A2BA83 /* TeaclaveClientSDK */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 9AA3BE7325C9D33B00A2BA83 /* 
Build configuration list for PBXNativeTarget "TeaclaveClientSDK" */;
+                       buildPhases = (
+                               9AA3BE5A25C9D33B00A2BA83 /* Headers */,
+                               9AA3BE5B25C9D33B00A2BA83 /* Sources */,
+                               9AA3BE5C25C9D33B00A2BA83 /* Frameworks */,
+                               9AA3BE5D25C9D33B00A2BA83 /* Resources */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = TeaclaveClientSDK;
+                       packageProductDependencies = (
+                               9AD06D4225CA061100651504 /* OpenSSL */,
+                       );
+                       productName = TeaclaveClientSDK;
+                       productReference = 9AA3BE5F25C9D33B00A2BA83 /* 
TeaclaveClientSDK.framework */;
+                       productType = "com.apple.product-type.framework";
+               };
+               9AA3BE6725C9D33B00A2BA83 /* TeaclaveClientSDKTests */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 9AA3BE7625C9D33B00A2BA83 /* 
Build configuration list for PBXNativeTarget "TeaclaveClientSDKTests" */;
+                       buildPhases = (
+                               9AA3BE6425C9D33B00A2BA83 /* Sources */,
+                               9AA3BE6525C9D33B00A2BA83 /* Frameworks */,
+                               9AA3BE6625C9D33B00A2BA83 /* Resources */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               9AA3BE6B25C9D33B00A2BA83 /* PBXTargetDependency 
*/,
+                       );
+                       name = TeaclaveClientSDKTests;
+                       productName = TeaclaveClientSDKTests;
+                       productReference = 9AA3BE6825C9D33B00A2BA83 /* 
TeaclaveClientSDKTests.xctest */;
+                       productType = "com.apple.product-type.bundle.unit-test";
+               };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+               9AA3BE5625C9D33B00A2BA83 /* Project object */ = {
+                       isa = PBXProject;
+                       attributes = {
+                               LastSwiftUpdateCheck = 1230;
+                               LastUpgradeCheck = 1230;
+                               TargetAttributes = {
+                                       9AA3BE5E25C9D33B00A2BA83 = {
+                                               CreatedOnToolsVersion = 12.3;
+                                               LastSwiftMigration = 1230;
+                                       };
+                                       9AA3BE6725C9D33B00A2BA83 = {
+                                               CreatedOnToolsVersion = 12.3;
+                                       };
+                               };
+                       };
+                       buildConfigurationList = 9AA3BE5925C9D33B00A2BA83 /* 
Build configuration list for PBXProject "TeaclaveClientSDK" */;
+                       compatibilityVersion = "Xcode 9.3";
+                       developmentRegion = en;
+                       hasScannedForEncodings = 0;
+                       knownRegions = (
+                               en,
+                               Base,
+                       );
+                       mainGroup = 9AA3BE5525C9D33A00A2BA83;
+                       packageReferences = (
+                               9AD06D4125CA061100651504 /* 
XCRemoteSwiftPackageReference "OpenSSL" */,
+                       );
+                       productRefGroup = 9AA3BE6025C9D33B00A2BA83 /* Products 
*/;
+                       projectDirPath = "";
+                       projectRoot = "";
+                       targets = (
+                               9AA3BE5E25C9D33B00A2BA83 /* TeaclaveClientSDK 
*/,
+                               9AA3BE6725C9D33B00A2BA83 /* 
TeaclaveClientSDKTests */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+               9AA3BE5D25C9D33B00A2BA83 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               9AA3BE6625C9D33B00A2BA83 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+               9AA3BE5B25C9D33B00A2BA83 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               9ABF3E5625C9EBFB003D7DDC /* 
TeaclaveClientSDK.swift in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               9AA3BE6425C9D33B00A2BA83 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               9AA3BE6E25C9D33B00A2BA83 /* 
TeaclaveClientSDKTests.swift in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+               9AA3BE6B25C9D33B00A2BA83 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 9AA3BE5E25C9D33B00A2BA83 /* TeaclaveClientSDK 
*/;
+                       targetProxy = 9AA3BE6A25C9D33B00A2BA83 /* 
PBXContainerItemProxy */;
+               };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+               9AA3BE7125C9D33B00A2BA83 /* 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = 
YES;
+                               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;
+                               CURRENT_PROJECT_VERSION = 1;
+                               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 = 14.3;
+                               MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+                               MTL_FAST_MATH = YES;
+                               ONLY_ACTIVE_ARCH = YES;
+                               OTHER_LDFLAGS = "-lc++";
+                               SDKROOT = iphoneos;
+                               SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+                               SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+                               VERSIONING_SYSTEM = "apple-generic";
+                               VERSION_INFO_PREFIX = "";
+                       };
+                       name = Debug;
+               };
+               9AA3BE7225C9D33B00A2BA83 /* 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = 
YES;
+                               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;
+                               CURRENT_PROJECT_VERSION = 1;
+                               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 = 14.3;
+                               MTL_ENABLE_DEBUG_INFO = NO;
+                               MTL_FAST_MATH = YES;
+                               OTHER_LDFLAGS = "-lc++";
+                               SDKROOT = iphoneos;
+                               SWIFT_COMPILATION_MODE = wholemodule;
+                               SWIFT_OPTIMIZATION_LEVEL = "-O";
+                               VALIDATE_PRODUCT = YES;
+                               VERSIONING_SYSTEM = "apple-generic";
+                               VERSION_INFO_PREFIX = "";
+                       };
+                       name = Release;
+               };
+               9AA3BE7425C9D33B00A2BA83 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               CLANG_ENABLE_MODULES = YES;
+                               CODE_SIGN_IDENTITY = "Apple Development";
+                               CODE_SIGN_STYLE = Automatic;
+                               DEFINES_MODULE = YES;
+                               DEVELOPMENT_TEAM = "";
+                               DYLIB_COMPATIBILITY_VERSION = 1;
+                               DYLIB_CURRENT_VERSION = 1;
+                               DYLIB_INSTALL_NAME_BASE = "@rpath";
+                               ENABLE_BITCODE = NO;
+                               INFOPLIST_FILE = TeaclaveClientSDK/Info.plist;
+                               INSTALL_PATH = 
"$(LOCAL_LIBRARY_DIR)/Frameworks";
+                               LD_RUNPATH_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "@executable_path/Frameworks",
+                                       "@loader_path/Frameworks",
+                               );
+                               LIBRARY_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(PROJECT_DIR)",
+                                       
"$(PROJECT_DIR)/../../rust/target/universal/debug",
+                               );
+                               MODULEMAP_FILE = 
"$(SRCROOT)/TeaclaveClientSDK/TeaclaveClientSDK.modulemap";
+                               PRODUCT_BUNDLE_IDENTIFIER = 
org.apache.teaclave.TeaclaveClientSDK;
+                               PRODUCT_NAME = 
"$(TARGET_NAME:c99extidentifier)";
+                               SKIP_INSTALL = YES;
+                               SUPPORTS_MACCATALYST = NO;
+                               SWIFT_INCLUDE_PATHS = "";
+                               SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+                               SWIFT_VERSION = 5.0;
+                               TARGETED_DEVICE_FAMILY = "1,2";
+                       };
+                       name = Debug;
+               };
+               9AA3BE7525C9D33B00A2BA83 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               CLANG_ENABLE_MODULES = YES;
+                               CODE_SIGN_IDENTITY = "Apple Development";
+                               CODE_SIGN_STYLE = Automatic;
+                               DEFINES_MODULE = YES;
+                               DEVELOPMENT_TEAM = "";
+                               DYLIB_COMPATIBILITY_VERSION = 1;
+                               DYLIB_CURRENT_VERSION = 1;
+                               DYLIB_INSTALL_NAME_BASE = "@rpath";
+                               ENABLE_BITCODE = NO;
+                               INFOPLIST_FILE = TeaclaveClientSDK/Info.plist;
+                               INSTALL_PATH = 
"$(LOCAL_LIBRARY_DIR)/Frameworks";
+                               LD_RUNPATH_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "@executable_path/Frameworks",
+                                       "@loader_path/Frameworks",
+                               );
+                               LIBRARY_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(PROJECT_DIR)",
+                                       
"$(PROJECT_DIR)/../../rust/target/universal/debug",
+                               );
+                               MODULEMAP_FILE = 
"$(SRCROOT)/TeaclaveClientSDK/TeaclaveClientSDK.modulemap";
+                               PRODUCT_BUNDLE_IDENTIFIER = 
org.apache.teaclave.TeaclaveClientSDK;
+                               PRODUCT_NAME = 
"$(TARGET_NAME:c99extidentifier)";
+                               SKIP_INSTALL = YES;
+                               SUPPORTS_MACCATALYST = NO;
+                               SWIFT_INCLUDE_PATHS = "";
+                               SWIFT_VERSION = 5.0;
+                               TARGETED_DEVICE_FAMILY = "1,2";
+                       };
+                       name = Release;
+               };
+               9AA3BE7725C9D33B00A2BA83 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+                               CODE_SIGN_STYLE = Automatic;
+                               DEVELOPMENT_TEAM = "";
+                               INFOPLIST_FILE = 
TeaclaveClientSDKTests/Info.plist;
+                               LD_RUNPATH_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "@executable_path/Frameworks",
+                                       "@loader_path/Frameworks",
+                               );
+                               PRODUCT_BUNDLE_IDENTIFIER = 
org.apache.teaclave.TeaclaveClientSDKTests;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SWIFT_VERSION = 5.0;
+                               TARGETED_DEVICE_FAMILY = "1,2";
+                       };
+                       name = Debug;
+               };
+               9AA3BE7825C9D33B00A2BA83 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+                               CODE_SIGN_STYLE = Automatic;
+                               DEVELOPMENT_TEAM = "";
+                               INFOPLIST_FILE = 
TeaclaveClientSDKTests/Info.plist;
+                               LD_RUNPATH_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "@executable_path/Frameworks",
+                                       "@loader_path/Frameworks",
+                               );
+                               PRODUCT_BUNDLE_IDENTIFIER = 
org.apache.teaclave.TeaclaveClientSDKTests;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               SWIFT_VERSION = 5.0;
+                               TARGETED_DEVICE_FAMILY = "1,2";
+                       };
+                       name = Release;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               9AA3BE5925C9D33B00A2BA83 /* Build configuration list for 
PBXProject "TeaclaveClientSDK" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               9AA3BE7125C9D33B00A2BA83 /* Debug */,
+                               9AA3BE7225C9D33B00A2BA83 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               9AA3BE7325C9D33B00A2BA83 /* Build configuration list for 
PBXNativeTarget "TeaclaveClientSDK" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               9AA3BE7425C9D33B00A2BA83 /* Debug */,
+                               9AA3BE7525C9D33B00A2BA83 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               9AA3BE7625C9D33B00A2BA83 /* Build configuration list for 
PBXNativeTarget "TeaclaveClientSDKTests" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               9AA3BE7725C9D33B00A2BA83 /* Debug */,
+                               9AA3BE7825C9D33B00A2BA83 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+/* End XCConfigurationList section */
+
+/* Begin XCRemoteSwiftPackageReference section */
+               9AD06D4125CA061100651504 /* XCRemoteSwiftPackageReference 
"OpenSSL" */ = {
+                       isa = XCRemoteSwiftPackageReference;
+                       repositoryURL = 
"https://github.com/krzyzanowskim/OpenSSL.git";;
+                       requirement = {
+                               kind = upToNextMajorVersion;
+                               minimumVersion = 1.1.180;
+                       };
+               };
+/* End XCRemoteSwiftPackageReference section */
+
+/* Begin XCSwiftPackageProductDependency section */
+               9AD06D4225CA061100651504 /* OpenSSL */ = {
+                       isa = XCSwiftPackageProductDependency;
+                       package = 9AD06D4125CA061100651504 /* 
XCRemoteSwiftPackageReference "OpenSSL" */;
+                       productName = OpenSSL;
+               };
+/* End XCSwiftPackageProductDependency section */
+       };
+       rootObject = 9AA3BE5625C9D33B00A2BA83 /* Project object */;
+}
diff --git 
a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata
 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "self:">
+   </FileRef>
+</Workspace>
diff --git 
a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.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>IDEDidComputeMac32BitWarning</key>
+       <true/>
+</dict>
+</plist>
diff --git 
a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
new file mode 100644
index 0000000..a88f90b
--- /dev/null
+++ 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -0,0 +1,16 @@
+{
+  "object": {
+    "pins": [
+      {
+        "package": "OpenSSL",
+        "repositoryURL": "https://github.com/krzyzanowskim/OpenSSL.git";,
+        "state": {
+          "branch": null,
+          "revision": "389296819a8d025ac10ddc9f22135a5518991fdc",
+          "version": "1.1.180"
+        }
+      }
+    ]
+  },
+  "version": 1
+}
diff --git 
a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.xcworkspace/xcuserdata/sunmingshen.xcuserdatad/UserInterfaceState.xcuserstate
 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.xcworkspace/xcuserdata/sunmingshen.xcuserdatad/UserInterfaceState.xcuserstate
new file mode 100644
index 0000000..1440b25
Binary files /dev/null and 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/project.xcworkspace/xcuserdata/sunmingshen.xcuserdatad/UserInterfaceState.xcuserstate
 differ
diff --git 
a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/xcuserdata/sunmingshen.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/xcuserdata/sunmingshen.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
new file mode 100644
index 0000000..f817af0
--- /dev/null
+++ 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/xcuserdata/sunmingshen.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Bucket
+   uuid = "A068DDE8-7E4D-40A0-BB82-859627A7910B"
+   type = "1"
+   version = "2.0">
+</Bucket>
diff --git 
a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/xcuserdata/sunmingshen.xcuserdatad/xcschemes/xcschememanagement.plist
 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/xcuserdata/sunmingshen.xcuserdatad/xcschemes/xcschememanagement.plist
new file mode 100644
index 0000000..75840d5
--- /dev/null
+++ 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK.xcodeproj/xcuserdata/sunmingshen.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,19 @@
+<?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>SchemeUserState</key>
+       <dict>
+               <key>TeaclaveClientSDK-macOS.xcscheme_^#shared#^_</key>
+               <dict>
+                       <key>orderHint</key>
+                       <integer>1</integer>
+               </dict>
+               <key>TeaclaveClientSDK.xcscheme_^#shared#^_</key>
+               <dict>
+                       <key>orderHint</key>
+                       <integer>0</integer>
+               </dict>
+       </dict>
+</dict>
+</plist>
diff --git a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK/Info.plist 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK/Info.plist
new file mode 100644
index 0000000..9bcb244
--- /dev/null
+++ b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK/Info.plist
@@ -0,0 +1,22 @@
+<?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>$(CURRENT_PROJECT_VERSION)</string>
+</dict>
+</plist>
diff --git a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK/TeaclaveClientSDK.h 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK/TeaclaveClientSDK.h
new file mode 100644
index 0000000..a3398a0
--- /dev/null
+++ b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK/TeaclaveClientSDK.h
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+//! Project version number for TeaclaveClientSDK.
+FOUNDATION_EXPORT double TeaclaveClientSDKVersionNumber;
+
+//! Project version string for TeaclaveClientSDK.
+FOUNDATION_EXPORT const unsigned char TeaclaveClientSDKVersionString[];
diff --git 
a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK/TeaclaveClientSDK.modulemap 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK/TeaclaveClientSDK.modulemap
new file mode 100644
index 0000000..f3d51f5
--- /dev/null
+++ b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK/TeaclaveClientSDK.modulemap
@@ -0,0 +1,9 @@
+framework module TeaclaveClientSDK {
+    umbrella header "TeaclaveClientSDK.h"
+
+    explicit module CTeaclaveClientSDK {
+        private header "teaclave_client_sdk.h"
+    }
+
+    export *
+}
diff --git 
a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK/TeaclaveClientSDK.swift 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK/TeaclaveClientSDK.swift
new file mode 100644
index 0000000..e24d696
--- /dev/null
+++ b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDK/TeaclaveClientSDK.swift
@@ -0,0 +1,327 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+import Foundation
+import TeaclaveClientSDK.CTeaclaveClientSDK
+
+enum TeaclaveClientError: Error {
+    case userLoginError
+    case userRegisterError
+    case setCredentialError
+    case registerFunctionError
+    case createTaskError
+    case invokeTaskError
+    case getTaskResultError
+    case registerInputFileError
+    case registerOutputFileError
+    case assignDataError
+    case approveTaskError
+}
+
+struct RegisterFunctionRequest: Encodable {
+    let request: String = "register_function_request"
+    let name: String
+    let description: String
+    let executor_type: String
+    let `public`: Bool = true
+    let payload: Array<Int>
+    let arguments: Set<String>
+    let inputs: Array<Dictionary<String, String>>
+    let outputs: Array<Dictionary<String, String>>
+}
+
+struct RegisterFunctionResponse: Codable {
+    let function_id: String
+}
+
+struct OwnerList: Encodable {
+    let data_name: String
+    let uids: Array<String>
+}
+
+struct CreateTaskRequest: Encodable {
+    let request: String = "register_create_task"
+    let function_id: String
+    let function_arguments: String
+    let executor: String
+    let inputs_ownership: Array<OwnerList>
+    let outputs_ownership: Array<OwnerList>
+}
+
+struct CreateTaskResponse: Codable {
+    let task_id: String
+}
+
+struct CryptoInfo: Codable {
+    let schema: String
+    let key: Array<Int>
+    let iv: Array<Int>
+}
+
+struct RegisterInputFileRequest: Encodable {
+    let request: String = "register_input_file"
+    let url: String
+    let cmac: String
+    let crypto_info: CryptoInfo
+}
+
+struct RegisterInputFileResponse: Codable {
+    let data_id: String
+}
+
+struct RegisterOutputFileRequest: Encodable {
+    let request: String = "register_output_file"
+    let url: String
+    let cmac: String
+    let crypto_info: CryptoInfo
+}
+
+struct RegisterOutputFileResponse: Codable {
+    let data_id: String
+}
+
+struct DataMap: Codable {
+    let data_name: String
+    let data_id: String
+}
+
+struct AssignDataRequest: Encodable {
+    let request: String = "assign_data"
+    let task_id: String
+    let inputs: Array<DataMap>
+    let outputs: Array<DataMap>
+}
+
+struct ApproveTaskRequest: Encodable {
+    let request: String = "approve_task"
+    let task_id: String
+}
+
+class AuthenticationClient {
+    internal let cClient: OpaquePointer
+
+    init?(address: String, enclave_info_path: String, as_root_ca_cert_path: 
String) {
+        let address_c_string = address.cString(using: .ascii)
+        let enclave_info_path_address_c_string = 
enclave_info_path.cString(using: .ascii)
+        let as_root_ca_cert_c_string = as_root_ca_cert_path.cString(using: 
.ascii)
+        let cClient = 
teaclave_connect_authentication_service(address_c_string, 
enclave_info_path_address_c_string, as_root_ca_cert_c_string)
+        guard let client = cClient else {
+            return nil
+        }
+        self.cClient = client
+    }
+
+    func register(id: String, password: String) -> Result<(), 
TeaclaveClientError> {
+        let id_c_string = id.cString(using: .ascii)
+        let password_c_string = password.cString(using: .ascii)
+
+        let ret = teaclave_user_register(cClient, id_c_string, 
password_c_string)
+        guard ret == 0 else {
+            return Result.failure(.userRegisterError)
+        }
+        return Result.success(())
+    }
+
+    func login(id: String, password: String) -> Result<String, 
TeaclaveClientError> {
+        let id_c_string = id.cString(using: .ascii)
+        let password_c_string = password.cString(using: .ascii)
+        let token_c_string = UnsafeMutablePointer<CChar>.allocate(capacity: 
1024)
+        let token_len = UnsafeMutablePointer<Int>.allocate(capacity: 1)
+        token_len.pointee = 1024
+        let ret = teaclave_user_login(cClient, id_c_string, password_c_string, 
token_c_string, token_len)
+        guard ret == 0 else {
+            token_c_string.deallocate()
+            token_len.deallocate()
+            return Result.failure(.userLoginError)
+        }
+        let token =  String(cString: token_c_string)
+        token_c_string.deallocate()
+        token_len.deallocate()
+
+        return Result.success(token)
+    }
+
+    deinit {
+        teaclave_close_authentication_service(cClient)
+    }
+}
+
+class FrontendClient {
+    internal let cClient: OpaquePointer
+
+    init?(address: String, enclave_info_path: String, as_root_ca_cert_path: 
String) {
+        let address_c_string = address.cString(using: .ascii)
+        let enclave_info_path_address_c_string = 
enclave_info_path.cString(using: .ascii)
+        let as_root_ca_cert_c_string = as_root_ca_cert_path.cString(using: 
.ascii)
+        let cClient = teaclave_connect_frontend_service(address_c_string, 
enclave_info_path_address_c_string, as_root_ca_cert_c_string)
+        guard let client = cClient else {
+            return nil
+        }
+        self.cClient = client
+    }
+
+    deinit {
+        teaclave_close_frontend_service(cClient)
+    }
+
+    func set_credential(id: String, token: String) -> Result<(), 
TeaclaveClientError> {
+        let id_c_string = id.cString(using: .ascii)
+        let token_c_string = token.cString(using: .ascii)
+
+        let ret = teaclave_set_credential(cClient, id_c_string, token_c_string)
+        guard ret == 0 else {
+            return Result.failure(.setCredentialError)
+        }
+        return Result.success(())
+    }
+
+    func register_function(with request: RegisterFunctionRequest) -> 
Result<RegisterFunctionResponse, TeaclaveClientError> {
+        let data = try! JSONEncoder().encode(request)
+        let json_string = String(data: data, encoding: .ascii)!
+
+        let request_c_string = json_string.cString(using: .ascii)
+        let response_c_string = UnsafeMutablePointer<CChar>.allocate(capacity: 
1024)
+        let response_len = UnsafeMutablePointer<Int>.allocate(capacity: 1)
+        response_len.pointee = 1024
+        let ret = teaclave_register_function_serialized(cClient, 
request_c_string, response_c_string, response_len)
+        guard ret == 0 else {
+            return Result.failure(.registerFunctionError)
+        }
+
+        let response_string = String(cString: response_c_string)
+        let response = try! 
JSONDecoder().decode(RegisterFunctionResponse.self, from: 
response_string.data(using: .ascii)!)
+
+        return Result.success(response)
+    }
+
+    func create_task(with request: CreateTaskRequest) -> 
Result<CreateTaskResponse, TeaclaveClientError> {
+        let data = try! JSONEncoder().encode(request)
+        let json_string = String(data: data, encoding: .ascii)!
+
+        let request_c_string = json_string.cString(using: .ascii)
+        let response_c_string = UnsafeMutablePointer<CChar>.allocate(capacity: 
10240)
+        let response_len = UnsafeMutablePointer<Int>.allocate(capacity: 1)
+        response_len.pointee = 10240
+        let ret = teaclave_create_task_serialized(cClient, request_c_string, 
response_c_string, response_len)
+        guard ret == 0 else {
+            return Result.failure(.createTaskError)
+        }
+
+        let response_string = String(cString: response_c_string)
+
+        let response = try! JSONDecoder().decode(CreateTaskResponse.self, 
from: response_string.data(using: .ascii)!)
+
+        return Result.success(response)
+    }
+
+    func register_input_file(with request: RegisterInputFileRequest) -> 
Result<RegisterInputFileResponse, TeaclaveClientError> {
+        let data = try! JSONEncoder().encode(request)
+        let json_string = String(data: data, encoding: .ascii)!
+
+        let request_c_string = json_string.cString(using: .ascii)
+        let response_c_string = UnsafeMutablePointer<CChar>.allocate(capacity: 
10240)
+        let response_len = UnsafeMutablePointer<Int>.allocate(capacity: 1)
+        response_len.pointee = 10240
+        let ret = teaclave_register_input_file_serialized(cClient, 
request_c_string, response_c_string, response_len)
+        guard ret == 0 else {
+            return Result.failure(.registerInputFileError)
+        }
+
+        let response_string = String(cString: response_c_string)
+
+        let response = try! 
JSONDecoder().decode(RegisterInputFileResponse.self, from: 
response_string.data(using: .ascii)!)
+
+        return Result.success(response)
+    }
+
+    func register_output_file(with request: RegisterOutputFileRequest) -> 
Result<RegisterOutputFileResponse, TeaclaveClientError> {
+        let data = try! JSONEncoder().encode(request)
+        let json_string = String(data: data, encoding: .ascii)!
+
+        let request_c_string = json_string.cString(using: .ascii)
+        let response_c_string = UnsafeMutablePointer<CChar>.allocate(capacity: 
10240)
+        let response_len = UnsafeMutablePointer<Int>.allocate(capacity: 1)
+        response_len.pointee = 10240
+        let ret = teaclave_register_output_file_serialized(cClient, 
request_c_string, response_c_string, response_len)
+        guard ret == 0 else {
+            return Result.failure(.registerOutputFileError)
+        }
+
+        let response_string = String(cString: response_c_string)
+
+        let response = try! 
JSONDecoder().decode(RegisterOutputFileResponse.self, from: 
response_string.data(using: .ascii)!)
+
+        return Result.success(response)
+    }
+
+    func assign_data(with request: AssignDataRequest) -> Result<(), 
TeaclaveClientError> {
+        let data = try! JSONEncoder().encode(request)
+        let json_string = String(data: data, encoding: .ascii)!
+
+        let request_c_string = json_string.cString(using: .ascii)
+        let response_c_string = UnsafeMutablePointer<CChar>.allocate(capacity: 
10240)
+        let response_len = UnsafeMutablePointer<Int>.allocate(capacity: 1)
+        response_len.pointee = 10240
+        let ret = teaclave_assign_data_serialized(cClient, request_c_string, 
response_c_string, response_len)
+        guard ret == 0 else {
+            return Result.failure(.assignDataError)
+        }
+
+        return Result.success(())
+    }
+
+    func invoke_task(task_id: String) -> Result<(), TeaclaveClientError> {
+        let task_id_c_string = task_id.cString(using: .ascii)
+        let ret = teaclave_invoke_task(cClient, task_id_c_string)
+        guard ret == 0 else {
+            return Result.failure(.invokeTaskError)
+        }
+
+        return Result.success(())
+    }
+
+    func approve_task(task_id: String) -> Result<(), TeaclaveClientError> {
+        let request = ApproveTaskRequest(task_id: task_id)
+        let data = try! JSONEncoder().encode(request)
+        let json_string = String(data: data, encoding: .ascii)!
+
+        let request_c_string = json_string.cString(using: .ascii)
+        let response_c_string = UnsafeMutablePointer<CChar>.allocate(capacity: 
10240)
+        let response_len = UnsafeMutablePointer<Int>.allocate(capacity: 1)
+        response_len.pointee = 10240
+        let ret = teaclave_approve_task_serialized(cClient, request_c_string, 
response_c_string, response_len)
+        guard ret == 0 else {
+            return Result.failure(.approveTaskError)
+        }
+        return Result.success(())
+    }
+
+    func get_task_result(task_id: String) -> Result<String, 
TeaclaveClientError> {
+        let task_id_c_string = task_id.cString(using: .ascii)
+        let response_c_string = UnsafeMutablePointer<CChar>.allocate(capacity: 
10240)
+        let response_len = UnsafeMutablePointer<Int>.allocate(capacity: 1)
+        response_len.pointee = 10240
+        let ret = teaclave_get_task_result(cClient, task_id_c_string, 
response_c_string, response_len)
+        guard ret == 0 else {
+            return Result.failure(.getTaskResultError)
+        }
+
+        return Result.success(String(cString: response_c_string))
+    }
+}
diff --git a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDKTests/Info.plist 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDKTests/Info.plist
new file mode 100644
index 0000000..64d65ca
--- /dev/null
+++ b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDKTests/Info.plist
@@ -0,0 +1,22 @@
+<?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>
+</dict>
+</plist>
diff --git 
a/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDKTests/TeaclaveClientSDKTests.swift
 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDKTests/TeaclaveClientSDKTests.swift
new file mode 100644
index 0000000..574e3db
--- /dev/null
+++ 
b/sdk/swift/TeaclaveClientSDK/TeaclaveClientSDKTests/TeaclaveClientSDKTests.swift
@@ -0,0 +1,174 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+import XCTest
+@testable import TeaclaveClientSDK
+
+class TeaclaveClientSDKTests: XCTestCase {
+    let authentication_service_address = "teaclave-9900:7776"
+    let frontend_service_address = "teaclave-9900:7777"
+
+    // Setup enclave info path e.g., /incubator-teaclave/enclave_info.toml
+    let enclave_info_path = ""
+    // Setup AS CA certificate path e.g., 
/incubator-teaclave/keys/ias_root_ca_cert.pem
+    let as_root_ca_cert_path = ""
+
+    func testBuiltinEcho() throws {
+        let client = AuthenticationClient(
+            address: authentication_service_address,
+            enclave_info_path: enclave_info_path,
+            as_root_ca_cert_path: as_root_ca_cert_path
+        )
+        let _ = client.register(id: "test_id", password: "test_password")
+        let token = try client.login(id: "test_id", password: 
"test_password").get()
+
+        let register_function_request = RegisterFunctionRequest(
+            name: "builtin-echo",
+            description: "Native Echo Function",
+            executor_type: "builtin",
+            payload: [],
+            arguments: ["message"],
+            inputs: [],
+            outputs: []
+        )
+
+        let frontend_client = FrontendClient(
+            address: frontend_service_address,
+            enclave_info_path: enclave_info_path,
+            as_root_ca_cert_path: as_root_ca_cert_path
+        )
+        try frontend_client.set_credential(id: "test_id", token: token).get()
+        let response = try frontend_client.register_function(with: 
register_function_request).get()
+        let function_id = response.function_id
+
+        let create_task_request = CreateTaskRequest(
+            function_id: function_id,
+            function_arguments: "{\"message\": \"Hello, Teaclave!\"}",
+            executor: "builtin",
+            inputs_ownership: [],
+            outputs_ownership: []
+        )
+
+        let task_id = try frontend_client.create_task(with: 
create_task_request).get().task_id
+
+        try frontend_client.invoke_task(task_id: task_id).get()
+        let task_result = try frontend_client.get_task_result(task_id: 
task_id).get()
+        XCTAssert(task_result == "Hello, Teaclave!")
+    }
+
+    func testBuiltinPasswordCheck() throws {
+        let user0_client = AuthenticationClient(
+            address: authentication_service_address,
+            enclave_info_path: enclave_info_path,
+            as_root_ca_cert_path: as_root_ca_cert_path
+        )
+        let _ = user0_client.register(id: "user0", password: "password")
+        let user0_token = try user0_client.login(id: "user0", password: 
"password").get()
+
+        let user0_frontend_client = FrontendClient(
+            address: frontend_service_address,
+            enclave_info_path: enclave_info_path,
+            as_root_ca_cert_path: as_root_ca_cert_path
+        )
+        try user0_frontend_client.set_credential(id: "user0", token: 
user0_token).get()
+
+        let register_function_request = RegisterFunctionRequest(
+            name: "builtin-password-check",
+            description: "Check whether a password is exposed.",
+            executor_type: "builtin",
+            payload: [],
+            arguments: [],
+            inputs: [
+                ["name": "password", "description": "Client 0's data."],
+                ["name": "exposed_passwords", "description": "Client 1's 
data."]
+            ],
+            outputs: []
+        )
+        let response = try user0_frontend_client.register_function(with: 
register_function_request).get()
+        let function_id = response.function_id
+
+        let create_task_request = CreateTaskRequest(
+            function_id: function_id,
+            function_arguments: "{}",
+            executor: "builtin",
+            inputs_ownership: [
+                OwnerList(data_name: "password", uids: ["user0"]),
+                OwnerList(data_name: "exposed_passwords", uids: ["user1"]),
+            ],
+            outputs_ownership: []
+        )
+        let task_id = try user0_frontend_client.create_task(with: 
create_task_request).get().task_id
+
+        let iv = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+        let key = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+        let register_input_file_request = RegisterInputFileRequest(
+            url: "data:text/plain;base64,c+mpvRfZ0fboR0j3rTgOGDBiubSzlCt9",
+            cmac: "e84748f7ad380e183062b9b4b3942b7d",
+            crypto_info: CryptoInfo(schema: "aes-gcm-128", key: key, iv: iv)
+        )
+        let user0_data_id = try 
user0_frontend_client.register_input_file(with: 
register_input_file_request).get().data_id
+
+
+        let user0_assign_data_request = AssignDataRequest(
+            task_id: task_id,
+            inputs: [DataMap(data_name: "password", data_id: user0_data_id)],
+            outputs: []
+        )
+        try user0_frontend_client.assign_data(with: 
user0_assign_data_request).get()
+
+        let user1_client = AuthenticationClient(
+            address: authentication_service_address,
+            enclave_info_path: enclave_info_path,
+            as_root_ca_cert_path: as_root_ca_cert_path
+        )
+
+        let _ = user1_client.register(id: "user1", password: "password")
+        let user1_token = try user1_client.login(id: "user1", password: 
"password").get()
+        let user1_frontend_client = FrontendClient(
+            address: frontend_service_address,
+            enclave_info_path: enclave_info_path,
+            as_root_ca_cert_path: as_root_ca_cert_path
+        )
+        try user1_frontend_client.set_credential(id: "user1", token: 
user1_token).get()
+
+        let user1_register_input_file_request = RegisterInputFileRequest(
+            url: 
"http://teaclave-file-service:6789/fixtures/functions/password_check/exposed_passwords.txt.enc";,
+            cmac: "42b16c29edeb9ee0e4d219f3b5395946",
+            crypto_info: CryptoInfo(schema: "teaclave-file-128", key: key, iv: 
[])
+        )
+        let user1_data_id = try 
user1_frontend_client.register_input_file(with: 
user1_register_input_file_request).get().data_id
+        let user1_assign_data_request = AssignDataRequest(
+            task_id: task_id,
+            inputs: [DataMap(data_name: "exposed_passwords", data_id: 
user1_data_id)],
+            outputs: []
+        )
+        try user1_frontend_client.assign_data(with: 
user1_assign_data_request).get()
+
+
+
+        try user0_frontend_client.approve_task(task_id: task_id).get()
+        try user1_frontend_client.approve_task(task_id: task_id).get()
+
+        try user0_frontend_client.invoke_task(task_id: task_id).get()
+
+        let result = try user0_frontend_client.get_task_result(task_id: 
task_id).get()
+        XCTAssert(result == "true")
+
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to